Pular para o conteúdo
Novo

DeepSeek V4.1 Flash grátis por 7 dias: 10M tokens por dia após qualquer recarga. Até 30/11.

Como funciona

O que é um modelo de linguagem grande (LLM)?

Como modelos de linguagem grandes transformam texto em tokens, preveem o próximo e por que soam confiantes quando erram.

Iniciante13 min de leituraPor NotHoly

O que é um modelo de linguagem grande

Um modelo de linguagem grande (LLM, na sigla em inglês) é um programa que aprendeu, a partir de uma quantidade enorme de texto, quais pedaços de texto costumam seguir quais outros. Você escreve um prompt, e o programa produz a resposta um pequeno pedaço por vez. Esse é o mecanismo inteiro, visto de cima. O resto deste artigo explica como uma tarefa tão simples se torna útil e onde ela falha.

A palavra "grande" se refere a duas coisas: a quantidade de texto usada no treinamento e o número de valores numéricos, chamados parâmetros, que o treinamento ajusta. A palavra "modelo" quer dizer que o programa atribui probabilidades a sequências de texto. Ele não consulta uma base de dados para responder, e não mantém uma lista de fatos que confere antes de falar. Ele gera texto a partir dos padrões que absorveu no treinamento.

Se você já usou uma ferramenta de chat com IA, já usou um LLM. O produto envolve o modelo em uma interface, acrescenta instruções que você não vê e, muitas vezes, conecta o modelo a uma busca ou a outras ferramentas. O modelo por baixo é a parte que este artigo descreve. Quando a resposta do produto parece errada, ajuda saber qual camada produziu o erro.

Por que isso importa para segurança

Trabalho de segurança é feito de afirmações. Um pacote é seguro para instalar. Uma porta está fechada. Uma configuração desativa uma verificação. Uma vulnerabilidade afeta determinada versão. Um LLM escreve cada afirmação no mesmo tom fluente, seja ela verdadeira ou não. Se você não sabe como o modelo produz texto, é fácil tratar um parágrafo confiante como se fosse um achado.

Entender o mecanismo muda três hábitos. Você para de esperar que o modelo saiba coisas que nunca viu. Para de tomar fluência como prova. E passa a perguntar onde cada afirmação pode ser conferida. O NIST Generative AI Profile, publicado como NIST AI 600-1, inclui a confabulação entre os riscos dos sistemas de IA generativa. Confabulação é a produção de conteúdo afirmado com confiança que está errado. O documento pede que as organizações planejem para isso, em vez de presumir que o problema não existe.

Como funciona, passo a passo

O trabalho do modelo se divide em algumas etapas: o texto vira tokens, os tokens viram vetores, a atenção mistura o contexto, o modelo prevê um token, e o treinamento e a inferência tornam essa previsão útil. As seções a seguir seguem essa ordem.

Passo 1: o texto vira tokens

O modelo não lê letras nem palavras inteiras diretamente. Ele lê tokens, pedaços de texto escolhidos por um componente chamado tokenizador. Um token pode ser uma palavra inteira, parte de uma palavra, um espaço, um sinal de pontuação ou uma pequena sequência de bytes. Palavras comuns costumam virar um único token. Palavras raras, identificadores de código e textos em idiomas menos frequentes costumam se dividir em vários.

O tokenizador aprende seus pedaços a partir de dados antes de o modelo ser treinado. Um método comum é o byte-pair encoding, normalmente abreviado como BPE. Ele começa com caracteres isolados e junta repetidamente o par de vizinhos que mais aparece, até o vocabulário chegar a um tamanho escolhido. O resultado é uma lista fixa de pedaços e uma regra para dividir qualquer texto novo nesses pedaços.

Para deixar a ideia concreta, o script abaixo constrói um BPE minúsculo a partir de algumas palavras. É um brinquedo, não o tokenizador de nenhum modelo real, mas o mecanismo é o mesmo. Salve como toy_bpe.py e rode com Python 3:

python
from collections import Counter

corpus = "low low low lower lowest newer newer newer wider wider new new"
words = Counter(tuple(w) + ("</w>",) for w in corpus.split())

def pair_counts(vocab):
    pairs = Counter()
    for word, freq in vocab.items():
        for a, b in zip(word, word[1:]):
            pairs[(a, b)] += freq
    return pairs

def merge(vocab, pair):
    out = Counter()
    for word, freq in vocab.items():
        new, i = [], 0
        while i < len(word):
            if i < len(word) - 1 and (word[i], word[i + 1]) == pair:
                new.append(word[i] + word[i + 1]); i += 2
            else:
                new.append(word[i]); i += 1
        out[tuple(new)] += freq
    return out

merges = []
vocab = words
for step in range(6):
    pairs = pair_counts(vocab)
    if not pairs:
        break
    best = max(pairs, key=lambda p: (pairs[p], p))
    merges.append(best)
    vocab = merge(vocab, best)
    print(f"merge {step + 1}: {best[0]!r} + {best[1]!r} -> {best[0] + best[1]!r} (count {pairs[best]})")

def tokenize(word):
    toks = list(word) + ["</w>"]
    for a, b in merges:
        i = 0
        while i < len(toks) - 1:
            if toks[i] == a and toks[i + 1] == b:
                toks[i:i + 2] = [a + b]
            else:
                i += 1
    return toks

for w in ["lowest", "newest", "widen"]:
    print(w, "->", tokenize(w))

A saída abaixo veio de rodar este script no Windows 11 com Python 3.12.10. A sua deve bater linha por linha, porque o script não usa aleatoriedade:

text
merge 1: 'r' + '</w>' -> 'r</w>' (count 6)
merge 2: 'e' + 'r</w>' -> 'er</w>' (count 6)
merge 3: 'w' + '</w>' -> 'w</w>' (count 5)
merge 4: 'n' + 'e' -> 'ne' (count 5)
merge 5: 'l' + 'o' -> 'lo' (count 5)
merge 6: 'w' + 'er</w>' -> 'wer</w>' (count 4)
lowest -> ['lo', 'w', 'e', 's', 't', '</w>']
newest -> ['ne', 'w', 'e', 's', 't', '</w>']
widen -> ['w', 'i', 'd', 'e', 'n', '</w>']

Leia primeiro as fusões. O par mais frequente no corpus pequeno é um marcador de fim de palavra colado em r, então essa fusão vem primeiro. As fusões seguintes montam pedaços como er</w> e lo, que refletem grafias repetidas no corpus. Depois observe as divisões. "lowest" se separa em lo, w, e, s, t e o marcador de fim, porque o vocabulário de brinquedo nunca aprendeu um pedaço para est ou owe. "widen" cai quase para caracteres isolados. O vocabulário do tokenizador cobre o que ele viu no próprio treinamento, e todo o resto custa mais pedaços.

Muitos tokenizadores reais trabalham com bytes e treinam com muito mais texto, então os pedaços são mais longos e em maior número. O princípio se mantém. Texto que aparece muito nos dados de treinamento é barato, e texto pouco familiar custa mais tokens. Isso tem efeitos práticos. Modelos limitam a entrada e a saída pelo número de tokens, e os serviços costumam cobrar pelo mesmo critério, então a mesma frase pode custar valores diferentes em outro idioma ou em código.

Passo 2: os tokens viram vetores

Cada token tem um identificador numérico. O modelo associa esse identificador a um vetor, uma lista de números que costuma ter centenas ou milhares de elementos. Esses vetores são aprendidos durante o treinamento. Tokens que aparecem em contextos parecidos acabam com vetores parecidos, então o modelo trata "carro" e "automóvel" como relacionados sem que alguém escreva uma regra para isso.

A partir daí, o modelo trabalha com números, não com caracteres. Ele não inspeciona as letras dentro de um token como você faria. Essa é uma explicação comum para o fato de modelos às vezes errarem a contagem de letras de uma palavra ou falharem em um problema simples de ortografia. As letras nunca foram apresentadas ao modelo como itens separados.

Passo 3: atenção e o transformer

A maioria dos LLMs atuais é construída sobre a arquitetura transformer, descrita em "Attention Is All You Need", de Vaswani e colegas, publicado em 2017 (arXiv:1706.03762). Modelos de linguagem anteriores costumavam ler o texto um token depois do outro, carregando um resumo corrente. O transformer permite que cada posição olhe diretamente para outras posições, por meio de um mecanismo chamado atenção.

Para cada token do contexto, a atenção calcula quanto peso dar a cada token anterior ao montar a representação do token atual. Empilhe muitas camadas de atenção e pequenas redes feed-forward, e o modelo constrói um quadro rico do contexto. Ele consegue ligar um pronome ao substantivo a que se refere, associar uma chamada de função a uma definição de várias linhas antes, ou perceber qual parte de uma pergunta a resposta precisa atender.

Para usar bem esses modelos, você não precisa da matemática. O fato útil é que a leitura que o modelo faz de um token depende dos tokens ao redor, em todo o contexto. Mude uma palavra do prompt e a representação de muitas outras palavras pode mudar junto. Por isso pequenas diferenças de redação às vezes produzem respostas bem diferentes.

Passo 4: prever o próximo token

No topo das camadas, o modelo produz uma pontuação para cada token do vocabulário e converte as pontuações em probabilidades. O próximo token é escolhido dessa distribuição, acrescentado ao texto, e o processo se repete com o texto mais longo como entrada. Uma resposta de 300 tokens são 300 previsões separadas, cada uma condicionada a tudo o que veio antes, inclusive aos tokens que o próprio modelo acabou de produzir.

Pense na frase "A capital da França é". Quase toda a probabilidade cai sobre um token que continua com "Paris". O modelo não consultou um mapa. Ele aprendeu que essa continuação é muito comum no texto que viu. O mesmo mecanismo cobre pedidos mais difíceis: um comentário de código seguido de uma assinatura de função, uma mensagem de erro seguida de uma causa provável, uma pergunta seguida de uma explicação plausível. Cada caso é uma continuação, e o acerto depende de quão bem os padrões aprendidos encaixam no texto novo.

Passo 5: treinamento

O treinamento ajusta os parâmetros para que as previsões do modelo batam com o texto dos dados de treinamento. De forma simplificada, o modelo lê um trecho, esconde o próximo token, tenta prevê-lo, mede a distância entre a previsão e o token real e ajusta os parâmetros um pouco na direção que teria ajudado. Repita isso sobre uma quantidade enorme de texto, com muito processamento, e os parâmetros passam a codificar boa parte da estrutura estatística da linguagem.

O treinamento costuma acontecer em etapas. A primeira, chamada pré-treinamento, é o processo de próximo token descrito acima. As etapas seguintes costumam usar exemplos de instruções e boas respostas, e às vezes avaliações de pessoas que ranqueiam respostas. Essas etapas moldam o comportamento quando alguém faz uma pergunta: o modelo fica mais disposto a responder de forma útil e menos propenso a continuar a conversa como se fosse uma página da web. Os dados de treinamento definem a gama de assuntos disponíveis, e a data de corte deles define até onde o modelo aprendeu com texto.

O treinamento é caro e é feito pelo desenvolvedor do modelo, não pela pessoa que digita na janela de chat. Conversas comuns não alteram os parâmetros do modelo.

Passo 6: inferência

Inferência é executar um modelo já treinado para produzir uma saída. Toda resposta que você vê é inferência. Durante a inferência, os parâmetros ficam fixos. Só muda a entrada de uma requisição para outra, que inclui as instruções do sistema, a conversa até ali, os arquivos anexados e os resultados de ferramentas devolvidos ao contexto.

Isso explica uma surpresa comum. Um modelo pode parecer ter esquecido a conversa no dia seguinte. Nada do que você digitou atualizou os parâmetros, então o modelo começa do mesmo estado de antes. Produtos com memória guardam anotações fora do modelo e as inserem no contexto de requisições futuras. O modelo lê essas anotações como texto. Ele não lembra delas como uma pessoa lembraria.

Janela de contexto

A janela de contexto é o número máximo de tokens que o modelo consegue considerar em uma requisição. Ela precisa caber as instruções, a conversa, os documentos anexados e a resposta que está sendo gerada. Texto fora da janela fica invisível para o modelo naquela etapa, por mais importante que tenha sido antes. Em conversas longas, mensagens antigas podem sair do contexto ou perder influência para as mais recentes.

Os tamanhos de janela variam entre modelos e mudam com o tempo. Consulte a documentação atual do modelo que você usa, em vez de confiar em um número de artigo, inclusive este. Uma janela maior também não garante bom uso dela. Contextos longos podem enterrar o detalhe que importa, então um prompt focado com o documento certo costuma valer mais do que uma pilha grande de texto.

Temperatura e amostragem

Amostragem é a etapa que escolhe um token da distribuição de probabilidades. A temperatura é a configuração que controla quão concentrada essa distribuição fica antes da escolha. Com temperatura baixa, os tokens mais prováveis dominam, então as respostas são mais repetitivas e mais estáveis de uma execução para outra. Com temperatura alta, a probabilidade se espalha por mais tokens, então as respostas variam mais e se desviam com mais frequência. Muitas interfaces de chat nem mostram essa configuração.

A temperatura não decide se a resposta está certa. Uma configuração baixa pode repetir uma afirmação errada com a mesma confiança de uma alta. Além disso, temperatura zero não garante saídas idênticas em todo ambiente, porque o cálculo por baixo pode variar entre hardware e versões de software. Se você precisa de saída repetível para um teste, registre a versão do modelo, as configurações e a entrada, e trate a saída como uma amostra, não como verdade fixa.

Por que modelos soam confiantes e mesmo assim erram

Uma resposta errada e confiante decorre de como o modelo foi construído, não de uma falha rara.

O modelo otimiza para a continuação plausível. Uma frase falsa que encaixa no padrão do texto pode receber a mesma pontuação de uma frase verdadeira. Os dados de treinamento também contêm erros, e o modelo absorve esses erros tão facilmente quanto absorve fatos corretos. Na inferência, ele não tem acesso direto ao mundo, a menos que uma ferramenta forneça esse acesso. Sem uma etapa de recuperação de documentos ou uma ferramenta, ele responde a partir dos padrões dos seus parâmetros.

A fluência faz parte do problema. Texto confiante e bem organizado é comum nos dados de treinamento, então o modelo aprende a produzi-lo independentemente da precisão. O tom de uma resposta não traz nenhuma informação sobre se o conteúdo é verdadeiro.

As lacunas pioram tudo. Quando falta um detalhe, o modelo preenche com algo que encaixa no padrão. Detalhes específicos, como números de versão, nomes de funções, identificadores CVE, chaves de configuração e URLs, são os mais fáceis de reconstruir errado, porque parecem regulares mas precisam corresponder a um fato particular. O NIST chama isso de confabulação, e o mesmo padrão aparece em quase todos os sistemas generativos.

Erros comuns

  1. Tratar a resposta como resultado de busca. O modelo pode parafrasear fontes reais, inventar outras ou misturar duas. Peça a fonte e depois abra a fonte.
  2. Presumir que o modelo executou o comando ou a varredura que descreve. A menos que uma ferramenta tenha devolvido saída real, ele está descrevendo o que uma execução dessas costuma mostrar.
  3. Colar segredos, credenciais ou dados de clientes em um prompt sem verificar como o serviço guarda e usa as entradas. Leia a política antes de colar algo sensível.
  4. Usar uma resposta como palavra final sobre número de versão, configuração padrão, ponto jurídico ou termo de licença.
  5. Achar que um contexto maior sempre ajuda. Texto extra pode diluir a parte que importa.
  6. Acreditar que uma citação é real só porque tem o formato certo. Autores, títulos e links também podem ser gerados para parecer plausíveis.

O que isso significa para trabalho de segurança

Confira as afirmações em fontes primárias. Em uma questão de segurança, isso normalmente significa o aviso do fabricante, a RFC ou norma relevante, a documentação oficial da versão exata que você usa, o registro CVE, a publicação do NIST ou o código do seu próprio repositório. Use o modelo para descobrir o que checar e como testar, não como autoridade final sobre o que é verdade.

Mantenha um registro curto de cada afirmação em que você se apoia: a afirmação, a fonte, a data em que você conferiu e a versão a que ela se aplica. Esse hábito pega tanto erros do modelo quanto os seus. Trate todo comando gerado como rascunho a ser lido antes de rodar. Execute-o apenas em um laboratório seu, e nunca aponte passos gerados de varredura ou exploração para um sistema sem permissão por escrito para testá-lo.

Como seguir em frente

Leia a primeira seção e a figura da arquitetura do artigo do transformer. Você não precisa entender todas as equações para ver a forma da ideia. Depois rode o tokenizador de brinquedo com as suas próprias palavras e veja onde ele divide cada uma. O artigo de Sennrich e colegas introduziu as unidades de subpalavra construídas por byte-pair encoding, e o capítulo do curso da Hugging Face percorre o algoritmo com código. Em seguida, leia a seção sobre confabulação do perfil do NIST para entender como a organização enquadra esse risco.

O próximo artigo, O que é uma API de LLM, trata de chamar um modelo a partir do seu próprio código. É assim que a NotHoly disponibiliza seus modelos para desenvolvedores, e o mesmo hábito de verificação vale para toda resposta recebida por uma API. Para ter base sobre o tipo de afirmação de que o trabalho de segurança depende, veja O que é uma vulnerabilidade.

Fontes

Fontes

  1. Attention Is All You Need (arXiv:1706.03762)
  2. Neural Machine Translation of Rare Words with Subword Units (arXiv:1508.07909)
  3. NIST AI 600-1: Generative AI Profile
  4. Byte-Pair Encoding tokenization, LLM Course

Mais em Modelos de LLM e APIs