Documento de contexto consolidado. Este arquivo descreve o projeto completo — motivação, hipóteses, metodologia, dados coletados e análises esperadas.
Large Language Models (LLMs) não possuem capacidade de gerar aleatoriedade verdadeira. São modelos determinísticos de probabilidade condicional: dado um prompt e um seed fixo, a saída é reproduzível. Mesmo com temperature > 0, o processo de amostragem é controlado por distribuições treinadas — não por entropia genuína.
Este projeto investiga empiricamente como diferentes LLMs de pequeno porte "fingem" ser aleatórios ao serem solicitados a escolher um número entre 1 e 10 — uma tarefa aparentemente trivial que expõe vieses profundos de treinamento, cultura e arquitetura.
Questão central: Quando um LLM é instruído a "escolher um número aleatório", o que ele revela sobre si mesmo?
LLMs não produzem distribuições uniformes ao simular aleatoriedade. Certos números (especialmente 7) devem ser escolhidos com frequência desproporcional, refletindo padrões presentes nos dados de treinamento.
Referência humana: Estudos de psicologia cognitiva mostram que humanos tendem ao número 7 quando solicitados a escolher um número "aleatório" entre 1 e 10. LLMs, treinados em texto humano, podem replicar esse viés.
O idioma do prompt influencia a distribuição dos números escolhidos. Culturas diferentes possuem números com conotações distintas (ex: 4 é inauspicioso no Japão e China; 7 é "sortudo" no Ocidente). LLMs multilíngues podem ter absorvido esses padrões.
temperature, top_p e top_k modificam a distribuição amostrada, mas podem não eliminar o viés subjacente — apenas redistribuí-lo. Temperaturas muito baixas devem concentrar a saída em um único número dominante.
Adicionar qualificadores como "truly random" ou "verdadeiramente aleatório" pode (ou não) alterar a distribuição. Se o modelo responde diferente, isso revela sensibilidade semântica ao conceito de aleatoriedade.
Quando solicitado a executar import random; print(random.randint(1, 10)) em Python, o modelo pode simular o resultado da função (enviesado pelo treinamento) em vez de gerar de fato um número uniforme. A distribuição deve diferir da instrução textual.
Um prompt que apresenta uma sequência numérica (ex: 0.7400071693241651_) e pede para completar com um dígito de 0 a 10 ativa um mecanismo diferente — o modelo tenta "completar o padrão" em vez de "simular aleatoriedade". Isso deve produzir distribuições ainda mais enviesadas.
| Item | Detalhe |
|---|---|
| Backend de inferência | Ollama — servidor local em localhost:11434 |
| API | /api/generate (sem streaming) |
| Controle de seed | seed = 42 + sample_index (varia por amostra para simular aleatoriedade) |
| Tokens gerados | num_predict = 30 (suficiente para capturar o número sem respostas longas) |
| Modelo | Parâmetros | Família |
|---|---|---|
llama3.2:1b |
~1 bilhão | Meta Llama 3.2 |
llama3.2:3b |
~3 bilhões | Meta Llama 3.2 |
gemma2:2b |
~2 bilhões | Google Gemma 2 |
phi3.5:latest |
~3.8 bilhões | Microsoft Phi-3.5 |
qwen2.5:1.5b |
~1.5 bilhões | Alibaba Qwen 2.5 |
Todos são modelos de linguagem de pequeno porte (SLMs), escolhidos por serem executáveis localmente, representarem diferentes arquiteturas e corpora de treinamento, e por possuírem capacidade multilíngue variável.
| Parâmetro | Valores testados | Efeito teórico |
|---|---|---|
temperature |
0.1, 0.5, 1.0 |
Controla a "nitidez" da distribuição de tokens |
top_p |
0.1, 0.5, 1.0 |
Nucleus sampling — limita o vocabulário ao núcleo de probabilidade |
top_k |
1, 10, 40 |
Limita o vocabulário aos K tokens mais prováveis |
Cada combinação de (idioma × temperature × top_p × top_k) foi amostrada N = 50 vezes (configuração padrão do protocolo).
Total de combinações por modelo (prompts_1): 6 idiomas × 3 temperaturas × 3 top_p × 3 top_k × 50 amostras = 8.100 chamadas
Solicita um número aleatório entre 1 e 10 em 6 idiomas. É o grupo de referência para todas as comparações.
| Idioma | Prompt |
|---|---|
| Inglês (en) | Pick a random number between 1 and 10. Reply with only the number, nothing else. |
| Português (pt) | Escolha um número aleatório entre 1 e 10. Responda apenas com o número, sem mais nada. |
| Espanhol (es) | Elige un número aleatorio entre 1 y 10. Responde solo con el número, nada más. |
| Alemão (de) | Nenn mir eine Zufallszahl zwischen 1 und 10. Antworte nur mit der Zahl, nichts weiter. |
| Japonês (ja) | 1から10までのランダムな数字を選んでください。数字だけを答えてください。 |
| Chinês (zh) | 随机选择一个1到10之间的数字。只回答数字,不要其他内容。 |
Idêntico ao prompts_1, mas com reforço semântico da aleatoriedade. Testa a H4.
| Idioma | Diferença em relação ao prompts_1 |
|---|---|
| en | "truly random" |
| pt | "verdadeiramente aleatório" |
| es | "verdaderamente aleatorio" |
| de | "wirklich zufällige" |
| ja | "真にランダムな" |
| zh | "真正随机" |
Testa a H5. Prompt em um único "idioma" (python):
execute this python code, with no explanations:
import random
print(random.randint(1, 10))
O modelo não executa código real — ele prevê o que o código produziria. A distribuição resultante revela se o modelo aprendeu a distribuição uniforme da função random.randint ou se projeta seu próprio viés.
Testa a H6. Apresenta uma sequência com aparência de número pseudoaleatório e pede para completar o último dígito (0–10):
Complete a sequência escolhendo um único número inteiro de 0 a 10:
'0.7400071693241651_'
Responda apenas o número, sem decimais.
Este prompt ativa o mecanismo de pattern completion em vez de simulação de aleatoriedade. O intervalo é 0–10 (11 valores), diferente dos outros grupos.
{
"timestamp": "2025-01-15T14:32:00.123456+00:00",
"model": "llama3.2:3b",
"language": "en",
"temperature": 0.5,
"top_p": 0.5,
"top_k": 10,
"seed": 43,
"sample_index": 1,
"raw_response": "7",
"eval_time_ms": 312.45,
"prompt_group": "prompts_1"
}| Campo | Tipo | Descrição |
|---|---|---|
raw_response |
string | Resposta bruta do modelo, sem pós-processamento |
parsed_number |
int | null | Extraído por regex \b(\d+)\b na análise |
is_valid |
bool | True se o número está dentro do intervalo esperado do grupo |
eval_time_ms |
float | Tempo de inferência em milissegundos (preferido do Ollama, fallback por elapsed) |
seed |
int | 42 + sample_index — varia por amostra para quebrar determinismo total |
data/
├── prompts_1_llama3.2_1b_results.json # ~8.100 registros
├── prompts_1_llama3.2_3b_results.json
├── prompts_1_gemma2_2b_results.json
├── prompts_1_phi3.5_latest_results.json
├── prompts_1_qwen2.5_1.5b_results.json
├── prompts_2_*.json # Mesmo volume
├── prompts_3_*.json # Menor volume (1 idioma)
└── prompts_4_*.json # Mesmo volume de prompts_1
O script analyze.py gera as seguintes análises a partir dos JSONs:
- Histograma de frequência (%) por número para cada modelo
- Linha de referência uniforme (10% por número)
- Anotação dos números com frequência > 1.5× o esperado
- Hipótese nula: a distribuição é uniforme
p < 0.05: evidência de viés estatisticamente significativo- Aplicado a todos os agrupamentos: por modelo, por idioma, por temperatura
- Matriz de frequência (%) com cor: verde = dentro do esperado, vermelho = sobre-representado
- Permite visualizar quais números cada idioma "prefere"
H = -Σ p(x) log₂ p(x), normalizada porlog₂(10)→ intervalo [0, 1]- 1.0 = distribuição perfeitamente uniforme
- 0.0 = um único número sempre escolhido
- Aplicada por: temperatura, top_p, top_k, modelo
prompts_1vsprompts_2: mudança de entropia com "truly random"prompts_1vsprompts_3: viés textual vs. viés de códigoprompts_1vsprompts_4: instrução direta vs. completude de padrão
- Heatmap duplo: qual número domina + qual % ele representa
- Frequência específica do 7 por idioma e modelo
- Comparação com a base de 10% esperado
Cada número de 1 a 10 com probabilidade 10,0%. Qualquer desvio sistemático é evidência de viés.
| Observação esperada | Interpretação |
|---|---|
| Alta frequência do 7 em idiomas ocidentais | Absorção do viés cognitivo humano do corpus de treinamento |
| Baixa frequência do 4 em japonês e chinês | Tetrafobia cultural ("4 = morte" nessas culturas) |
Distribuição mais uniforme em top_k=1 não necessariamente |
top_k=1 = greedy decoding → sempre o token mais provável → mais concentrado |
temperature=0.1 → distribuição muito concentrada |
Alta "certeza" do modelo favorece o número dominante |
prompts_2 com entropia ligeiramente maior |
O reforço "truly" pode ativar caminhos de maior dispersão |
prompts_3 (código) mais uniforme ou com pico em números "típicos de output de random" |
Depende de quanto texto de Python com random.randint está no corpus |
prompts_4 com pico no último dígito da sequência (1) |
Completude de padrão: modelo pode tender ao dígito final da sequência apresentada |
- Rejeição de H₀ (uniformidade) para a maioria dos modelos e idiomas com p < 0.05
- Diferença mensurável na entropia entre pelo menos dois grupos de prompts
- Padrão cultural identificável com desvio > 5pp (pontos percentuais) da frequência esperada para ao menos um número em ao menos um idioma
| Limitação | Impacto |
|---|---|
| Modelos pequenos (1B–4B params) | Vieses podem ser mais pronunciados que em modelos grandes com RLHF extenso |
Seed variável por amostra (42 + i) |
Necessário para não amostrar sempre o mesmo token, mas não é aleatoriedade genuína |
| Extração por regex | Respostas não numéricas ou com múltiplos números são descartadas como inválidas |
| Ausência de controle de contexto | Cada chamada é independente (sem histórico) — efeito de "âncora" entre chamadas não existe |
num_predict = 30 |
Suficiente para o número, mas o modelo pode emitir texto antes do número em alguns casos |
| Termo | Definição |
|---|---|
| Temperatura | Parâmetro que controla a "nitidez" da distribuição de tokens. Valores baixos = determinístico; valores altos = mais diverso |
| top_p (nucleus sampling) | Restringe a amostragem ao menor conjunto de tokens cuja probabilidade acumulada ≥ p |
| top_k | Restringe a amostragem aos K tokens com maior probabilidade |
| Seed | Valor inicial do gerador pseudoaleatório usado no processo de amostragem |
| Entropia de Shannon | Medida de incerteza/uniformidade de uma distribuição. Máxima quando uniforme |
| Teste χ² de Goodness-of-fit | Teste estatístico que verifica se uma distribuição observada difere da esperada (uniforme) |
| Viés cognitivo do 7 | Fenômeno documentado em que humanos tendem a escolher 7 como número "mais aleatório" entre 1–10 |
| Tetrafobia | Aversão cultural ao número 4, comum em culturas do Leste Asiático, por homofonia com "morte" |
| SLM | Small Language Model — modelos com menos de ~7B parâmetros, executáveis localmente |
| Greedy decoding | Estratégia de geração que sempre seleciona o token de maior probabilidade (equivalente a top_k=1) |
| Falsa aleatoriedade | Comportamento de um sistema determinístico que aparenta produzir saídas aleatórias |
- "The Most Random Number" — estudos de psicologia experimental documentam o viés humano pelo 7 em escolhas "aleatórias"
- Kalai & Kalai (2010) — sobre aleatoriedade percebida vs. estatística em contextos de tomada de decisão
- Holtzman et al. (2020) — "The Curious Case of Neural Text Degeneration" — formaliza nucleus sampling (top_p)
- Kenton et al. — BERT e viés cultural em embeddings multilíngues
- O projeto é metodologicamente inspirado em trabalhos de auditing de modelos que testam comportamento em tarefas aparentemente simples para revelar vieses internos