Fundamentos da Métrica Perplexity
A perplexidade (PPX) quantifica a capacidade preditiva de modelos de linguagem, sendo a exponenciação da entropia cruzada média. Valores menores indicam maior confiança do modelo na distribuição textual observada.
Formalmente, para uma sequência de tokens w₁, w₂, ..., wₙ com probabilidade estimada P:
PPX = exp( - (1/N) × Σ log P(wᵢ | w₁...wᵢ₋₁) )
Uma PPX de 20 equivale a um modelo que se comporta como se escolhesse entre 20 palavras equiprováveis a cada passo.
Implementação com PyTorch
import torch
import torch.nn.functional as F
def avaliar_perplexidade(rede, carregador, dispositivo):
rede.eval()
entropia_acumulada = 0.0
total_tokens = 0
with torch.no_grad():
for lote in carregador:
entradas = lote['ids'].to(dispositivo)
alvos = lote['rotulos'].to(dispositivo)
saidas = rede(entradas).logits
logits_ajustados = saidas[:, :-1, :].contiguous()
rotulos_ajustados = alvos[:, 1:].contiguous()
perda = F.cross_entropy(
logits_ajustados.reshape(-1, logits_ajustados.size(-1)),
rotulos_ajustados.reshape(-1),
ignore_index=-100
)
entropia_acumulada += perda.item() * rotulos_ajustados.numel()
total_tokens += rotulos_ajustados.numel()
perda_media = entropia_acumulada / total_tokens
return torch.exp(torch.tensor(perda_media)).item()
Tabela de Referência em WikiText-103
| Arquitetura | Perplexidade (Validação) | Observações |
|---|---|---|
| LSTM (2 camadas) | 73.4 | Linha de base clássica |
| Transformer-XL | 18.3 | Posições relativas e memória segmentada |
| GPT-2 Small | 15.1 | 12 camadas, 768 dimensões ocultas |
Taxonomia de Falhas e Diagnóstico
Categoria 1: Erros de Tokenização e AST
Fragmentação de identificadores em tokens inválidos corrompe a aálise sintática:
# Código original
def calcular_total(itens):
return sum(itens)
# Após tokenização incorreta
def calcu
lar_total(itens):
return sum(itens)
| Sintoma | Origem | Verificação |
|---|---|---|
| Unexpected EOF | Fluxo de tokens truncado | Inspecionar presença de LPAR/COLON no final |
| Identificador inválido | Cisão em bytes UTF-8 | Comparar token.text com índices de bytes originais |
Categoria 2: Colapso de Contexto
Template curl para reproduzir truncamento silencioso:
curl -X POST http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "llama3",
"messages": [{"role":"user","content":"'$(python3 -c "print('A '*4097)")'"}],
"max_tokens": 10
}'
Categoria 3: Inconsistências em Chamada de Ferramentas
Exemplo de violação de schema OpenAPI v3:
{
"nome": "consultar_clima",
"argumentos": {
"cidade": "São Paulo",
"unidade": "celsius",
"dias": 7.5
}
}
Problemas: unidade deve estar em ["c", "f"] (enum); dias deve ser inteiro.
Categoria 4: Alucinações e Deriva Factual
Métrica combinada para detecção:
escore_drift = confianca / (entropia + 1e-8)
LIMIAR_OTIMO = 0.62 # F1 maximizado via validação cruzada em 12 domínios
| Limiar | Recall Alucinações | Falsos Positivos |
|---|---|---|
| 0.50 | 89.2% | 14.7% |
| 0.62 | 76.5% | 5.3% |
| 0.75 | 41.1% | 1.2% |
Templates curl para Diagnóstico
Templaet 1: Rastreamento Completo
GET /api/v1/completions HTTP/1.1
Host: api.exemplo.com
X-Request-ID: req-7f8a2c1e-9b4d-4e6f-8a1c-3d5e7f9a1b2c
X-B3-TraceId: 4bf92f3577b34da6a3ce929d0e0e4736
X-B3-SpanId: 00f067aa0ba902b7
X-B3-Sampled: 1
Template 2: Consistência de Sessão
Verificação de context_hash no servidor:
hash_esperado := sha256.Sum256([]byte(
fmt.Sprintf("%s|%s|%d",
sessao.Token,
strings.Join(sessao.Mensagens, "\n"),
sessao.ContadorTurnos,
),
))
if !bytes.Equal(hash_esperado[:], requisicao.ContextHash) {
return errors.New("divergencia de contexto: possivel replay ou drift")
}
Template 3: Injeção Reversa em function_response
resposta = {
"role": "function",
"name": "obter_clima",
"content": '{"cidade": "São Paulo", "temperatura": 25} // injetado: {"malicioso": true}'
}
Modo tool_choice |
Ferramenta Obrigatória | Suscetibilidade a Injeção |
|---|---|---|
| "auto" | Não | Alta |
| {"type": "function", ...} | Sim | Baixa |
Template 4: Snapshot DOM Multimodal
function capturarSnapshotConsistente() {
return Promise.all([
MathJax.typesetPromise(),
mermaid.run({ querySelector: '.mermaid' }),
Prism.highlightAll()
]).then(() => document.documentElement.outerHTML);
}
Template 5: Teste de Carga com curl
for i in {1..100}; do
curl -s -o /dev/null -w "%{http_code} %{time_total}\n" \
-H "X-Request-ID: req-$RANDOM" \
http://localhost:8000/v1/completions
done
Template 6: Validação de Contrato OpenAPI
curl -X POST http://localhost:8000/v1/tools/validate \
-H "Content-Type: application/json" \
-d '{
"schema_url": "https://api.exemplo.com/openapi.json",
"invocation": {"name": "consultar_clima", "arguments": {"dias": 7.5}}
}'
Ferramenta CLI perp-blame
Arquitetura de Dupla Modalidade
O motor correlaciona diferenças em nós AST com mapas de atenção do LLM via projeção linear:
projecao = torch.nn.Linear(768, len(nos_ast))
logits_atencao = projecao(estado_oculto.mean(dim=1))
Métricas de Confiança
| Indicador | Fórmula | Limiar |
|---|---|---|
| Jaccard AST-Atenção | |ΔAST ∩ Atendido| / |ΔAST ∪ Atendido| | ≥ 0.62 |
| Cobertura Top-3 | Nós de diff cobertos / Total de nós de diff | ≥ 0.85 |
Geração de Patch e Reescrita de Prompt
A partir da resposta estruturada:
{
"erro": "undefined method `strip' for nil:NilClass",
"rastreamento": ["app/models/usuario.rb:42"],
"sugestao": "Adicionar verificação de nil antes de strip"
}
Geração de git diff com inserção de guarda condicional e instrução de resecrita contextualizada.
Sistema de Plugins por Rule Pack
// plugins/sql-inject/regras.go
func init() {
RegistrarPacoteRegras("sql-inject", &PacoteSQLInject{
Regras: []Regra{
{ID: "sql-001", Padrao: `(?i)select.*from.*union.*select`, Severidade: "ALTA"},
},
})
}
Otimizações de Performance
Processamento paralelo em 128 slots para milhões de tokens:
func (m *Motor) processarSlot(idSlot int, tokens []Token) {
m.cache.Lock()
defer m.cache.Unlock()
atribuicao := m.poolAtribuicoes.Get().(*Atribuicao)
defer m.poolAtribuicoes.Put(atribuicao)
atribuicao.Calcular(tokens)
}
| Métrica | Antes | Depois |
|---|---|---|
| Latência P99 | 1.82s | 0.89s |
| Pico de Memória | 4.2 GB | 2.6 GB |