NVIDIA lançou Dory 1.0 4B, um pequeno modelo de raciocínio dos Nemotron Labs cujas camadas centrais formam um bloco partilhado, aplicável uma, duas, três ou quatro vezes a cada token. Segundo um tutorial do MarkTechPost, este funcionamento permite executar um mesmo ficheiro em quatro níveis de cálculo diferentes, sem retreino.
Cada passagem adicional no bloco, chamada de loop, consome mais cálculo por token sem adicionar qualquer parâmetro. O tutorial utiliza o motor llama.cpp e um ficheiro no formato GGUF de 3,7 GB, em quantização Q5_K_M, ou seja, comprimido para reduzir o seu tamanho em memória. A versão do llama.cpp utilizada corresponde ao commit fixado na ficha do modelo da NVIDIA, o suporte a Dory sendo ainda uma pull request em rascunho. O nome do ficheiro difere do indicado na ficha, que menciona dory-q5_k_m.gguf, e o tutorial recomenda, portanto, verificar o seu tamanho e a sua impressão digital SHA-256. O ficheiro descarregado corresponde à soma de controlo publicada pela NVIDIA.
Uma arquitetura lida diretamente no ficheiro
O cabeçalho do GGUF descreve a estrutura do modelo antes mesmo do seu carregamento. O Dory tem 72 entradas de camadas, distribuídas por 16 camadas de entrada, 40 camadas recorrentes e 16 camadas de saída. O bloco recorrente representa 1,84 mil milhões dos 3,98 mil milhões de parâmetros do modelo.
O cabeçalho indica também um número de loops por defeito de 4, enquanto a ficha do modelo recomenda 2. Um servidor iniciado sem opção explícita funciona, portanto, com o ajuste mais dispendioso. Segundo o tutorial, é necessário definir sempre este parâmetro manualmente.
A partir destes dados, o tutorial estima o custo de cada loop. Um token atravessa o bloco recorrente uma vez por loop, de modo que quatro loops aplicam 2,51 vezes os parâmetros de um único loop e lêem 2,28 vezes os bytes dos pesos, sendo esta leitura o fator determinante para uma descodificação limitada pela memória. A cache KV, a memória que conserva os cálculos dos tokens anteriores, varia conforme o modo escolhido. No modo per_loop, passa de 306 MiB com um loop para 816 MiB com quatro loops, para um contexto de 4096 tokens. No modo last_loop, mantém-se em 306 MiB independentemente do número de loops.
Medições para verificar as previsões
O notebook associado verifica depois estas estimativas num servidor em funcionamento. Mede a velocidade de descodagem para cada número de loops, testa se a cache last_loop modifica as previsões do modelo e compara as distribuições dos tokens seguintes entre vários ajustes. Lança também uma avaliação emparelhada em 30 questões do conjunto de teste GSM8K, um benchmark de problemas matemáticos, medindo a precisão, o comprimento das respostas e o tempo por questão resolvida.
O tutorial especifica que a ficha do modelo anuncia desempenhos noutros benchmarks, como SWE-bench ou GPQA, que não são reproduzidos neste contexto, assim como o contexto de 256K tokens e o pré-treino em NVFP4.
O notebook está acessível no GitHub, no repositório do MarkTechPost dedicado a projetos de agentes e tutoriais. Os autores insistem em dois pontos: definir explicitamente o número de loops, uma vez que o GGUF utiliza quatro por defeito, e fixar o commit do fork do llama.cpp, porque o suporte a Dory continua a ser uma pull request em rascunho.
