3 pontos por GN⁺ 2026-03-25 | 1 comentários | Compartilhar no WhatsApp
  • Otimiza a alocação de tensores entre GPU, RAM e NVMe para executar grandes modelos de linguagem com um agendador de inferência com reconhecimento da hierarquia de armazenamento
  • Em um Mac Mini com 32 GB, consegue executar o modelo Mixtral 8x7B (31 GB) a 2.2 tok/s e o modelo Llama 70B (40 GB) a 0.3 tok/s
  • Analisa padrões de acesso e largura de banda do hardware para executar com estabilidade até modelos que excedem a memória física, incluindo modelos que antes falhavam por OOM no llama.cpp
  • Usa roteamento de especialistas em arquitetura MoE, cache de neurônios e prefetch para reduzir o I/O em até 75% e alcançar taxa de acerto de cache de 99.5%
  • Seleciona automaticamente os modos Full-resident, Expert-streaming e Dense FFN-streaming de acordo com o tamanho do modelo e o hardware, mantendo o melhor desempenho
  • Oferece API HTTP compatível com Ollama para integração com OpenClaw e outros, e usa o SSD apenas para leitura, permitindo inferência baseada em NVMe sem degradar a vida útil

Visão geral

  • Hypura é um agendador de inferência de LLM com reconhecimento da hierarquia de armazenamento para o ambiente Apple Silicon, uma ferramenta que realiza otimização da alocação de tensores entre GPU, RAM e NVMe
  • Com base em padrões de acesso, custo de largura de banda e desempenho do hardware, distribui os tensores para executar com estabilidade grandes modelos que excedem a memória física
  • Em um Mac Mini com 32 GB, consegue executar o modelo Mixtral 8x7B (31 GB) a 2.2 tok/s e o modelo Llama 70B (40 GB) a 0.3 tok/s
  • No mesmo ambiente, o llama.cpp não consegue executar devido a OOM (Out of Memory)

Contexto do problema

  • Macs para consumidores contam com memória unificada rápida e armazenamento NVMe, mas têm capacidade de memória limitada
  • Por exemplo, um M1 Max com 32 GB não consegue carregar diretamente um modelo de 40 GB, causando swap excessivo e encerramento por OOM
  • O Hypura resolve esse problema analisando a estrutura do modelo e aplicando a alocação ideal por camada

Alocação em camadas com base na estrutura do modelo

  • Norms e Embeddings: são pequenos, mas acessados a cada token, então ficam fixos na GPU
  • Roteamento de especialistas MoE: aproveita a esparsidade; apenas 2 especialistas entre 8 são ativados por token
    • Intercepta o roteador para identificar os especialistas ativos e carregar do NVMe apenas as partes necessárias
    • Redução de 75% no I/O e taxa de acerto de 99.5% no cache de neurônios
    • Usa co-activation tracking para prever os próximos especialistas ativos e fazer prefetch antecipado
  • Pesos de FFN densos: representam cerca de 60% do tamanho do modelo
    • Faz streaming a partir do NVMe com um buffer pool dinâmico
    • A profundidade de prefetch (prefetch lookahead depth) é ajustada automaticamente conforme a memória disponível
  • Como resultado, modelos que travavam com a abordagem tradicional de mmap passam a ser executáveis, e modelos que cabem em memória operam na velocidade da GPU Metal sem overhead

Como funciona

  • O Hypura lê arquivos GGUF e faz profiling da largura de banda de GPU, RAM e NVMe
  • Cada tensor é colocado em uma das três camadas abaixo
    • GPU (Metal): camadas de Attention, Norm e Embedding
    • RAM: camadas de overflow que não cabem na GPU
    • NVMe: demais camadas, com I/O direto via F_NOCACHE + pread
  • Seleciona automaticamente o modo de inferência de acordo com o tamanho do modelo e o hardware
    • Full-resident: carrega o modelo inteiro em GPU+RAM, sem I/O em NVMe
    • Expert-streaming: para modelos MoE, mantém na GPU apenas tensores não especialistas e faz streaming dos tensores especialistas pelo NVMe
    • Dense FFN-streaming: para grandes modelos não-MoE, mantém Attention+Norm na GPU e faz streaming do FFN pelo NVMe
  • Tamanho do buffer pool, profundidade de prefetch e orçamento de memória são calculados automaticamente com base no perfil do hardware

Desempenho

  • Ambiente de teste: M1 Max, 32 GB de memória unificada, NVMe de 5.1 GB/s
  • Principais resultados de benchmark
    • Qwen 2.5 14B Q4_K_M (8.4 GB): totalmente carregado na GPU, 21 tok/s
    • Mixtral 8x7B Q5_K_M (30.9 GB): modo Expert-streaming, 2.2 tok/s, taxa de acerto de cache de 99.5%
    • Llama 3.3 70B Q4_K_M (39.6 GB): modo Dense FFN-streaming, 0.3 tok/s, pool de 24 slots, prefetch de 7 camadas
  • Modelos que cabem em memória têm overhead zero, enquanto modelos maiores continuam executáveis graças ao Hypura

Instalação e execução

  • Requer Rust 1.75+ e CMake
  • Procedimento de instalação
    git clone --recurse-submodules https://github.com/hypura/hypura.git  
    cd hypura  
    cargo build --release  
    
  • Exemplos de execução
    hypura profile  
    hypura run ./model.gguf --prompt "Hello, world"  
    hypura run ./model.gguf --interactive  
    hypura bench ./model.gguf  
    hypura inspect ./model.gguf  
    
  • Para modelos ainda não validados, recomenda-se testar com --max-tokens 10

Servidor compatível com Ollama

  • O Hypura oferece uma API HTTP compatível com Ollama, sendo totalmente compatível com ferramentas baseadas em Ollama, como o OpenClaw
    hypura serve ./model.gguf  
    
    Endpoint: http://127.0.0.1:8080  
    
    API: /api/generate, /api/chat, /api/tags  
    
  • Principais endpoints
    Endpoint Função
    GET / Verificação de status
    GET /api/tags Lista de modelos carregados
    GET /api/version Versão do servidor
    POST /api/show Metadados do modelo
    POST /api/generate Geração de texto
    POST /api/chat Geração conversacional
  • Para a integração com OpenClaw, defina a base URL do Ollama como Hypura em ~/.openclaw/openclaw.json
  • Opções do servidor
    hypura serve  [OPTIONS]  
    --host    padrão 127.0.0.1  
    --port    padrão 8080  
    --context    padrão 4096  
    

Arquitetura

  • Estrutura em Cargo workspace, composta por dois crates
    • hypura: binário principal e biblioteca
    • hypura-sys: bindings FFI do llama.cpp (build com CMake)
  • Principais módulos
    Módulo Papel
    scheduler/placement.rs Otimização da alocação de tensores entre GPU/RAM/NVMe
    compute/inference.rs Engine de inferência e funções de carregamento/geração para o servidor
    compute/nvme_backend.rs Streaming em NVMe, cache de neurônios e callbacks de avaliação
    server/routes.rs Handlers HTTP compatíveis com Ollama
    profiler/ Profiling de hardware
    cli/bench.rs Ferramenta de benchmark
    model/tensor_role.rs Classificação do papel dos tensores

FAQ

  • Sem problema de vida útil do SSD

    • O Hypura apenas lê do SSD, sem gravações
    • O I/O em NVMe é feito somente em leitura com pread() + F_NOCACHE
    • O SSD atua apenas como armazenamento frio, enquanto o processamento ocorre em RAM/GPU
    • As escritas se limitam a itens mínimos em escala de KB, como JSON de benchmark e arquivos de estatísticas

Diretrizes de segurança

  • Se o modelo exceder o limite de RAM (–4 GB de folga), bench --baseline é bloqueado
  • Para modelos ainda não validados, teste com --max-tokens 10
  • Os modelos de teste ficam armazenados no diretório ./test-models/

Licença

  • MIT License

Aviso ético

  • O código do repositório não foi escrito manualmente pelo autor
  • Foi produzido como um experimento de geração de código orientada por instruções com uso de LLM
  • É um projeto para explorar as possibilidades práticas de inferência baseada em NVMe

1 comentários

 
GN⁺ 2026-03-25
Comentários do Hacker News
  • Gostaria de sugerir isso ao mantenedor. A tabela comparativa atual inclui modelos antigos como Qwen 2.5 14B, Mixtral 8x7B e Llama 3.3 70B
    Recentemente, há muitos relatos de que os modelos Qwen 3.5 MoE apresentam desempenho impressionante em hardware da Apple
    Vale a pena consultar o texto de Simon Willison
    Se possível, seria bom adicionar também o modelo Kimi K2.5 (1T de parâmetros) à tabela
    Tweets relacionados: seikixtc, danpacary

    • Obrigado por compartilhar. Se você topar rodar benchmarks diretamente com o Hypura, eu junto os resultados às estatísticas. Caso contrário, coloco isso na minha lista de tarefas
    • Simon, mudando um pouco de assunto, seu site ficou fora do ar por um tempo
      Apareceu uma mensagem de erro relacionada ao Heroku, mas agora voltou ao normal
      Entrei para ver este post, e vi que você já tinha escrito também sobre o litellm. Gostei muito de ler
    • É uma pena que no exemplo do Kimi esteja faltando a métrica de tokens por segundo
  • Em trabalho local, mesmo uma velocidade abaixo de 1 token por segundo pode ser perfeitamente utilizável se for uma tarefa em segundo plano
    A diferença entre “terminar imediatamente” e “concluir durante a noite” ainda é um salto de desempenho significativo

  • Na prática, o importante é quão sequencial é o padrão de leitura
    O NVMe chega a 5–7GB/s em leitura sequencial, mas cai para algo na faixa de 500MB/s em leitura aleatória
    No caso de um modelo 1T, em fp16, seria preciso fazer streaming de 2TB em um único forward pass, então teoricamente levaria mais de 300 segundos por token
    Não serve para uso interativo, mas pode ter potencial para inferência em lote (batch inference)

    • No M1 Max, leitura aleatória de 4K (QD=1) fica em torno de 65MB/s
    • Concordo. Isso está mais para um POC (Proof of Concept) do que para algo prático
      Mas, em modelos MoE pequenos, dá para gerar vários tokens por segundo e isso já é realmente útil
    • O ponto-chave dos modelos MoE é a ativação esparsa (sparse activation)
      Em vez de ler os 2TB inteiros, só parte das camadas de especialistas é acessada
      Como cada camada tem tamanho de alguns MiB, a eficiência de acesso ao NVMe também não é tão ruim
  • Fiquei me perguntando de onde saiu esse “modelo de 1T de parâmetros”. No repositório só vejo modelos de até 70B

    • Foi mencionado apenas em termos de possibilidade. Mas o desempenho é lento demais para ser prático fora de tarefas especiais de longa duração
      Os modelos realistas são os MoE menores, que ainda conseguem gerar vários tokens por segundo
    • O título parece um pouco exagerado. No fim, o que importa é a velocidade, e não há informação sobre isso
  • A questão dos MoE é justamente que, por causa da ativação esparsa, não é preciso ler os 2TB completos
    Mas o padrão de acesso fica aleatorizado, o que é a pior condição possível para NVMe
    Em tarefas onde a latência é importante, como inferência com agentes, esse ponto é central

  • Parece o tipo de situação que faria o Intel Optane se revirar no túmulo

    • O Memristor também parecia prestes a virar produto comercial há 10 anos, e agora sumiu completamente
    • Ainda tenho quatro Optane novos guardados. Parece piada, mas é verdade
      Na prática, porém, eles não são mais rápidos que NVMe. Em software que suporta leitura/escrita paralela, a diferença quase desaparece
    • Já virou rotina a Intel criar algo bom e abandonar no meio do caminho
      Mesmo assim, se juntar quatro em RAID 0, talvez dê para saturar toda a largura de banda de PCIe 16x
    • menção ao pmem
  • O hardware Mac para consumidores tem memória unificada e NVMe rápidos, mas a capacidade é limitada
    Ao carregar um modelo de 40GB em um M1 Max com 32GB, o swap dispara e no fim o sistema entra em panic
    O macOS não tem um OOM killer como o do Linux; ele simplesmente fica sem espaço de swap

  • Ter “o máximo possível de memória” é importante, mas a variável maior é a largura de banda (bandwidth)
    O M4 Pro tem 273GB/s, o M4 Max 546GB/s e o M4 Ultra 819GB/s
    Depois que o modelo cabe na memória, a largura de banda passa a determinar a velocidade de tokens
    No caso do Hypura, o M4 Max é o sweet spot. Com 64GB, dá para rodar com folga um modelo 70B (Q4) e gerar em 2x a velocidade do Pro

  • Este projeto na prática funciona como uma espécie de memória swap inteligente
    É interessante como ele controla o uso para não sobrecarregar demais o NVMe
    Ainda assim, se o NVMe realmente receber muita carga, há preocupação com redução da vida útil

    • Essa expressão “sobrecarregar o NVMe” soa estranha
      SSDs realmente têm sua vida útil reduzida pelo número de escritas nas células, mas é muito raro que carga de leitura danifique o controlador
      Se isso acontecer, então há outro problema no sistema
  • Seria bom comparar este projeto com experimentos anteriores, outra tentativa
    Houve relatos de que esta abordagem, por ser baseada em mmap, traz muito overhead

    • Esse código foi escrito por LLM, então a confiabilidade é baixa
    • Além disso, esta implementação não usa quantização (quantization) agressiva, então há menos perda de qualidade