Depois de 1 ano de fine-tuning: uma IA local para gerar mensagens de commit
Ha mais de um ano estou fazendo fine-tuning para resolver um problema especifico:
ter modelos pequenos rodando localmente que escrevem mensagens de commit a partir do git diff, sem enviar codigo para terceiros.
Motivacao? Privacidade e seguranca. Em muitos projetos, nao da para mandar o repositorio para uma API externa so para ganhar produtividade.

Os dois maiores desafios
1) Dataset bom (e de verdade)
Nao existe um dataset "limpo" de diff → commit message.
Tive que coletar exemplos reais, normalizar diffs, remover ruido, padronizar prompts e balancear casos (refactors, doc, config, testes, etc).
So isso ja comeu uma boa fatia do tempo, e e um trabalho continuo.
2) Modelos pequenos x diffs grandes
Mesmo com tuning, contexto limita.
Para contornar, criei um script de orquestracao que:
- quebra o
diffem partes, - gera resumos por arquivo,
- e depois sintetiza a mensagem final.
Isso virou um pipeline em duas etapas:
sp_change[_variant]→ sumariza cada arquivosp_commit[_variant]→ gera a mensagem final
O que ja tem funcionando

- Roda 100% local com Ollama
- Variantes de tamanho: mini (4B), default (8B), pro (14B)
- Para o dia a dia, mini tem sido um bom meio termo (velocidade x contexto)
- Para diffs enormes, uso default/pro
Modelos no Ollama:
👉 https://ollama.com/tavernari/git-commit-message
Datasets e pesos abertos (para tweaks):
👉 https://huggingface.co/Tavernari
Script publico (para melhorar/avaliar juntos):
👉 https://gist.github.com/Tavernari/b88680e71c281cfcdd38f46bdb164fee
Como testar (1 linha)
Instala o script globalmente com comando explicado no https://ollama.com/tavernari/git-commit-message
Entao rode num projeto git:
git gen-commit
Espero que gostem e gostaria de ter feedbacks do uso, e saber se os modelos conseguiram responder em ambiente real de desenvolvimento.
No passado publiquei um post sobre o inicio destes testes.
Editado:
No Macbook Pro M1 Pro com 32Gb de RAM.
Valores por iteração. Ou 1 change, ou 1 commit message.
Modelo Pro (14B):
total duration: 17.943454666s
load duration: 55.428041ms
prompt eval count: 1184 token(s)
prompt eval duration: 11.313669458s
prompt eval rate: 104.65 tokens/s
eval count: 84 token(s)
eval duration: 6.573659417s
eval rate: 12.78 tokens/s
Modelo Default (8B):
total duration: 10.027014125s
load duration: 67.751667ms
prompt eval count: 1182 token(s)
prompt eval duration: 6.131400333s
prompt eval rate: 192.78 tokens/s
eval count: 81 token(s)
eval duration: 3.827028375s
eval rate: 21.17 tokens/s
Modelo Mini (4B):
total duration: 16.234274s
load duration: 58.083208ms
prompt eval count: 1182 token(s)
prompt eval duration: 11.476908625s
prompt eval rate: 102.99 tokens/s
eval count: 115 token(s)
eval duration: 4.698046458s
eval rate: 24.48 tokens/s
Alto valores por causa do contexto maior, tenho que ajustar isso.
Usei Qwen3 (1.7B, 4B, 8B, 14B) com https://unsloth.ai
1.7B (nano - removido temporariamente)
Não performou bem apesar da velocidade incrível, então vou ver se é problema no fine-tuning ou problema mesmo da deficiência em modelos pequenos.
4B (mini)
Este performou bem, mas o contexto é de 256 o que o deixa lento, e preciso estudar mais como contornar esse contexto gigantesco.
8B (default)
Rápido e aceitável..
14B (pro)
Lento como o 4B, porém acerta mais do que a média nos meus testes internos.