Instructions to use vkusterl/extrator-cardapios-0.5b with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use vkusterl/extrator-cardapios-0.5b with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-generation", model="vkusterl/extrator-cardapios-0.5b") messages = [ {"role": "user", "content": "Who are you?"}, ] pipe(messages)# pip install -U transformers accelerate # Load model directly from transformers import AutoTokenizer, AutoModelForCausalLM tokenizer = AutoTokenizer.from_pretrained("vkusterl/extrator-cardapios-0.5b") model = AutoModelForCausalLM.from_pretrained("vkusterl/extrator-cardapios-0.5b", device_map="auto") messages = [ {"role": "user", "content": "Who are you?"}, ] inputs = tokenizer.apply_chat_template( messages, add_generation_prompt=True, tokenize=True, return_dict=True, return_tensors="pt", ).to(model.device) outputs = model.generate(**inputs, max_new_tokens=256) print(tokenizer.decode(outputs[0][inputs["input_ids"].shape[-1]:])) - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- vLLM
How to use vkusterl/extrator-cardapios-0.5b with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "vkusterl/extrator-cardapios-0.5b" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "vkusterl/extrator-cardapios-0.5b", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker
docker model run hf.co/vkusterl/extrator-cardapios-0.5b
- SGLang
How to use vkusterl/extrator-cardapios-0.5b with SGLang:
Install from pip and serve model
# Install SGLang from pip: pip install sglang # Start the SGLang server: python3 -m sglang.launch_server \ --model-path "vkusterl/extrator-cardapios-0.5b" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "vkusterl/extrator-cardapios-0.5b", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker images
docker run --gpus all \ --shm-size 32g \ -p 30000:30000 \ -v ~/.cache/huggingface:/root/.cache/huggingface \ --env "HF_TOKEN=<secret>" \ --ipc=host \ lmsysorg/sglang:latest \ python3 -m sglang.launch_server \ --model-path "vkusterl/extrator-cardapios-0.5b" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "vkusterl/extrator-cardapios-0.5b", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }' - Docker Model Runner
How to use vkusterl/extrator-cardapios-0.5b with Docker Model Runner:
docker model run hf.co/vkusterl/extrator-cardapios-0.5b
Extrator de cardรกpios 0.5B
Modelo de 0,5 bilhรฃo de parรขmetros que converte cardรกpios de restaurante escritos em texto livre (mensagens de WhatsApp, texto copiado de PDF, posts e saรญda de OCR) em um catรกlogo estruturado em JSON Lines, com nome, descriรงรฃo, preรงo, porรงรฃo, categoria, restriรงรตes alimentares, tamanhos e adicionais de cada item. ร um ajuste fino com LoRA do Qwen2.5 0.5B Instruct, treinado em uma GTX 1070 sobre o conjunto cardรกpios sintรฉticos em portuguรชs.
A ideia รฉ medir atรฉ onde chega, numa tarefa de extraรงรฃo bem delimitada, um modelo pequeno que roda em CPU e custa uma fraรงรฃo de uma chamada a um modelo grande, quando os dados e a avaliaรงรฃo sรฃo construรญdos com cuidado. Uma demonstraรงรฃo em Gradio para rodar localmente estรก em codigo/demo_gradio.py no conjunto de dados.
English summary. A 0.5B model fine tuned with LoRA from Qwen2.5 0.5B Instruct to turn free text Brazilian Portuguese restaurant menus into a structured JSON Lines catalog. On a hand written out of distribution test set that was never used for any decision, it reaches an item level F1 of 0.645, against 0.450 for a rule based parser and 0.060 for the same base model prompted without fine tuning.
Uso
from transformers import AutoModelForCausalLM, AutoTokenizer
modelo_id = "vkusterl/extrator-cardapios-0.5b"
tok = AutoTokenizer.from_pretrained(modelo_id)
modelo = AutoModelForCausalLM.from_pretrained(modelo_id)
cardapio = """Boa noite! Segue o cardรกpio de hoje ๐
*Marmita P* arroz, feijรฃo, frango grelhado e salada R$ 18
*Marmita G* arroz, feijรฃo, frango grelhado e salada R$ 24
Adicional de ovo +R$ 2
Refri lata R$ 6"""
mensagens = [
{"role": "system", "content": "Extraia o cardรกpio em JSON Lines, com o restaurante na primeira linha quando houver e um item por linha."},
{"role": "user", "content": cardapio},
]
entrada = tok.apply_chat_template(mensagens, add_generation_prompt=True, return_tensors="pt", return_dict=True)
saida = modelo.generate(**entrada, max_new_tokens=1024, do_sample=False)
print(tok.decode(saida[0, entrada["input_ids"].shape[1]:], skip_special_tokens=True))
A saรญda deste modelo para o exemplo acima, gerada em CPU, foi a seguinte. O adicional fica no item logo acima dele, que รฉ a convenรงรฃo dos dados de treino.
{"nome": "Marmita P", "descricao": "Arroz, feijรฃo, frango grelhado e salada", "preco": 18.0, "categoria": "Marmitas"}
{"nome": "Marmita G", "descricao": "Arroz, feijรฃo, frango grelhado e salada", "preco": 24.0, "categoria": "Marmitas", "adicionais": [{"nome": "Ovo", "preco": 2.0}]}
{"nome": "Refri Lata", "preco": 6.0, "categoria": "Bebidas"}
Use sempre a mesma instruรงรฃo de sistema do exemplo, que รฉ a do treino. A saรญda tem uma linha por item e pode ser validada com o esquema em codigo/esquema.py do conjunto de dados. Linhas invรกlidas sรฃo raras, mas convรฉm descartรก-las em vez de rejeitar o cardรกpio inteiro, como faz a funรงรฃo de_jsonl.
Resultados
A mรฉtrica principal รฉ o F1 de item correto, em que um item sรณ conta quando o nome foi pareado com o gabarito e o preรงo (ou a grade de tamanhos) e a categoria estรฃo certos. Sรฃo trรชs conjuntos de avaliaรงรฃo. O teste sintรฉtico vem do mesmo gerador do treino. Os dois conjuntos fora da distribuiรงรฃo foram escritos ร parte, em formatos que o gerador original nรฃo produzia. O de desenvolvimento orientou a segunda versรฃo dos dados, e o de teste foi escrito depois dela e nunca foi usado para decidir nada, entรฃo รฉ a medida mais honesta de generalizaรงรฃo.
| Modelo | Parรขmetros | Teste sintรฉtico (100) | Desenvolvimento fora da distribuiรงรฃo (24) | Teste fora da distribuiรงรฃo (24) |
|---|---|---|---|---|
| Extrator v2 (este modelo) | 0,5 B | 0,972 | 0,659 | 0,645 |
| Extrator v1 (primeira rodada) | 0,5 B | 0,821 | 0,580 | 0,582 |
| Qwen2.5 1.5B Instruct sem ajuste fino | 1,5 B | n/d | 0,051 | 0,120 |
| Qwen2.5 0.5B Instruct sem ajuste fino | 0,5 B | 0,064 | 0,090 | 0,060 |
| Analisador por regras | nรฃo se aplica | 0,496 | 0,359 | 0,450 |
Na comparaรงรฃo, o teste sintรฉtico usa as 100 primeiras amostras, as mesmas para todos os modelos. No teste sintรฉtico completo, com 500 cardรกpios, este modelo obtรฉm 0,967. Os modelos sem ajuste fino tendem a responder com uma lista JSON dentro de um bloco de cรณdigo, com campos trocados e categorias fora da lista, e mesmo com leitura tolerante ficam longe do modelo ajustado. O Qwen 1.5B sem ajuste fino nรฃo foi rodado no teste sintรฉtico, porque nos dois conjuntos fora da distribuiรงรฃo ele jรก fica muito abaixo do modelo ajustado. Em CPU, limitada a 2 threads, o extrator leva em mรฉdia 38,2 s por cardรกpio, gerando cerca de 8 tokens por segundo.
Acerto por campo deste modelo, calculado sobre os itens pareados.
| Mรฉtrica | Teste sintรฉtico (500) | Desenvolvimento (24) | Teste fora da distribuiรงรฃo (24) |
|---|---|---|---|
| Itens encontrados (pareados) | 0,989 | 0,890 | 0,910 |
| Nome idรชntico ou quase | 0,994 | 0,967 | 0,970 |
| Preรงo ou grade de tamanhos | 0,990 | 0,934 | 0,941 |
| Categoria | 0,985 | 0,762 | 0,743 |
| Porรงรฃo | 0,988 | 0,910 | 0,861 |
| Restriรงรตes | 0,996 | 0,959 | 0,980 |
| Adicionais | 0,998 | 1,000 | 1,000 |
| Descriรงรฃo (F1 de tokens) | 0,975 | 0,776 | 0,613 |
| Restaurante | 0,994 | 0,667 | 0,750 |
| Item correto, precisรฃo | 0,969 | 0,655 | 0,660 |
| Item correto, revocaรงรฃo | 0,964 | 0,664 | 0,631 |
| Item correto, F1 | 0,967 | 0,659 | 0,645 |
| JSON vรกlido | 0,996 | 0,958 | 0,917 |
| Cardรกpio inteiro perfeito | 0,732 | 0,125 | 0,042 |
F1 de item correto por estilo de escrita no teste sintรฉtico.
| Estilo | Cardรกpios | Modelo | Regras |
|---|---|---|---|
| corrido | 40 | 0,934 | 0,000 |
| informal | 31 | 0,929 | 0,214 |
| 31 | 0,961 | 0,203 | |
| lista | 86 | 0,964 | 0,378 |
| ocr | 46 | 0,950 | 0,361 |
| 113 | 0,982 | 0,484 | |
| tabela | 49 | 0,966 | 0,709 |
| 104 | 0,980 | 0,689 |
Como o modelo chegou aqui
A primeira versรฃo foi treinada com um gerador que cobria sete estilos de escrita. Ela acertava praticamente tudo no teste sintรฉtico, mas ficava em 0,580 no conjunto escrito ร parte. A anรกlise dos erros mostrou trรชs padrรตes. Sabores listados sem o nome do prato, como pizzas sob uma tabela de sabores, recebiam categorias erradas. Linhas com preรงo compartilhado ("Pastรฉis (R$ 9,00 cada): carne, queijo...") nรฃo eram expandidas em um item por sabor. Tamanhos declarados sรณ no cabeรงalho confundiam a associaรงรฃo entre preรงo e tamanho. Nomes fora do vocabulรกrio tambรฉm saรญam com erros de grafia.
A segunda versรฃo do gerador passou a produzir esses formatos, ganhou um estilo informal, mais nomes compostos e pratos internacionais, e o modelo foi treinado de novo do zero. Para nรฃo medir a melhora com o mesmo material que a orientou, um segundo conjunto fora da distribuiรงรฃo foi escrito antes de qualquer resultado da nova versรฃo. Nele, a primeira versรฃo obtรฉm 0,582 e esta obtรฉm 0,645.
A melhora foi real, mas parcial. No teste final, o modelo encontrou 101 dos 111 itens e acertou o nome de quase todos, mas 26 deles saรญram com a categoria errada, o que faz da categoria o principal gargalo. Pratos fora do vocabulรกrio do gerador, como abarรก, quesadilla e bolinho de estudante, tendem a cair em Porรงรตes ou Acompanhamentos, e itens de cafรฉ da manhรฃ como pรฃo de queijo e cuscuz saem como Lanches. Parte desses casos admite mais de uma resposta razoรกvel (mandioca frita pode ser porรงรฃo ou acompanhamento), mas a maioria รฉ erro de fato.
Os formatos que motivaram a segunda versรฃo ainda falham em parte. Em linhas de preรงo compartilhado, o modelo ร s vezes registra sรณ o sabor ("Carne" em vez de "Pastel de Carne"), e grades de tamanho declaradas sรณ no cabeรงalho continuam sendo perdidas em alguns cardรกpios. Tambรฉm aparecem erros em formatos que o gerador nรฃo produz, como o preรงo promocional ("de R$ 59,90 por R$ 44,90"), a venda por unidade e por cento e o prefixo omitido ("Sanduรญche natural de frango 14 / de atum 15"). O prรณximo passo รฉ ampliar o vocabulรกrio com pratos regionais e de cafรฉ da manhรฃ e levar esses formatos ao gerador.
Treino
| Configuraรงรฃo | Valor |
|---|---|
| Modelo base | Qwen/Qwen2.5-0.5B-Instruct |
| Mรฉtodo | LoRA (r 16, alfa 32, dropout 0,05) em todas as projeรงรตes lineares, depois incorporado ao modelo |
| Dados | 4.000 cardรกpios sintรฉticos, 1 รฉpoca, perda calculada sรณ na resposta |
| Otimizaรงรฃo | AdamW, taxa de aprendizado 2e-4 com decaimento cosseno, lote efetivo de 8 |
| Comprimento mรกximo | 2.048 tokens |
| Hardware | NVIDIA GTX 1070 (8 GB), fp32 |
| Tempo | 106 minutos |
| Perda final | treino 0,0276, validaรงรฃo 0,0108 |
A instruรงรฃo de sistema usada no treino รฉ curta (40 tokens), porque o formato รฉ aprendido a partir dos dados. Os modelos sem ajuste fino da comparaรงรฃo recebem uma instruรงรฃo longa, com o esquema e a lista de categorias, que รฉ a melhor condiรงรฃo para eles, e suas respostas sรฃo lidas de forma tolerante.
Limitaรงรตes
O modelo foi treinado sรณ com dados sintรฉticos, e a diferenรงa entre o teste sintรฉtico e os conjuntos fora da distribuiรงรฃo mostra quanto o desempenho cai diante de formatos novos. Cardรกpios reais com combinaรงรตes, observaรงรตes de preparo ou layouts muito irregulares podem gerar itens faltando, nomes alterados ou preรงos associados ao item errado, entรฃo a saรญda deve passar por revisรฃo humana antes de virar catรกlogo. Em listas muito curtas, sem descriรงรตes, o modelo ร s vezes inventa descriรงรตes e porรงรตes que nรฃo estรฃo no texto, provavelmente porque cerca de dois terรงos dos itens dos dados sintรฉticos trazem descriรงรฃo. A demonstraรงรฃo descarta esses campos quando suas palavras e seus nรบmeros nรฃo aparecem no cardรกpio (funรงรฃo filtra em codigo/demo_gradio.py), e o mesmo cuidado vale para qualquer uso real. As categorias seguem uma taxonomia fixa de 14 classes. O modelo nรฃo lรช imagens, entรฃo cardรกpios em foto precisam de OCR antes. Restriรงรตes alimentares sรณ sรฃo registradas quando o cardรกpio as declara, e o modelo nรฃo deve ser usado para inferir alergรชnicos.
Licenรงa e autoria
Apache 2.0, a mesma do modelo base. Treinado e avaliado por Vinicius Kuster Lodi, Universidade Federal de Viรงosa. O cรณdigo de geraรงรฃo, treino e avaliaรงรฃo estรก na pasta codigo/ do conjunto de dados.
- Downloads last month
- 15