3 pontos por GN⁺ 2024-04-13 | 1 comentários | Compartilhar no WhatsApp
  • Transformers.js é uma biblioteca para executar modelos 🤗 Transformers no navegador sem servidor, com o objetivo de ser funcionalmente equivalente ao transformers em Python da Hugging Face e oferecer uma API semelhante
  • A execução dos modelos usa ONNX Runtime, e modelos pré-treinados em PyTorch, TensorFlow e JAX podem ser convertidos para ONNX com 🤗 Optimum
  • Com a API pipeline, é possível chamar tarefas como análise de sentimento de forma parecida com Python, e selecionar outro modelo informando o ID do modelo ou caminho como segundo argumento
  • A execução padrão no navegador usa CPU baseada em WASM, e é possível escolher execução via WebGPU com device: 'webgpu', embora a API WebGPU ainda seja experimental em vários navegadores
  • Em ambientes com recursos limitados, como navegadores web, é possível escolher tipos de dados como "fp32", "fp16", "q8" e "q4" com dtype para ajustar largura de banda e desempenho

Transformers em execução no navegador

  • Transformers.js é uma biblioteca projetada para executar 🤗 Transformers diretamente no navegador sem servidor
  • Ela busca uma experiência de uso funcionalmente equivalente à da biblioteca Python transformers da Hugging Face, permitindo executar os mesmos modelos pré-treinados com uma API muito semelhante
  • As tarefas suportadas abrangem várias modalidades
    • Processamento de linguagem natural: classificação de texto, reconhecimento de entidades nomeadas, perguntas e respostas, modelagem de linguagem, sumarização, tradução, múltipla escolha, geração de texto
    • Visão computacional: classificação de imagens, detecção de objetos, segmentação, estimativa de profundidade
    • Áudio: reconhecimento automático de fala, classificação de áudio, conversão de texto em fala
    • Multimodal: embeddings, classificação de áudio zero-shot, classificação de imagens zero-shot, detecção de objetos zero-shot

Forma de execução e conversão de modelos

Instalação e uso no navegador

  • O pacote NPM pode ser instalado com o comando abaixo
npm i @huggingface/transformers
  • Também é possível usar em JavaScript puro sem bundler, importando como ES Modules via CDN ou hospedagem estática
<script type="module">
    import { pipeline } from 'https://cdn.jsdelivr.net/npm/@huggingface/transformers@4.2.0';
</script>

API pipeline semelhante à do Python

  • A API pipeline reúne modelo pré-treinado, pré-processamento de entrada e pós-processamento de saída, sendo a forma mais simples de executar modelos na biblioteca
  • Assim como no exemplo de análise de sentimento do transformers em Python, em JavaScript também é possível criar pipeline('sentiment-analysis'), inserir um texto e receber o resultado
import { pipeline } from '@huggingface/transformers';

const pipe = await pipeline('sentiment-analysis');
const out = await pipe('I love transformers!');
// [{'label': 'POSITIVE', 'score': 0.999817686}]
  • Para usar outro modelo, informe o ID do modelo ou caminho como segundo argumento da função pipeline
const pipe = await pipeline(
  'sentiment-analysis',
  'Xenova/bert-base-multilingual-uncased-sentiment'
);

CPU, WebGPU e opções de quantização

  • O padrão de execução no navegador é via CPU baseada em WASM
  • Para executar na GPU, defina device: 'webgpu'
const pipe = await pipeline(
  'sentiment-analysis',
  'Xenova/distilbert-base-uncased-finetuned-sst-2-english',
  {
    device: 'webgpu',
  }
);
  • Mais detalhes sobre WebGPU estão no guia de WebGPU
  • Como a API WebGPU ainda é experimental em vários navegadores, a documentação orienta enviar relatórios de bug do WebGPU caso ocorram problemas
  • Em ambientes de navegador com recursos limitados, recomenda-se usar modelos quantizados
    • A opção dtype permite escolher o tipo de dado do modelo
    • As escolhas comuns são "fp32" como padrão no WebGPU, "fp16", "q8" como padrão no WASM, e "q4"
    • Mais detalhes estão no guia de quantização
const pipe = await pipeline(
  'sentiment-analysis',
  'Xenova/distilbert-base-uncased-finetuned-sst-2-english',
  {
    dtype: 'q4',
  }
);

Configuração personalizada

import { env } from '@huggingface/transformers';

env.localModelPath = '/path/to/models/';
env.allowRemoteModels = false;
env.backends.onnx.wasm.wasmPaths = '/path/to/files/';
  • A lista completa de configurações disponíveis está na API Reference
  • Ao converter modelos PyTorch para ONNX, recomenda-se a abordagem de comando único com Optimum

Tarefas suportadas e escopo dos modelos

  • Para encontrar modelos compatíveis no Hugging Face Hub, é possível filtrar pela tag da biblioteca transformers.js
  • As tarefas suportadas abrangem processamento de linguagem natural, visão, áudio, multimodal e aprendizado por reforço, embora algumas ainda não sejam suportadas
    • Em processamento de linguagem natural, são suportados fill-mask, question-answering, summarization, text-classification, text-generation, token-classification, translation, zero-shot-classification, feature-extraction e outros
    • Em visão, são suportados background-removal, depth-estimation, image-classification, image-segmentation, image-to-image, object-detection, image-feature-extraction e outros
    • Em áudio, são suportados audio-classification, automatic-speech-recognition e text-to-speech
    • Em multimodal, são suportados document-question-answering, image-to-text, zero-shot audio/image classification, zero-shot object detection e outros
  • Também há indicação explícita das tarefas ainda não suportadas
    • table-question-answering, mask-generation, video-classification, unconditional-image-generation
    • audio-to-audio, tabular-classification, tabular-regression
    • text-to-image, visual-question-answering
  • A lista de arquiteturas de modelos suportadas inclui muitas famílias, como BERT, BART, CLIP, DistilBERT, Whisper, Llama, Qwen, Gemma, Phi, Segment Anything e ViT
  • Se a tarefa ou o modelo desejado não estiver na lista ou ainda não for suportado, é possível abrir uma solicitação de funcionalidade

1 comentários

 
GN⁺ 2024-04-13
Comentários no Hacker News
  • Esta biblioteca é muito legal. É incrivelmente fácil colocar uma demo rápida no ar, então já a usei algumas vezes em notebooks do Observable
    CLIP no navegador: https://observablehq.com/@simonw/openai-clip-in-a-browser
    Detecção de objetos em imagens com detra-resnet-50: https://observablehq.com/@simonw/detect-objects-in-images
    O tamanho dos modelos parece uma limitação no começo, mas há bastante apps em que não é absurdo pedir a usuários com um bom notebook e uma boa conexão que esperem uns 30 segundos pelo carregamento
    A versão mais recente adicionou suporte a quantização de embeddings binários, e estou muito a fim de testar: https://github.com/xenova/transformers.js/releases/tag/2.17....
    • Embeddings binários provavelmente exigiriam uma reordenação adicional, mas parece divertido testar
      Criei um pacote npm para o transformers.js v3 e acho que preciso atualizá-lo. Não tenho certeza se ele já inclui esse recurso
      Eu mantinha o fork principalmente para fazê-lo rodar no bun, mas quando o v3 for lançado, ele deve oferecer suporte adequado ao bun. Só que o WebGPU não vai funcionar, embora seja um recurso opcional
      [edição: se quiser usar, mande DM. Não quero ficar promovendo o fork]
  • Estou usando esta biblioteca para gerar embeddings gte-small (~0,07 GB) e armazená-los no Upstash Vector
    São só 384 dimensões, mas funciona surpreendentemente bem em texto no nível de parágrafo. No ranking, ele também aparece acima do text-embedding-ada-002
    https://huggingface.co/spaces/mteb/leaderboard
  • O podcast Syntax lançou recentemente um episódio sobre Transformers.js e seu desenvolvedor
    https://syntax.fm/show/740/local-ai-models-in-javascript-mac...
  • transformers.js é uma biblioteca realmente muito legal
    Criei um pequeno webapp para remoção de fundo de imagens com o modelo RMBG1.4 da BRIA AI: https://aether.nco.dev
    É ótimo não precisar enviar dados para uma API e ele ainda roda em smartphones. Acho que veremos muitos projetos usando isso para modelos pequenos de visão, linguagem e outras utilidades (estimativa de profundidade, remoção de fundo etc.), e o futuro da web parece promissor
    Já estou trabalhando no próximo projeto e, com certeza, vou usar transformers.js de novo nele
    • Estou usando em um projeto simples: https://github.com/sroussey/ellmers
      A ideia é testar embeddings e estratégias de busca para várias estratégias de RAG a serem usadas em servidores ou apps Electron
  • É muito legal, mas infelizmente a praticidade parece bem baixa. Como os modelos em geral são bem grandes, mesmo que o navegador consiga executá-los, levá-los até o navegador exige uma de duas coisas
    1. Um download grande toda vez que você visita o site
    2. Um download grande e muito uso de armazenamento para cada site que usa um modelo grande. Por exemplo, 150 sites × um modelo de 800 MB consumiriam 120 GB de armazenamento
      As duas opções são ruins
      No longo prazo, talvez o caminho certo seja o navegador trazer alguns modelos embutidos e expô-los por uma API Web padronizada, mas ainda não ouvi falar de nenhum esforço desse tipo em andamento

Os modelos são armazenados em cache por domínio (usando a Web Cache API), então não é preciso baixá-los novamente a cada carregamento da página. Se você quiser manter modelos entre domínios, pode criar uma extensão de navegador com esta biblioteca
A última parte mencionada é um esforço em andamento, mas ainda não está em um estágio em que se possa falar sobre isso

  • É praticamente o mesmo problema que aflige jogos Web desde as primeiras demos de Unreal/Unity em asm.js, há 10 anos, e desde então houve pouco progresso rumo a uma solução
    É difícil criar, de forma prática, webapps que exijam gigabytes de dados no cliente. Não há uma forma estável de garantir que eles permaneçam no cache pelo tempo que o usuário quiser e, mesmo que fosse possível armazenar em cache de forma confiável, por causa das políticas de particionamento de cache dos navegadores, cada site que usa o mesmo modelo acaba duplicando o download e o espaço de armazenamento
  • Os modelos têm menos de 80 MB, e o restante é LLM, portanto está fora do escopo. Whisper tem 40 MB, embeddings têm 23 MB
    Partes do comentário original como “parece muito impraticável”, “os modelos em geral são bem grandes” e “150 sites × modelo de 800 MB” parecem vir com a própria ressalva de que há falta de entendimento
  • Alguns modelos são bem pequenos, então vale a pena executá-los on-device em vez de enviar todos os dados para um servidor para processamento
    Outra grande vantagem é que transformers também roda em Node.js. É muito mais fácil montar um ambiente de execução do que acertar uma combinação estranha de Python e suas dependências
  • Isso não é um problema exclusivo do navegador, mas sim um problema essencial do processamento de IA on-device
    Parece que a situação só deve melhorar quando os sistemas operacionais começarem a pré-instalar modelos e a fornecer APIs que os fornecedores de navegadores também possam usar
    Mesmo assim, para a maioria das tarefas, é bem provável que modelos hospedados na nuvem continuem sendo muito melhores
  • Então agora dá para criar um plugin de navegador que seleciona todas as bicicletas ou pontes nos CAPTCHAs do Google?
  • Treinamento não é possível? Alguns anos atrás, experimentei criar e treinar pequenas redes neurais no navegador, e fico curioso se hoje isso funcionaria melhor dessa forma com um transformer customizado pequeno
    • Em teoria, certamente é possível, mas acho que problemas de desempenho provavelmente são o motivo de ainda não ter sido implementado
      Há um benchmark de embeddings com WebGPU no Hugging Face Space que permite ter uma noção da execução de inferência: https://huggingface.co/spaces/Xenova/webgpu-embedding-benchm...
      Por si só é impressionante, mas treinar com essa latência deve ser sofrido. Com fp16, batch 32 e comprimento de sequência 512, a inferência de um modelo com 22 milhões de parâmetros leva cerca de 500 ms
  • Isso também não abre a possibilidade de rodar esses modelos em funções serverless de Node.js?
    Parece que certamente também cria possibilidades para previsões sob demanda
  • Há suporte a aceleração em Apple Silicon?