23 pontos por GN⁺ 2025-09-16 | 7 comentários | Compartilhar no WhatsApp
  • RustGPT é um modelo de linguagem baseado em transformer implementado sem frameworks externos de machine learning, usando apenas Rust puro e ndarray
  • Foi projetado para aprender conhecimento factual e padrões conversacionais por meio de pré-treinamento (Pre-training) e instruction tuning
  • Sua estrutura segue a arquitetura típica de LLM: tokenizador → embeddings → blocos transformer → projeção de saída
  • Oferece estrutura de código modular e testes, permitindo entender em detalhe os processos de treinamento, inferência e otimização
  • É uma referência importante para desenvolvedores e estudantes do ecossistema Rust que queiram implementar um LLM do zero sem depender de frameworks

Visão geral do projeto

  • RustGPT é um projeto open source que implementa um LLM usando apenas a linguagem Rust e a biblioteca de álgebra linear (ndarray), sem frameworks externos de machine learning ou dependências complexas
  • O principal objetivo é implementar diretamente os componentes centrais dos LLMs modernos, como transformer, attention, embeddings e otimização, para compreender o processo de treinamento
  • Diferentemente de outros LLMs mais populares, ele projeta diretamente em Rust toda a estrutura transformer, além de backpropagation, tokenizador e otimizador, o que é uma grande vantagem para desenvolvedores e pesquisadores Rust que queiram entender e expandir os princípios do deep learning desde a base
  • Seu diferencial é usar ndarray para operações matriciais e não depender de pacotes externos de machine learning como PyTorch ou TensorFlow
  • Com modularização e cobertura de testes sólidas, é adequado para vários experimentos e melhorias, além de servir bem a fins educacionais de um LLM “feito do zero” (From Scratch)

Principais características e forma de implementação

  • Arquitetura transformer: texto de entrada → tokenização → embeddings → blocos transformer → previsão final
    • O texto de entrada passa pelo processo de tokenização e é convertido em vetores de embedding
    • Os embeddings passam por Transformer Block (multi-head attention + feed-forward network)
    • Por fim, a Output Projection Layer gera a distribuição de probabilidade do vocabulário para realizar a predição

Estrutura da implementação

  • main.rs: pipeline de treinamento, preparação de dados e execução do modo interativo
  • llm.rs: lógica geral de forward pass, backpropagation e treinamento do LLM
  • transformer.rs, self_attention.rs, feed_forward.rs: blocos centrais do transformer
  • embeddings.rs, output_projection.rs: embeddings e camada final de saída
  • adam.rs: implementação do otimizador Adam
  • Cada módulo inclui código de teste correspondente (tests/), permitindo validar as funcionalidades

Como treinar, testar e fluxo de dados

  • Processo de treinamento
    • Criação do vocabulário → pré-treinamento (100 epochs, dados de frases factuais) → instruction tuning (100 epochs, dados conversacionais)
    • Exemplo de pré-treinamento: "The sun rises in the east and sets in the west"
    • Exemplo de instruction tuning: "User: How do mountains form? Assistant: ..."
  • Suporte a modo interativo
    • Após o fim do treinamento, é possível testar conversas com base em prompt e resposta
    • Exemplo: "How do mountains form?" → "Mountains are formed through tectonic forces or volcanism..."

Detalhes técnicos da composição

  • Tamanho do vocabulário: definido dinamicamente com base nos dados de treino
  • Dimensão do embedding: 128, camada oculta: 256
  • Comprimento máximo da sequência: 80 tokens
  • Arquitetura: 3 blocos transformer + embeddings + camada de saída
  • Algoritmo de treinamento: otimizador Adam, gradient clipping (limite de norma L2 de 5.0)
  • Taxa de aprendizado: pre-training 0.0005, instruction tuning 0.0001
  • Função de perda: cross-entropy loss

Características do modelo e do código

  • Tokenizador customizado (tratamento de pontuação)
  • Geração de texto baseada em greedy decoding
  • Estrutura de camadas modular e interfaces claras
  • Cobertura de testes: testes unitários para cada camada e funcionalidade
  • Dependências: usa apenas ndarray (operações matriciais) e rand/rand_distr (inicialização aleatória), sem ML externo como PyTorch/TensorFlow
  • Valor educacional: ideal para aprender a estrutura interna e os princípios de treinamento de LLMs modernos

Possibilidades de evolução

  • Introdução de arquiteturas avançadas: multi-head attention, RoPE, positional encoding etc.
  • Otimização de desempenho: SIMD, treinamento paralelo e melhoria de eficiência de memória
  • Suporte para salvar/carregar modelos
  • Adição de amostragem aprimorada (beam search, Top-k/Top-p) e métricas de avaliação

Significado

  • É um projeto para aprendizado e experimentação que mostra que é possível implementar diretamente um LLM em Rust sem depender de frameworks como PyTorch e TensorFlow, baseados em Python
  • É uma referência útil para desenvolvedores que querem entender o funcionamento interno de LLMs e criar sistemas de ML em ambiente Rust

7 comentários

 
t7vonn 2025-09-18

Bem limpo.

 
ahwjdekf 2025-09-16

Mas por quê? Tipo, "eu também consigo fazer isso", é isso?

 
cosine20 2025-09-22

A imponência de um karma de -47 kkk

 
skrrgang 2025-09-16

Só de ver o r de rust já dá uma coceira e uma raiva, né? kkkkkkkkkkkkkk

 
aer0700 2025-09-16

Deve haver algo para aprender ao criar isso.

 
devjeonghwan 2025-09-16

Não dá para criar sem tentar fazer.

 
GN⁺ 2025-09-16
Comentários do Hacker News
  • Vi código com comentários gerados pelo GPT automaticamente e constantes já definidas sendo duplicadas, então acho que essas partes precisam ser removidas. Por exemplo, constantes como const MAX_SEQ_LEN: usize = 80 já estão em lib.rs, então me parece melhor usar essas constantes diretamente, como indicado no comentário

    • Acho que deixar esse tipo de coisa no código mostra que não foi um resultado realmente construído com entendimento pelo desenvolvedor
    • Fico curioso se foi enviado algum PR relacionado a isso
    • Sobre a forma de usar constantes, também acho possível que o autor simplesmente não soubesse como fazer. Eu também lembro que, na minha primeira semana com Rust, pensei bastante sobre nomenclatura e estrutura de código
    • Queria saber o que vocês acham da ideia de que um estilo de Rust baseado em vibe coding pode acabar reduzindo a qualidade geral do código na linguagem
    • Acho que essa crítica faz todo sentido
  • Já perdi dias no inferno das dependências de Python, então a ideia de resolver tudo com um único cargo run em Rust parece um sonho. Mas queria saber qual foi a parte mais dolorosa sem framework. Se eu tivesse que apostar, diria que foi depurar a lógica de backpropagation

    • Recomendo uma ferramenta chamada uv. Pela minha experiência, ela deixou rodar projetos Python 90% mais fácil ir para uv
    • Acho que a parte mais difícil é o uso de recursos como GPU
    • Essa descrição dos problemas de dependência em Python faria sentido lá por 2010, mas em 2025 me parece um exagero enorme
    • Dizem que cargo run é um sonho, mas eu pessoalmente prefiro a experiência do cargo build recompilando a internet inteira e aquecendo a CPU no inverno
    • Sinto que quem elogia o cargo muitas vezes não entende bem os trade-offs de gerenciamento de dependências. Recompilar todas as bibliotecas toda vez, como em C, é ineficiente, mas sistemas como npm ou cargo, que facilitam demais puxar dependências, acabam trazendo desvantagens sérias como proliferação de dependências, tempo de build e problemas de segurança. Um bom sistema de build não é necessariamente a mesma coisa que tornar fácil adicionar dependências, e esse modelo de repositório centralizado em que qualquer um pode emaranhar dependências também não me parece um padrão saudável
  • Estou tocando um projeto parecido em Rust. Há uma versão que roda no navegador via WebAssembly, e também deixei públicos a demo no navegador e o código-fonte

  • A combinação dos pacotes ndarray, rand e rand_distr parece bem limpa

    • Por curiosidade, dei uma olhada na árvore de dependências com cargo tree, e por enquanto ela parece enxuta
    • Acho que essa árvore, por si só, não significa muita coisa. O código pode ter sido implementado de forma ineficiente, e em alguns casos usar bibliotecas externas de forma adequada pode até ser melhor
    • Fico em dúvida se essa avaliação é ironia ou se falta mais contexto
  • Acho que a segurança de memória do Rust é bem útil para reduzir buffer overflows ao implementar transformadores. Os kernels CUDA ainda levam vantagem em desempenho. Também fiquei curioso se o tokenizer recria o BPE do zero ou usa alguma biblioteca existente

  • Eu também fiz o picogpt em Rust e me apoiei bastante no blog GPT from scratch do jaykmody. Link do projeto

  • Parabéns, e junto disso queria fazer uma observação pequena: em um LLM, é melhor não reutilizar o transformer block e sim ter instâncias separadas para cada um. Eu mesmo já fiz exercícios parecidos para construir a base com Zig e MLX, e depois fui adicionando recursos aos poucos até migrar para PyTorch/Transformers

    • Ainda assim, acho que esse tipo de exercício só tem valor quando você escreve o código por conta própria. A experiência tem valor justamente em fazer sem ajuda do GPT
  • O comentário do autor do projeto está resumido no Reddit

  • Gosto de como o projeto inteiro tem uma estrutura realmente fácil de ler

    • Quero mencionar que parece código gerado por IA
    • O estilo é fortemente procedural/orientado a objetos, então é difícil chamar isso de bom estilo Rust no sentido mais estrito. O estilo funcional com iterators e enums costuma ser visto como mais conciso e ideal. Mas, como experimento de ideias, está perfeitamente ok
    • Eu não sabia que Rust podia ficar tão legível assim. Chego até a ter a impressão de que os engenheiros de Rust evitam esse tipo de código simples e fazem uma espécie de competição de autoflagelação. Isso explica tudo o que vivi com a comunidade Rust, com contratações e afins
  • Fiquei curioso sobre a origem do dataset. Vou procurar, mas quis deixar a pergunta. Eu desenvolvi uma arquitetura focada em CPU e sem backpropagation, e ela funciona bem em datasets de classificação. Como permite atualizações incrementais por exemplo único, talvez sirva também para aprendizado contínuo. Só treinei com tiny.txt em uma demo de brinquedo e nunca tentei um modelo de linguagem grande (LLM). Minha arquitetura parece ter potencial para funcionar muito bem como assistente on-device ou on-premise, então pretendo continuar experimentando. Queria saber se alguém tem recomendação de dataset open source para treinar LLM

    • O Hermes-3 Dataset é bom
    • No Hugging Face há várias cadeias usuário-assistente abertas da OpenAI e da Anthropic, mas o ponto de atenção é que elas têm muita alucinação. Para instruction fine-tuning, são bem úteis. Se o objetivo for seguir instruções, recomendo a destilação do Kimi K2
    • Neste projeto, os dados de treino estão embutidos diretamente no arquivo main.rs. O conteúdo é algo como 50 frases curtas de conhecimento geral, provavelmente para reduzir o tempo de treino. Por isso, o desempenho piora drasticamente fora de padrões baseados em script. Exemplos de prompt e resultado:
      • ao inserir "hello": "Eclipses occur when one celestial body moves into the shadow of another" e outras saídas corretas
      • ao inserir "what are facts": repetição de listas de palavras sem sentido
      • ao inserir "how are mountains formed?": aparecem palavras inconsistentes e saídas sem sentido