Executando verificação de segurança...
20

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.

screenshot


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 diff em partes,
  • gera resumos por arquivo,
  • e depois sintetiza a mensagem final.

Isso virou um pipeline em duas etapas:

  1. sp_change[_variant] → sumariza cada arquivo
  2. sp_commit[_variant] → gera a mensagem final

O que ja tem funcionando

example

  • 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.

Carregando publicação patrocinada...
3

Muito legal, mas.... (lá vem a crítica construtiva)


Vc tem mais exemplos de mensagens geradas com código de projetos reais? Pergunto porque vendo somente o gif de exemplo, fiquei com algumas dúvidas.

A impressão que passa é que a IA é muito boa para detectar o que foi alterado, mas não porque aquilo foi feito.

Por exemplo, "reduzir padding de X para Y no arquivo tal". É bem legal que a IA tenha detectado isso e produzido uma mensagem de acordo, mas - na minha opinião - o mais importante é saber porque foi preciso alterar tal valor. Foi para corrigir um bug? Uma melhoria no layout? Mudou alguma guideline da empresa? etc etc etc...

Se eu adicionei um if (suspenso(usuario)) { faz algo }, ele provavelmente vai dizer que foi adicionada uma nova condição que faz algo se o usuário está suspenso, certo? Mas ele tem como saber que isso foi feito porque, sei lá, criaram uma norma/lei/regulamentação que diz para fazer isso com usuários suspensos? Pra mim, isso é o que deveria estar na mensagem de commit (a justificativa técnica ou de negócios que motivou a alteração). Até poderia ter a mensagem da IA dizendo o que foi feito, como complemento, embora eu ache redundante (um git diff me mostraria isso facilmente, mas enfim).

Pode-se argumentar que "Adjust UI element sizing and spacing for better visual balance" seria uma explicação do motivo, mas eu ainda acho que a motivação de fato está em uma etapa anterior. Por exemplo, um estudo da área de design, feito a pedido da área de negócios, depois de uma pesquisa entre os usuários que mostrou que isso poderia ser melhorado. Isso sim seria uma mensagem de commit muito mais útil e informativa, pois além de dizer porque aquilo foi feito, é algo que não daria para adivinhar só lendo o código.

Além disso, em muitos projetos costuma-se colocar alguma referência ao número do ticket/chamado/issue e uma breve descrição. Para mim, essa informação é muito mais útil do que saber que o arquivo tal foi alterado, pois - novamente - isso eu posso verificar facilmente com git diff. Já o porquê - a motivação técnica ou de negócio que levou à mudança - nem sempre dá para saber só olhando o código, e por isso eu acho muito mais importante ter isso na mensagem de commit.

E também fico receoso com afirmações do tipo "This change enhances user experience without altering functionality", pois é uma inferência que nem sempre é verdade, dependendo do que foi alterado. Só testando bastante pra saber se realmente é o caso.

Vi que no final tem a opção de editar a mensagem, então acho que eu sempre usaria isso para adicionar o porquê. E provavelmente removeria um pouco do que eu considero excesso, pois não sei se eu gostaria de ter uma descrição arquivo a arquivo em todos os commits - novamente, para isso existe o git diff, pois pra mim as mensagens de commit devem ser mais sucintas e diretas, e focar mais no porque foi feito. Uma sugestão seria poder configurar se eu quero mensagens longas ou sucintas, se vai listar todos os arquivos ou só um "resumão", etc.

Enfim, não disse isso para te desmotivar ou menosprezar seu projeto. Acho que pode ser útil sim, afinal ainda estamos aprendendo as melhores formas de usar IA e isso é uma tentativa válida. Só queria levantar essa discussão porque vejo que muita gente se preocupa cada vez menos com mensagens de commit claras, concisas e de fato úteis, ao ponto de querer delegar isso completamente sem sequer parar pra pensar.

3

Eu concordo 100% com você e não acredito que modelos llms serão capazes de ir tão a fundo só de olhar um diff, talvez, um editor tipo CoPilot baseado na conversa consiga tal commit.

Dito isso, está no roadmap o próximo fine-tuning considerar contexto, que é basicamente o usuário ter que escrever algo para guiar o commit message.

Não deixei claro dessa vez mas este projeto surge depois de ver muitos commits com este padrão "Changes", "PR Fix", "Oops", "Oops again"... a minha ideia é.. já que não vai escrever nada, então deixa a ferramenta resumir o seu diff para ajudar nos Reviews do PR por exemplo.

E agradeço a crítica e concordo com vc, bom se um dia chegar lá ao ponto de dar contexto para o commit e funcionar 100%, volto a postar aqui :D

Obrigado 🙏

2

Trabalho excepcional! Fiquei curioso pra saber em qual modelo você fez o fine tunning, he he he. Vejo muita gente usando LLMs gigantes pra essa tarefa, mas acredito que um modelo menor, porém específico, vai ter vantagem principalmente pelo preço baixíssimo.

3

Jurava que tinha escrito o nome e no final só coloquei os parametros..

Usei Qwen3 (1.7B, 4B, 8B, 14B) com https://unsloth.ai

Basicamente:

1.7B

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

Este performou bem, mas o contexto é de 256 o que o deixa lento, e preciso estudar mais como contornar esse contexto gigantesco.

8B

Rápido e aceitável..

14B

Lento como o 4B, porém acerta mais do que a média nos meus testes internos.

2

Meus 2 cents,

Que app legal - ja coloquei na lista para testar !

Vi que voce fez o fine-tunning (tem ate os datasets) - agora a pergunta de 1 milhao: qual o desempenho do modelo em CPU (sem GPU) (em tokens/seg) ?

E para fazer o fine-tunning, voce alugou uma VPS GPU ou fez localmente ?

Novamente, parabens pela iniciativa !

Saude e Sucesso !

3

agora a pergunta de 1 milhao: qual o desempenho do modelo em CPU (sem GPU) (em tokens/seg) ?

Não testei em outro OS.

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.

E para fazer o fine-tunning, voce alugou uma VPS GPU ou fez localmente ?

Tentei fazer localmente, mas minha maquina "só" tem 64Gb de ram (Macbook M2 Max), pra modelos pequeninos foi mas queria para algo maior.
Dito isso, aluguei o Cloud da Google com A100 para treinar estes modelos pelo "custo/beneficio"


Obrigado e espero poder contribuir pra galera evitar commits do tipo "Wip", "Changes", "Oops".. já vi estes e mais.. hahahaha

1
1

Muito obrigado, pelo trabalho, vou testar.
Uma ideia (talvêz você já tenha pensado nisso), para ter contexto da modificação, colocar pequenos comentarios emcima ou do lado do ajuste do código, já sirva para a IA ter contexto para dizer o motivo. Poderia ser assim:

//Motivo: Agora o fiscal pode modificar ...
if(status == 4 or status == 3){
...