- WASTE é um motor de inferência em C que converte o modelo completo de pesos abertos Kimi K3, com 2,78 trilhões de parâmetros, sem redução, em um contêiner de 982 GiB para executá-lo em notebooks de consumo
- Mantém na memória apenas o tronco residente do modelo e lê do NVMe cerca de 4% dos pesos de especialistas ativados a cada token; a RAM restante é usada como um cache de especialistas com tamanho limitado
- O Kimi K3 abre com no mínimo 29,05 GB de RAM em contexto de 4K, mas a configuração prática é um orçamento de 46 GB em um MacBook Pro de 64 GB, onde registra 0,45~0,62 tok/s
- Sobrepõe leitura de especialistas e computação para uma melhora de cerca de 1,6×, e executa o roteador da próxima camada um residual à frente para elevar a taxa de acerto do cache de 14% para 38%, sem alterar o total lido nem os logits
- Permite executar localmente um modelo gigantesco sem conexão à internet, custo por token nem envio de dados externos, mas exige NVMe interno e cerca de 1 TB de armazenamento; com orçamento de RAM de 52 GB ou mais, pode ficar drasticamente mais lento por causa de paginação do sistema operacional
Objetivo e forma de implementação do WASTE
- WASTE(Weight-Aware Streaming Tensor Engine) é um motor de inferência em C embutível, sem dependências externas em tempo de execução
- Usa apenas
libwaste.ae o executávelwaste, e não precisa de BLAS, CUDA, ONNX nem Python além de libc e pthreads - Python é usado apenas para conversão do modelo e validação contra a referência em PyTorch, e não entra no caminho de inferência
- A API pública é composta por 26 funções e oferece suporte a abrir modelo, definir limite de RAM, gerar, salvar sessão e encerrar
- Usa apenas
- O alvo atualmente validado é o modelo completo Kimi K3 2.78T
- A fonte pública original tem 1,42 TB, e o contêiner após a conversão tem 982 GiB
- Não é uma versão destilada, podada nem reduzida
- O Kimi-Linear 48B também registra, com o mesmo motor e formato, contêiner de 19 GiB, mínimo de 1,87 GB de RAM e 10,7 tok/s
- O nome do projeto vem do objetivo de reduzir situações em que modelos que poderiam rodar em hardware sobre a mesa são executados em datacenters de nuvem, consumindo custo por token e energia ao mesmo tempo
Estrutura de streaming a partir do disco
- Como o K3 usa uma estrutura Mixture of Experts, apenas cerca de 4% do modelo é ativado por token; por isso, os pesos inativos são organizados para serem acessados no momento necessário, sem precisar residir na RAM
- O contêiner
.wasteé composto por manifesto JSON, tronco residente e bancos de especialistas por camada- Cada registro de especialista é alinhado a 4 KiB
- As matrizes gate, up e down são colocadas de forma contígua para ler um especialista inteiro exatamente com um único
pread - O page cache é contornado com
F_NOCACHEno macOS,O_DIRECTno Linux eFILE_FLAG_NO_BUFFERINGno Windows
- Sem contornar o page cache, contêineres de teste menores que a RAM podem entrar no cache do sistema operacional e produzir taxas de acerto que não se reproduzem no modelo de 982 GiB
- Ao ler registros, magic, ID do especialista e intervalo de offsets são sempre verificados para evitar que bancos truncados ou combinados incorretamente respondam com pesos errados
- A verificação
crc32do payload é ativada com--verify - O custo de verificação é de cerca de 5% no Kimi-Linear e cerca de 1% no K3; por padrão fica desligada
- Recomenda-se verificar uma vez contêineres copiados, baixados ou colocados em discos não confiáveis
- O tronco e os codebooks não têm checksum
- A verificação
Leitura antecipada e previsão do roteador
- Quando o roteador de uma camada decide 16 IDs de especialistas, cada leitura é solicitada em uma thread separada, e a computação consome os dados à medida que chegam
- A sobreposição de leitura e computação melhora cerca de 1,6× no K3
- O trabalho executado e as estatísticas de cache são iguais antes e depois de ativar o recurso
- Antes que o hidden state real da próxima camada seja produzido, o próximo roteador residente é executado com o hidden state atual para buscar antecipadamente 6 especialistas
- A previsão um residual à frente tem 92% de acurácia em rank 1 e 81% entre os 6 principais
- A saída é mantida exatamente correta porque o roteador real decide os especialistas finais
- A demand hit rate sobe de 14% para 38%, e o total de bytes lidos não muda
- Pode ser desativado com
WASTE_LOOKAHEAD=0
- A implementação que aplicava a mesma técnica ao prefill foi removida
- A camada de decode ocupa 16 slots de cache, mas a camada de chunk ocupa cerca de 550
- Os registros lidos antecipadamente eram despejados antes do uso, aumentando as leituras em 6,9% sem reduzir o tempo
Quantização e precisão
- Os pesos de especialistas são armazenados com quantização vetorial residual em 3 estágios, com codebook de 256 itens para vetores de 8 dimensões, usando 3,00 bits por peso
- Sem restaurar a matriz inteira, cria uma tabela de produtos internos parciais e processa cada linha com 3 consultas à tabela e 2 somas
- O tronco mantém 4 bits e 8 bits
- Como o modelo foi treinado com consciência de quantização apenas para especialistas, a saída colapsa com tronco de 3 bits
- A previsão de cache acertava, mas o throughput também não melhorava, então foi removida
- Todas as camadas são comparadas com a implementação de referência em PyTorch
- A diferença final de logits é
3.6e-06 - A torre de visão fica em
2.3e-06contra sua própria referência - A conversão do cache latent KV mantém logits idênticos no nível de
1.2e-05
- A diferença final de logits é
Orçamento de RAM e faixa estreita de desempenho
- O K3 usa 16 especialistas em cada uma de 92 camadas, criando um conjunto de trabalho de 17,0 GB por token
- Se o cache for menor que esse tamanho, especialistas armazenados em um token são despejados antes do próximo token, e a taxa de acerto vira 0%
- Resultados medidos em um sistema de 64 GB mostram que alocar mais RAM nem sempre acelera
- Orçamento de 32 GB · cache de 3,32 GB: taxa de acerto 0%, 0,50 tok/s
- Orçamento de 46 GB · cache de 17,32 GB: taxa de acerto anterior 17%, 0,53~0,55 tok/s
- Orçamento de 52 GB · cache de 23,32 GB: 0,04~0,15 tok/s, não reproduzível
- Orçamento de 58 GB · cache de 29,32 GB: 0,02~0,03 tok/s
- O lookahead do roteador eleva a taxa de acerto em 46 GB de cerca de 14% para 38%, mas o colapso com 52 GB ou mais não é por cache miss, e sim por paginação do sistema operacional
- Em 58 GB, mesmo com taxa de acerto maior, fica cerca de 20 vezes mais lento que em 46 GB
- Depois de colocar o sistema em estado de paginação com um orçamento grande, até medições em 46 GB podem cair para 0,02 tok/s
- O orçamento padrão é escolhido abaixo de 7/8 da RAM física, reduzido em unidades do conjunto de trabalho por token
- Em um MacBook Pro de 64 GB, usa 46,24 GB e aloca 17,56 GB ao cache de especialistas
- Se o orçamento especificado for menor que o mínimo, ele recusa iniciar em vez de prosseguir com swapping
- Em sistemas de 128 GB, é possível usar o orçamento total recomendado, equivalente ao tronco mais 3 vezes o conjunto de trabalho
Desempenho do K3 e requisitos de hardware
- O sistema de medição é um MacBook Pro M5 Pro de 64 GB com SSD interno
- RAM mínima para contexto de 4K: 29,05 GB
- 32K: 30,54 GB, 128K: 35,63 GB, 1M: 83,21 GB
- Tronco residente: 27,28 GB
- Carregamento do modelo: 20 segundos
- Decode: 0,45~0,62 tok/s no orçamento padrão
- Prefill: chunked 0,47 tok/s, sequencial 0,29 tok/s
- Embora o modelo possa ser aberto com o mínimo de 29,05 GB, sistemas de 32 GB podem paginar severamente, então 64 GB é a especificação realmente recomendada
- Em estado cold, lê 17,0 GB de especialistas por token; com taxa de acerto de 38% do lookahead, lê 10,5 GB
- O SSD interno foi medido em 12,78 GB/s, e um gabinete USB externo em 0,94 GB/s
- Como um token lê 17 GB de especialistas, o mesmo processamento leva cerca de 13 segundos em armazenamento externo
- O download original pode ficar em um disco externo, mas o contêiner convertido deve ficar no NVMe interno
- São necessários 982 GiB para o contêiner convertido e 1,42 TB para staging dos shards originais; o espaço de staging pode ser liberado após a conversão
Attention e processamento multimodal
- A attention do K3 combina Kimi Delta Attention e gated multi-head latent attention na proporção 3:1
- O KDA mantém um recurrent state de tamanho fixo em vez de um KV cache crescente
- O MLA faz cache de um latent de largura 512, sem expandir keys/values por head
- Ao absorver
kv_b_projna query e na output, o cache para contexto de 4K cai de 11,25 GB para 0,21 GB- Uma redução de 53 vezes em relação ao formato anterior
- Em 128K, o layout expandido exige 360 GB, e o layout latent exige 7,2 GB
- O caminho multimodal oferece suporte a um ViT de 401M parâmetros, 27 camadas e patch 14
- A codificação de imagem com 1024 patches leva 15,7 segundos
- Imagens de 896×896 ocupam 256 posições de sequência na configuração padrão
- Como os embeddings de imagem também passam pelas 92 camadas MoE, a maior parte do custo é igual ao prefill de texto, não à torre de visão
- Reduzir
max_patchesemvision.jsonpela metade também reduz pela metade o número de posições de prompt
- Suporta PNG, JPEG, GIF, BMP, TGA e PSD, e imagens podem ser usadas em
run,chateeval- Em uma conversa, as posições de imagens codificadas permanecem no attention state e não são recodificadas no turno seguinte
- A torre de visão só é carregada quando há imagem, usando 434 MB de pesos e 1,12 GB de memória reservada total
Conversão, execução e servidor
- O build exige apenas um compilador C11 e
makemake checkpassa em 23 testes e pula 11 com um contêiner sintético, sem modelo real- Com os dois contêineres reais, o total de testes é 36
- A conversão do K3 usa diretamente os 96 shards safetensors públicos de moonshotai/Kimi-K3
- Leva cerca de 4,7 horas em um M5 Pro com 3 processos
- O encoder em PyTorch puro leva 23,7 horas
- Pode ser retomada por camada, então em caso de interrupção apenas a camada em andamento é reprocessada
- O downloader oferece retomada de arquivos parciais, exponential backoff e jitter, verificação de
Content-Lengthe registro do estado de shards concluídos
- A CLI oferece
run,chat,eval,planetc., e com--jsonimprime resultados deeval,tokenize,plan,infoebenchem formato legível por máquina serve/é um servidor HTTP compatível com OpenAI que chama a API C pública via ctypes- Oferece
/v1/chat/completions,/v1/completions,/v1/modelse/health - Processa streaming, definições e resultados de ferramentas, typed call arguments, esquema de resposta JSON,
tool_choice, think channel,thinking_efforte imagens - O renderer de prompts portou o
encoding_k3.pydo lançamento do K3 e, quando há diretório de pesos, compara 38 conversas em nível de segmento
- Oferece
Plataformas e limitações atuais
- macOS arm64, Linux arm64 e Linux x86_64 registram 23 pass e 11 skip nos mesmos testes independentes de modelo, além de passar em sanitizer e 400 casos de fuzz
- Windows x86_64 foi compilado cruzado com MinGW-w64 e validado com contêiner sintético, CLI e forward pass, mas não foi executado com contêiner de modelo real
- MSVC e Windows ARM64 não são suportados
- O contorno do page cache no Windows foi confirmado apenas no filesystem de CI, não sob carga de um contêiner real maior que a RAM
- O SIMD em x86 escolhe AVX-512 ou AVX2 conforme CPUID, mas o caminho AVX-512 ainda não foi executado em CPU com suporte real
- O backend Metal é correto, mas, pelo formato da carga com centenas de pequenos matvecs dependentes, é 22% mais lento que a CPU e fica desativado por padrão
- A API ainda não está fixa, e a conversão automática de chat format atualmente só dá suporte ao K3
- O Kimi-Linear roda em modo raw, sem tentar inferir o template
- Não será introduzida alocação não uniforme de bits por especialista
- O valor do terceiro bit varia no máximo 1,15× entre especialistas dentro de uma camada e apenas 1,01× entre camadas, então a alocação ótima não trouxe ganho
- A alocação baseada em routing frequency também reduz o espaço de armazenamento, mas quase não reduz o gargalo de I/O
- A licença é Apache 2.0
1 comentários
Comentários do Hacker News
Muito legal. Não é um projeto tentando ser mais prático que um provedor de nuvem agora; é um projeto mostrando os limites do possível
Se a melhoria na eficiência dos modelos e o avanço do desempenho do hardware local se combinarem, um dia modelos locais de alta qualidade também poderão se tornar economicamente viáveis
0,5 token por segundo me parece inútil para qualquer tarefa longa. Eu preferiria gastar dinheiro e usar 2 placas 4060 Ti de 16GB com paralelismo de tensores
Daqui a 20 anos, talvez combine com robôs lentos em estilo cyberpunk movidos a energia solar, cortando grama ou limpando calçadas, ou com um robô no jardim mal conseguindo acompanhar a velocidade de crescimento de um bonsai enquanto faz a poda
Dizem que é desperdício pagar pelo token e deixar o provedor de inferência pagar a conta de luz, mas não vejo como isso seria diferente de comprar pepinos e o agricultor pagar água e fertilizante. Espero que LLM seja só uma lógica improvisada depois do fato
A ideia em si é interessante, e eu gostaria de testar com modelos menores. Se ele gera 0,5 token por segundo enquanto lê vários GB por segundo do SSD, ainda é grande demais para um notebook comum, mas pode até ser mais prático para modelos de 250~500GiB
Assumindo uso contínuo de 42W e eletricidade a 20 centavos por kWh, isso dá cerca de 5 dólares por 1 milhão de tokens, sem contar outros custos como hardware
O llama.cpp padrão também consegue fazer
mmapdo GGUF, então as partes que não cabem na memória ficam no disco, e o cache de páginas do kernel mantém o chunk residente que é usado com frequência. Fico curioso sobre qual seria a vantagem de implementar isso por conta própriammapprimeiro, depois fizeram uma implementação própria e ela ficou 10 vezes mais rápidaÉ o mesmo motivo de engines de banco de dados implementarem o próprio cache. A paginação do kernel é genérica e baseada em requisição, mas se você conhece o padrão real de acesso, pode ler os dados necessários com antecedência e montar um pipeline
Para um modelo que cabe inteiro em RAM, eu tive resultados melhores executando o llama-server com
--no-mmap. Claro, para carregar o Kimi K3 completo e contexto de 1 milhão de tokens seria preciso um servidor com 2TBO README passa muito a sensação de texto escrito por LLM; fico curioso se o codebase também foi escrito por LLM
Agora uso minhas habilidades para coordenar LLMs e agentes e escrever código melhor muito mais rápido. Desenvolvedores têm duas escolhas: se adaptar às novas tecnologias ou ficar para trás
Decisões internas importantes para o usuário, mas irrelevantes para quem vê o produto pronto, e também a terminologia obscura típica do Claude, acabam entrando no texto como estão. Eu uso LLM com frequência e reconheço que é muito útil para escrever código complexo, mas a qualidade de rascunho do texto é péssima
claudena lista de contribuidores, nem é preciso adivinhar. Se chegaram ao ponto de deixar o Claude fazer commits, parece improvável que o código tenha sido revisado diretamenteIsso pode ganhar valor se a tecnologia evoluir a ponto de permitir escolher com precisão o modelo certo para cada tarefa. Dá para imaginar um futuro em que, no processo de exploração automática, um modelo grande rode só uns 30 minutos por dia e o resto do tempo se usem modelos pequenos