Hugging Face Optimum: Inferência Rápida

Hugging Face Optimum: Inferência Rápida

Aviso: Este post foi traduzido para o português usando um modelo de tradução automática. Por favor, me avise se encontrar algum erro.

Optimun é uma extensão da biblioteca Transformers que fornece um conjunto de ferramentas de otimização de desempenho para treinar e inferir modelos, em hardware específico, com a máxima eficiência.

O ecossistema de IA evolui rapidamente e a cada dia surge mais hardware especializado junto com suas próprias otimizações. Portanto, Optimum permite aos usuários utilizar eficientemente qualquer deste HW com a mesma facilidade que Transformers.

Optimun permite a otimização para as seguintes plataformas HW:

  • Nvidia
  • AMD
  • Intel
  • AWS
  • TPU
  • Havana
  • FuriosaIA

Além disso, oferece aceleração para as seguintes integrações open source

  • Tempo de execução do ONNX
  • Exportadores: Exportar modelos Pytorch ou TensorFlow para diferentes formatos como ONNX ou TFLite
  • BetterTransformer
  • Torch FX

Instalaçãolink image 13

Para instalar Optimun simplesmente execute:

pip install optimum

Mas se quiser instalar com suporte para todas as plataformas HW, pode ser feito assim

Acelerador Instalação
ONNX Runtime pip install --upgrade --upgrade-strategy eager optimum[onnxruntime]
Intel Neural Compressor pip install --upgrade --upgrade-strategy eager optimum[neural-compressor]
OpenVINO pip install --upgrade --upgrade-strategy eager optimum[openvino]
GPUs AMD Instinct e NPU Ryzen AI pip install --upgrade --upgrade-strategy eager optimum[amd]
AWS Trainum & Inferentia pip install --upgrade --upgrade-strategy eager optimum[neuronx]
Processador Habana Gaudi (HPU) pip install --upgrade --upgrade-strategy eager optimum[habana]
FuriosaAI pip install --upgrade --upgrade-strategy eager optimum[furiosa]

Os flags --upgrade --upgrade-strategy eager são necessários para garantir que os diferentes pacotes sejam atualizados para a versão mais recente possível.

Como a maioria das pessoas usa o Pytorch em GPUs da Nvidia, e principalmente, como eu tenho uma Nvidia, este post vai falar apenas sobre o uso do Optimun com GPUs da Nvidia e Pytorch.

BeterTransformerlink image 14

BetterTransformer é uma otimização nativa do PyTorch para obter um aumento de velocidade de x1,25 a x4 na inferência de modelos baseados em Transformer

BetterTransformer é uma API que permite aproveitar as características de hardware modernas para acelerar o treinamento e a inferência de modelos de transformers no PyTorch, utilizando implementações de atenção mais eficientes e fast path da versão nativa de nn.TransformerEncoderLayer.

BetterTransformer usa dois tipos de acelerações:

  1. Flash Attention: Esta é uma implementação da attention que utiliza sparse para reduzir a complexidade computacional. A atenção é uma das operações mais custosas nos modelos de transformers, e Flash Attention torna-a mais eficiente.
  2. Atenção Eficiente em Memória: Esta é outra implementação da atenção que utiliza a função scaled_dot_product_attention do PyTorch. Essa função é mais eficiente em termos de memória do que a implementação padrão da atenção no PyTorch.

Além disso, a versão 2.0 do PyTorch inclui um operador de atenção de produtos ponto escalado (SDPA) nativo como parte de torch.nn.functional

Optimun fornece esta funcionalidade com a biblioteca Transformers

Inferência com Automodellink image 15

Primeiro vamos a ver como seria a inferência normal com Transformers e Automodel

	
< > Input
Python
from transformers import AutoTokenizer, AutoModelForCausalLM
checkpoint = "openai-community/gpt2"
tokenizer = AutoTokenizer.from_pretrained(checkpoint)
model = AutoModelForCausalLM.from_pretrained(checkpoint, device_map="auto")
tokenizer.pad_token = tokenizer.eos_token
input_tokens = tokenizer(["Me encanta aprender de"], return_tensors="pt", padding=True).to("cuda")
output_tokens = model.generate(**input_tokens, max_length=50)
sentence_output = tokenizer.decode(output_tokens[0], skip_special_tokens=True)
sentence_output
Copied
>_ Output
			
Setting `pad_token_id` to `eos_token_id`:50256 for open-end generation.
>_ Output
			
'Me encanta aprender de la vie de la vie de la vie de la vie de la vie de la vie de la vie de la vie de la vie de la vie de la vie de'

Agora veremos como isso seria otimizado com BetterTransformer e Optimun

O que temos que fazer é converter o modelo usando o método transform de BetterTransformer

	
< > Input
Python
from transformers import AutoTokenizer, AutoModelForCausalLM
from optimum.bettertransformer import BetterTransformer
checkpoint = "openai-community/gpt2"
tokenizer = AutoTokenizer.from_pretrained(checkpoint)
model_hf = AutoModelForCausalLM.from_pretrained(checkpoint, device_map="auto")
# Convert the model to a BetterTransformer model
model = BetterTransformer.transform(model_hf, keep_original_model=True)
tokenizer.pad_token = tokenizer.eos_token
input_tokens = tokenizer(["Me encanta aprender de"], return_tensors="pt", padding=True).to("cuda")
output_tokens = model.generate(**input_tokens, max_length=50)
sentence_output = tokenizer.decode(output_tokens[0], skip_special_tokens=True)
sentence_output
Copied
>_ Output
			
The BetterTransformer implementation does not support padding during training, as the fused kernels do not support attention masks. Beware that passing padded batched data during training may result in unexpected outputs. Please refer to https://huggingface.co/docs/optimum/bettertransformer/overview for more details.
Setting `pad_token_id` to `eos_token_id`:50256 for open-end generation.
>_ Output
			
'Me encanta aprender de la vie de la vie de la vie de la vie de la vie de la vie de la vie de la vie de la vie de la vie de la vie de'

Inferência com Pipelinelink image 16

Assim como antes, primeiro vemos como seria a inferência normal com Transformers e Pipeline

	
< > Input
Python
from transformers import pipeline
pipe = pipeline(task="fill-mask", model="distilbert-base-uncased")
pipe("I am a student at [MASK] University.")
Copied
>_ Output
			
[{'score': 0.05116177722811699,
'token': 8422,
'token_str': 'stanford',
'sequence': 'i am a student at stanford university.'},
{'score': 0.04033993184566498,
'token': 5765,
'token_str': 'harvard',
'sequence': 'i am a student at harvard university.'},
{'score': 0.03990468755364418,
'token': 7996,
'token_str': 'yale',
'sequence': 'i am a student at yale university.'},
{'score': 0.0361952930688858,
'token': 10921,
'token_str': 'cornell',
'sequence': 'i am a student at cornell university.'},
{'score': 0.03303057327866554,
'token': 9173,
'token_str': 'princeton',
'sequence': 'i am a student at princeton university.'}]

Agora vemos como otimizá-lo, para isso usamos pipeline de Optimun, em vez do de Transformers. Além disso, é necessário indicar que queremos usar bettertransformer como acelerador.

	
< > Input
Python
from optimum.pipelines import pipeline
# Use the BetterTransformer pipeline
pipe = pipeline(task="fill-mask", model="distilbert-base-uncased", accelerator="bettertransformer")
pipe("I am a student at [MASK] University.")
Copied
>_ Output
			
The BetterTransformer implementation does not support padding during training, as the fused kernels do not support attention masks. Beware that passing padded batched data during training may result in unexpected outputs. Please refer to https://huggingface.co/docs/optimum/bettertransformer/overview for more details.
/home/wallabot/miniconda3/envs/nlp/lib/python3.11/site-packages/optimum/bettertransformer/models/encoder_models.py:868: UserWarning: The PyTorch API of nested tensors is in prototype stage and will change in the near future. (Triggered internally at /opt/conda/conda-bld/pytorch_1708025845868/work/aten/src/ATen/NestedTensorImpl.cpp:177.)
hidden_states = torch._nested_tensor_from_mask(hidden_states, attn_mask)
>_ Output
			
[{'score': 0.05116180703043938,
'token': 8422,
'token_str': 'stanford',
'sequence': 'i am a student at stanford university.'},
{'score': 0.040340032428503036,
'token': 5765,
'token_str': 'harvard',
'sequence': 'i am a student at harvard university.'},
{'score': 0.039904672652482986,
'token': 7996,
'token_str': 'yale',
'sequence': 'i am a student at yale university.'},
{'score': 0.036195311695337296,
'token': 10921,
'token_str': 'cornell',
'sequence': 'i am a student at cornell university.'},
{'score': 0.03303062543272972,
'token': 9173,
'token_str': 'princeton',
'sequence': 'i am a student at princeton university.'}]

Treinamentolink image 17

Para o treinamento com Optimun fazemos o mesmo que com a inferência com Automodel, convertemos o modelo por meio do método transform de BeterTransformer.

Quando terminamos o treinamento, voltamos a converter o modelo usando o método reverse de BetterTransformer para recuperar o modelo original e assim poder salvá-lo e enviá-lo para o hub da Hugging Face.

	
< > Input
Python
from transformers import AutoTokenizer, AutoModelForCausalLM
from optimum.bettertransformer import BetterTransformer
checkpoint = "openai-community/gpt2"
tokenizer = AutoTokenizer.from_pretrained(checkpoint)
model_hf = AutoModelForCausalLM.from_pretrained(checkpoint, device_map="auto")
# Convert the model to a BetterTransformer model
model = BetterTransformer.transform(model_hf, keep_original_model=True)
##############################################################################
# do your training here
##############################################################################
# Convert the model back to a Hugging Face model
model_hf = BetterTransformer.reverse(model)
model_hf.save_pretrained("fine_tuned_model")
model_hf.push_to_hub("fine_tuned_model")
Copied

Posts relacionados

Perguntas frequentes

O que faz o parâmetro keep_original_model=True em BetterTransformer.transform()?

Ao converter um modelo com BetterTransformer.transform(model_hf, keep_original_model=True), o Optimum substitui as camadas de atenção pelas implementações otimizadas (Flash Attention e Memory-Efficient Attention baseada na scaled_dot_product_attention do PyTorch), mas mantém uma cópia do modelo original na memória em vez de modificá-lo in-place. Isso permite continuar usando a referência original (model_hf) junto com a versão acelerada (model), embora duplique o consumo de memória enquanto as duas coexistirem.

Por que é preciso chamar BetterTransformer.reverse() antes de salvar ou enviar o modelo para o hub após o treinamento?

Um modelo convertido com BetterTransformer.transform() usa camadas internas modificadas (o fast path de nn.TransformerEncoderLayer) que não são compatíveis com o formato padrão esperado por save_pretrained() ou push_to_hub() do Transformers. Por isso, após o treinamento, é preciso executar model_hf = BetterTransformer.reverse(model) para restaurar a arquitetura original do modelo antes de chamar model_hf.save_pretrained("fine_tuned_model") e model_hf.push_to_hub("fine_tuned_model"); sem isso, o modelo salvo fica em um estado incompatível.

Continuar lendo

Últimos posts -->

Você viu esses projetos?

Gymnasia

Gymnasia Gymnasia
Expo
React Native
TypeScript
OpenAI
Anthropic

App de fitness com dois agentes que são executados integralmente no dispositivo, sem backend, de forma que os dados do usuário nunca saem do celular. Um coach conversacional BYOK com adaptadores para OpenAI, Anthropic e Google, 12 tools locais e system prompt remoto com fallback offline, e um subagente de visão que estima macronutrientes a partir de fotos de comida, com leitura de códigos de barras contra o OpenFoodFacts.

LangGraph Deep Researcher

LangGraph Deep Researcher LangGraph Deep Researcher
Python
LangGraph
FastAPI
React
TypeScript
Docker

Sistema multiagente de pesquisa construído com LangGraph. Um supervisor decompõe sua pergunta em tópicos e lança subagentes de busca em paralelo; cada um comprime seus achados antes de repassá-los a um agente redator que escreve o relatório final em markdown com suas fontes. Streaming ao vivo por WebSockets, modelo configurável por papel e chaves de API próprias que nunca são armazenadas no servidor.

Tau

Tau Tau
Python
LangChain

Sistema multiagente de tutoria para estudantes do ensino médio, com um agente por disciplina e material de curso elaborado e validado por uma equipe de professores. Chegou a ser usado com alunos reais em um colégio privado na Espanha e em uma escola de ensino médio na Colômbia.

Ver todos os projetos -->
>_ Disponível para projetos

Tem um projeto com IA?

Vamos conversar.

maximofn@gmail.com

Especialista em Machine Learning e Inteligência Artificial. Desenvolvo soluções com IA generativa, agentes inteligentes e modelos personalizados.

Quer assistir alguma palestra?

Últimas palestras -->

Quer melhorar com essas dicas?

Últimos tips -->

Use isso localmente

Os espaços do Hugging Face nos permitem executar modelos com demos muito simples, mas e se a demo quebrar? Ou se o usuário a deletar? Por isso, criei contêineres docker com alguns espaços interessantes, para poder usá-los localmente, aconteça o que acontecer. Na verdade, se você clicar em qualquer botão de visualização de projeto, ele pode levá-lo a um espaço que não funciona.

Flow edit

Flow edit Flow edit

Edite imagens com este modelo de Flow. Baseado em SD3 ou FLUX, você pode editar qualquer imagem e gerar novas

FLUX.1-RealismLora

FLUX.1-RealismLora FLUX.1-RealismLora
Ver todos os contêineres -->
>_ Disponível para projetos

Tem um projeto com IA?

Vamos conversar.

maximofn@gmail.com

Especialista em Machine Learning e Inteligência Artificial. Desenvolvo soluções com IA generativa, agentes inteligentes e modelos personalizados.

Você quer treinar seu modelo com esses datasets?

short-jokes-dataset

HuggingFace

Dataset com piadas em inglês

Uso: Fine-tuning de modelos de geração de texto humorístico

231K linhas 2 colunas 45 MB
Ver no HuggingFace →

opus100

HuggingFace

Dataset com traduções de inglês para espanhol

Uso: Treinamento de modelos de tradução inglês-espanhol

1M linhas 2 colunas 210 MB
Ver no HuggingFace →

netflix_titles

HuggingFace

Dataset com filmes e séries da Netflix

Uso: Análise de catálogo Netflix e sistemas de recomendação

8.8K linhas 12 colunas 3.5 MB
Ver no HuggingFace →
Ver mais datasets -->