- Ao ajudar no desenvolvimento de apps de IA que lidam com dados de e-commerce, foi identificado um problema: o Retrieval-augmented generation (RAG) funcionava bem para algumas consultas, mas não para outras
- Ao resolver esse tipo de problema, é importante examinar os dados de entrada (o texto-fonte indexado e as consultas de usuário usadas na busca)
- Em especial, parecia haver necessidade de otimização nos aspectos de chunking e tokenização
[Tokenization]
- Tokenização é o processo de decompor texto em partes menores, chamadas tokens, por meio de um tokenizer
- Esses tokens são mapeados para IDs de token, que são valores inteiros que identificam unicamente cada token dentro do vocabulário do tokenizer
- O vocabulário do tokenizer é o conjunto de todos os tokens possíveis usados no treinamento do tokenizer
- Problemas podem surgir quando os tokens de um texto não existem no vocabulário do tokenizer do LLM
- A maioria dos LLMs tem vocabulários grandes, na faixa de 30k a 300k
- A maioria dos LLMs amplamente usados depende de tokenizers subword (BPE, Wordpiece etc.)
- Tipos de tokenizer
- word: divide com base em espaços em branco, pontuação etc.
- character: divide em caracteres individuais (às vezes até pontuação)
- subword: divide tokens em subpalavras que podem parecer sem sentido
- a maioria dos LLMs usa tokenizers subword
- BPE(Byte-Pair Encoder): biblioteca
tiktoken da OpenAI
- Wordpiece: Cohere, MiniLM-L6-v2 etc.
Comparação entre MiniLM-L6-v2 e tiktoken
- O tamanho do vocabulário do tokenizer do modelo MiniLM-L6-v2 é 30522, muito menor que o do tiktoken (200019)
- Ao tokenizar a frase "tokenizer tokenizes text into tokens"
- MiniLM-L6-v2: [CLS] token ##izer token ##izes text into token ##s [SEP]
- tiktoken: token, izer, token, izes, text, into, tokens
- A biblioteca
tiktoken da OpenAI implementa um tokenizer BPE e é usada nos modelos LLM do ChatGPT
- O vocabulário do MiniLM-L6-v2 também inclui caracteres alemães e japoneses
Tokenização de emoji, erros de digitação e palavras específicas de domínio
- O MiniLM-L6-v2 tokeniza emojis como o token [UNK]
- O
tiktoken foi treinado com alguns tokens de caracteres Unicode, mas isso ainda pode ser um problema em RAG
- Nomes de produtos específicos de domínio, como "Gucci Savoy Leathertrimmed Printed Coatedcanvas Suitcase", também não são tokenizados adequadamente
- No caso de uma frase com erro de digitação ("I hve received wrong pckage")
- MiniLM-L6-v2: i, h, ##ve, received, wrong, pc, ##ka, ##ge
- tiktoken: I, h, ve, received, wrong, p, ck, age
[Embeddings]
- O tokenizer, por si só, não é muito útil. Ele foi desenvolvido principalmente para fazer análises numéricas complexas com base na frequência de tokens individuais
- Para preservar o significado contextual do texto, é necessário um método que consiga capturar as relações entre os tokens
- Embeddings são vetores que representam tokens e capturam bem os significados e relações entre palavras no texto
- Embeddings são um subproduto do treinamento de transformers e são efetivamente aprendidos a partir de grandes volumes de texto tokenizado
- Quando você solicita geração de texto, o que é dado como entrada ao LLM são justamente os embeddings
- Um LLM é composto por dois componentes principais: encoder e decoder
- Tanto o encoder quanto o decoder recebem embeddings como entrada
- A saída do encoder também é um embedding, que é passado para as heads de cross-attention do decoder e desempenha papel importante na geração (previsão) de tokens na saída do decoder
- Em um pipeline de RAG, o texto é primeiro tokenizado, depois transformado em embeddings e então inserido no transformer
- IDs de token funcionam como índices no vocabulário do tokenizer e também são usados para buscar embeddings na matriz de embeddings
- Os embeddings recuperados são montados em um tensor e fornecidos como entrada ao transformer
- Fluxo do encoder: tokenização do texto -> buscar embeddings de cada token -> montar tensor de embeddings -> inserir na entrada do transformer -> encoding -> passar a saída do encoder para a cross-attention do decoder -> gerar a saída do decoder
Exemplos de embedding
- "You can break it 😞" e "You can not break it 😊" têm sentimentos opostos, mas no MiniLM-L6-v2 a distância entre os embeddings é muito pequena
- A OpenAI apresenta desempenho melhor porque o vocabulário de tokens lida melhor com emojis
- A OpenAI também lida melhor com erros de digitação
- Porém, mesmo na OpenAI, adicionar um espaço no final da frase faz a distância entre embeddings aumentar mais do que o esperado
- Desenvolvedores também têm dificuldade ao lidar com formatos de data. Expressões de tempo relativo ("foi enviado ontem") podem ser um problema ainda maior
- Diferenças em formas de representar moeda (£40, $50, 40£, 50¢ etc.) também podem causar problemas estranhos
- Em dados específicos de domínio, como no caso da bolsa Gucci, isso geralmente é resolvido com fine-tuning, mas é sempre essencial verificar os dados e as métricas de avaliação
Conclusão
- Este texto ajuda a entender melhor como tokenizers podem afetar apps RAG e por que vale a pena prestar atenção neles
- Em aplicações com agentes, garbage-in garbage-out nem sempre vai entregar o desempenho esperado
- Fazer uma pequena limpeza no texto de entrada já pode ajudar bastante
- padronizar formatos de data de forma consistente
- remover espaços em branco à direita sempre que possível (foi observado impacto nos embeddings)
- aplicar o mesmo também a outros dados numéricos, como preços em moedas diferentes
- Quem sabe um dia não seja mais necessário pensar em tokenizers. Talvez possamos descartá-los por completo
- Se isso acontecer, não será mais preciso lidar com erros de digitação, espaços em branco arbitrários, ataques adversariais baseados em perplexity de palavras etc. Uma categoria inteira de tristeza poderá desaparecer da noite para o dia
- Até lá, tokenize com responsabilidade
Opinião do GN⁺
- Este texto mostra bem como tokenizers e embeddings podem afetar o desempenho de apps de IA baseados em RAG. Em especial, ao lidar com emojis, erros de digitação e termos específicos de domínio, ele explica com casos reais os pontos que exigem cuidado, o que deve ser muito útil para desenvolvedores
- No entanto, tanto o MiniLM-L6-v2 quanto o
tiktoken apresentados aqui são modelos otimizados para inglês, então pode haver considerações adicionais ao lidar com outros idiomas, como o coreano. No caso do coreano, é comum usar tokenização com analisadores morfológicos, e também parece importante examinar as vantagens, desvantagens e limitações disso
- Além disso, embora o texto se concentre no papel de tokenizers e embeddings no pipeline de RAG, em ambientes reais de produção há muito mais fatores a considerar, como pré-processamento de dados, ajuste de hiperparâmetros e compactação de modelos. Portanto, é melhor tomar o conteúdo deste texto como ponto de partida e buscar o método ideal por meio de vários experimentos e avaliações durante o desenvolvimento real
- Por outro lado, também existe a opinião de que a importância do tokenizer está diminuindo com a chegada de grandes modelos de linguagem como o GPT-4. Como esses modelos operam no nível de frases ou parágrafos, e não no nível de tokens individuais, o impacto da qualidade de cada token no desempenho pode ser relativamente menor. Ainda assim, parece difícil afirmar isso com certeza, já que ainda não há pesquisa suficiente sobre o tema
- Por fim, como mencionado no texto, apenas limpar e padronizar os dados de entrada com antecedência já pode melhorar bastante o desempenho do modelo. Ao desenvolver serviços reais, é muito importante construir um pipeline robusto de pré-processamento de dados levando em conta a diversidade e o ruído das entradas dos usuários. Além disso, também parece necessário investir recursos suficientes em rotulagem e anotação de dados para garantir dados de treinamento de alta qualidade
1 comentários
Comentários do Hacker News
Tokenizers não são vistos como a parte "sexy" dos LLMs, mas há quem veja isso como uma oportunidade. Artigos como xVal propõem estratégias de especialização da tokenização. Tarefas de ortografia e manipulação de caracteres são outro tipo de problema que pode se beneficiar de inovação em tokenização
É preciso entender os dados para realizar um trabalho significativo. O principal motivo de muitas pessoas usarem ferramentas automatizadas de processamento de dados é não querer olhar diretamente para os dados. Elas querem que o computador veja os dados e peça a coleta de informações adicionais
Gostei especialmente da parte sobre erros de digitação no post do blog. Estou ajudando com uma aplicação parecida com RAG em um projeto e me preocupo com o impacto de pequenos erros de digitação ou diferenças de formatação nas consultas dos usuários sobre o cálculo de distância entre embeddings
Já trabalhei em um app que usava Elasticsearch para lidar, com consultas de texto avançadas, com similaridade entre entradas de 1-2 frases e documentos com parágrafos ou mais. Foi interessante ver o quanto a estratégia de tokenização pode afetar consultas específicas
Sinto falta, no artigo, de uma discussão sobre soluções para cada problema. Sugiro executar a verificação ortográfica antes da tokenização ou tokenizar lado a lado a palavra com erro e suas possíveis correções
Muitos desenvolvedores estão acostumados a desenvolver no espaço tradicional (determinístico), mas não conseguem mudar a forma de pensar os problemas no espaço estatístico. Apps com LLM são, no fim das contas, um espaço estatístico
A maioria das pessoas que implementa RAG pensa em embeddings, não em tokenização
Não consigo reproduzir alguns números do post do blog. Por exemplo, no código usando SentenceTransformer, o resultado do cálculo de similaridade de cosseno entre duas frases é diferente do esperado
Em várias implementações de RAG, vi o problema de assumir que o documento-alvo será uma boa chave de busca para as consultas recebidas. Em um projeto recente, a relevância da busca melhorou muito ao separar a chave de busca do valor retornado (o documento dividido em chunks) e usar um LM para gerar e embutir chaves apropriadas
Dizem que muitos vocabulários de LLMs grandes são bem extensos, mas só o inglês já tem mais de 1 milhão de palavras. De 30k a 300k tokens parece pouco