9 pontos por GN⁺ 2024-10-24 | 1 comentários | Compartilhar no WhatsApp
  • 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

 
GN⁺ 2024-10-24
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

    • LLMs são fracos para contar o número de caracteres em uma palavra ou remover caracteres. Por exemplo, o GPT-4o escreve e executa um pequeno programa em Python para contar ocorrências de caracteres. A tokenização efetivamente apaga o conhecimento sobre os caracteres do prompt e impacta diretamente de forma negativa o desempenho nessas tarefas
  • É 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

    • Estou pensando se deveríamos adicionar erros de digitação/substituições/uso de maiúsculas intencionais aos dados de treinamento para que ele aprenda que "wrk" e "work" provavelmente são sinônimos
  • 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

    • Por exemplo, em casos como "W-4" ou "W4", a tokenização padrão pode dividir no "-" ou na fronteira entre letra e número. Isso faz com que essa entrada deixe de ser identificável no índice
  • 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

    • Não sei qual seria a solução para o problema com nomes de marcas. Esse problema pode ser mais grave em idiomas menos comuns ou em idiomas que usam muitas palavras compostas
  • 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

    • Como desenvolvedor, tenho dificuldade para explicar isso aos usuários
  • A maioria das pessoas que implementa RAG pensa em embeddings, não em tokenização

    • Dividem o corpus de dados em chunks e calculam embeddings para cada chunk. Geram consultas e calculam embeddings para cada uma. Rankeiam os chunks do corpus pela distância em relação à consulta. Montam o valor de retorno
    • Este artigo destaca a importância de um trabalho oculto e relativamente mundano que pode ter grande impacto no desempenho do sistema
  • 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