Curso / Lição 07
Lição 07 · O engine

DS4 / DwarfStar

As lições anteriores deram o vocabulário — MoE, memória unificada, quantização, KV cache. O DS4 é onde tudo isso vira um binário que roda. Não é mais um carregador genérico de GGUF: é um engine nativo em C escrito por antirez com um único alvo em mente — rodar o DeepSeek-V4 num Mac. Esta lição abre a caixa: a arquitetura, o build que já provamos neste Mac, o streaming de SSD que dissolve o limite de RAM, e como ligar um cliente.

Leia primeiro (fonte primária)
antirez — "A few words on DS4" (antirez.com/news/165)

Esta lição destila o README + MODEL_CARD do DS4 (hf.co/antirez/deepseek-v4-gguf) e o ensaio news/165 — mais o build real neste M5 Max. Por que importa pra missão: é o motor que coloca um modelo de fronteira a rodar local, exatamente o cérebro que o Alembic quer rodar neste Mac sem mandar nada pra nuvem.

Objetivos desta lição
  • Explicar a tese central do DS4 — um engine focado em UMA família de modelos em vez de muitos — e por que isso vence engines genéricos para o DeepSeek-V4.
  • Descrever a pilha em 5 camadas (GGUF assimétrico → núcleo C/Metal → KV híbrido RAM+disco → ds4-server → clientes) e desenhar o caminho de um token entre elas.
  • Escolher o quant correto para uma RAM dada (q2 / q2-q4 / q4 / pro-q2) e prever, antes do download, se cabe.
  • Explicar o streaming de SSD em termos de cache-hit/miss e estimar como mais RAM se traduz em mais tokens por segundo.
0B / 13B
DeepSeek-V4-Flash · total / ativos
0 GB
q2-imatrix em disco (Macs 96/128 GB)
0M
contexto suportado (tokens)
0 binários
gerados pelo make (Metal)

01 · O que é o DS4 — e por que ele é diferente

O DS4 — apelidado de "DwarfStar" — é um engine de inferência pequeno, nativo e autocontido, escrito em C. Ele não tenta rodar qualquer modelo: foi otimizado primeiro para o DeepSeek-V4-Flash (284 B de parâmetros totais, 13 B ativos por token, contexto de 1M). A variante Pro (1,6 T totais / 49 B ativos) existe para máquinas de memória gigante. Pense nele como um motor de corrida construído para uma pista — não um carro de passeio que vai a qualquer lugar.

A diferença em relação a um llama.cpp da vida é o foco: em vez de suportar centenas de arquiteturas, o DS4 conhece uma família a fundo e gasta toda a engenharia nela — quantização sob medida (seção 02), streaming de SSD desenhado para o MoE (seção 04) e um servidor que já fala os protocolos comerciais (seção 05). É o que permite a um modelo de 284 B parecer de fronteira num laptop.

É a primeira vez que uso um modelo local para coisa séria que eu normalmente pediria pro Claude ou pro GPT... o DS4 é muito mais B [fronteira] do que A [modelo local pequeno].— antirez, antirez.com/news/165
O EIXO A → B · onde o DS4 se posiciona (leitura de antirez)
A · modelo local "de brinquedo" B · modelo de fronteira (Claude/GPT) DS4 "muito mais B do que A"

A leitura de antirez (news/165): pela primeira vez um modelo que roda local fica perto do território de Claude/GPT — não no "brinquedo" da esquerda. O DS4 existe para colocar esse ponto no laptop.

Três coisas tiveram que acontecer juntas (Motivations do README): (1) surgiu um modelo aberto quasi-frontier que ainda é rápido — o DeepSeek-V4-Flash; (2) chegaram máquinas pessoais com muita RAM unificada (MacBooks, DGX Spark); (3) o design de KV cache do V4 tornou prático rodar contextos enormes. O DS4 é a aposta de que dá para fazer um modelo parecer "terminado de ponta a ponta" num Mac de 96/128 GB para cima.

01b · DS4 vs llama.cpp — a aposta estreita

A melhor forma de entender o DS4 é contrastá-lo com o carregador genérico que todo mundo conhece. Não é "melhor" em abstrato — é uma troca deliberada: ele abre mão da generalidade para ganhar profundidade numa família só. (O próprio README agradece ao llama.cpp: o DS4 herda formatos GGUF, kernels e tabelas de quant daquele ecossistema.)

LARGURA vs PROFUNDIDADE · llama.cpp (genérico) × DS4 (uma família)
llama.cpp · LARGO + raso centenas de arquiteturas, 1 camada de profundidade Llama Qwen Gemma Phi Mixtral + genérico: qualquer GGUF carrega − não pode otimizar a fundo p/ 1 modelo − quant assimétrico sob medida não é o foco − SSD streaming p/ MoE não é o objetivo central DS4 · ESTREITO + profundo uma família, pilha vertical até o agente DeepSeek-V4 (Flash/Pro) + quant assimétrico 2/8-bit sob medida + SSD streaming desenhado p/ o MoE + logits validados contra a impl. oficial + servidor + agente nativos p/ ESTE modelo

A aposta do DS4: "um modelo de cada vez, validação por vetores oficiais, e integração de agente suficiente para saber se funciona de verdade" (README). Largura é do llama.cpp; profundidade vertical é do DS4.

Dimensãollama.cpp (genérico)DS4 / DwarfStar
Modelos suportadosCentenas de arquiteturasSó os GGUF do DeepSeek-V4 deste projeto
QuantizaçãoFormatos genéricos (Q2_K…Q8)Assimétrica sob medida: experts em 2-bit, resto em Q8
KV cacheTipicamente residente na RAM"Cidadão de disco de 1ª classe" (RAM + SSD)
RAM < modeloGeralmente "não cabe"SSD streaming: vira espectro de velocidade
ValidaçãoGenéricaLogits batem com a impl. oficial em vários ctx
AgenteExternods4-agent nativo, sem fronteira de socket

Repare que metade da tabela são coisas que fazem sentido quando você fixa o modelo: o quant assimétrico, o streaming do MoE e o agente vertical dependem de conhecer a arquitetura exata. É o preço e o prêmio da aposta estreita.

Adivinhe antes de revelar

Um modelo de 284 bilhões de parâmetros em FP16 (16 bits) ocuparia ~568 GB. Quantizado para 2 bits ingênuos, a conta limpa dá ~71 GB. Quanto pesa o GGUF q2 real do DS4 em disco? (Dica: ele não esmaga tudo em 2 bits.)

81 GB. São ~10 GB a mais que a conta limpa — exatamente as camadas que o DS4 mantém em Q8 de propósito (atenção, projeções compartilhadas, roteamento). Esse "extra" é o que faz o modelo continuar chamando ferramentas de forma confiável a 2 bits. A seção 02 abre essa receita.

02 · A arquitetura do engine

O DS4 é uma pilha curta e direta: um GGUF com quantização assimétrica no disco, um núcleo C com kernels Metal que faz a matemática, um KV cache que vive entre RAM e disco, e um servidor que fala os protocolos das APIs comerciais. Os clientes (Claude Code, Codex, seu app) nem percebem que estão falando com algo local. Veja a pilha se montar, camada por camada:

PILHA DO DS4 · GGUF → núcleo C/Metal → KV (RAM+disco) → servidor → clientes
1 · GGUF em disco hf.co/antirez/deepseek-v4-gguf Especialistas roteados quant 2-bit (assimétrico) Resto dos pesos quant Q8 (8-bit) q2-imatrix ≈ 81 GB DeepSeek-V4-Flash 284B totais · 13B ativos ctx 1M tokens 2 · Núcleo DS4 (C) engine nativo · autocontido Kernels Metal alvo primário · GPU unificada CUDA / ROCm (outras plataformas) roteador MoE → 13B ativos por token ⚠ macOS: NUNCA make cpu (bug da VM dá kernel panic) → use Metal (o default) 3 · KV cache RAM + disco (cidadão de 1ª classe) 4 · ds4-server 127.0.0.1:8000 · single-stream /v1/chat/completions · OpenAI /v1/messages · Anthropic /v1/responses · Responses /v1/completions · completions 5 · Clientes Claude Code (via /v1/messages) Codex / seu app (via /v1/chat)

O GGUF assimétrico (1) alimenta o núcleo C com kernels Metal (2); o KV cache (3) vive entre RAM e disco; o ds4-server (4) expõe quatro famílias de API e os clientes (5) falam o protocolo que já conhecem.

A quantização assimétrica 2/8-bit

Aqui está a sacada que faz 284 B caber em 81 GB sem virar lixo. O DS4 não quantiza tudo no mesmo nível. Os especialistas roteados — a maior parte dos parâmetros, mas só um punhado ativo por token — vão para 2-bit. Todo o resto (atenção, embeddings, roteador, camadas densas) fica em Q8. A precisão é gasta onde importa para a fidelidade, e a economia é feita onde há volume. É a tese da Lição 04 aplicada com bisturi, não com martelo.

Por que isso funciona: num MoE, os especialistas roteados concentram o volume de parâmetros, mas como só ~13 B ativam por token, o erro de quantização de cada um pesa pouco no resultado. As partes que tocam todo token (atenção, roteador) ficam em Q8 para não acumular erro. Por isso o GGUF real dá 81 GB e não os ~71 da conta limpa: aquele "a mais" são as camadas mantidas em Q8 de propósito.
Os quants de 2-bit não são brincadeira; ele chama ferramentas de forma confiável.— antirez, DS4 MODEL_CARD
✓ provado neste Mac
Nesta sessão, no M5 Max do fundador: git clone && make compilou 5 binários Metalds4, ds4-server, ds4-bench, ds4-eval e ds4-agent — com exit 0, e os binários rodam. Não é "deve compilar": compilou e executou.

02b · O fluxo de um token, do prompt ao próximo token

Camadas empilhadas é o mapa estático. Agora siga um token pelo engine — é aqui que MoE, atenção comprimida e streaming aparecem em movimento. Cada token novo refaz este caminho. Repare no losango de decisão: é o ponto onde o roteador escolhe os experts, e onde o streaming de SSD pode ou não custar um acesso a disco.

CAMINHO DE UM TOKEN · tokenizar → 43 camadas (atenção + MoE) → amostrar · losango = decisão do cache
1 · tokenizar o prompt (BOS, <|User|>…) 2 · embeddings (Q8, residente na RAM) repete por 43 camadas (loop) 3 · atenção comprimida janela crua 128 tok + linhas comprimidas 4 · roteador escolhe experts só ~13B ativam neste token expert está no cache? ✓ HIT · zero disco ✗ MISS stream do expert do SSD → cache próxima camada ↺ 6 · projeção (Q8) → amostra o próximo token

As caixas verdes/Q8 (embeddings, projeções) estão sempre na RAM. O custo variável está no losango: um HIT não toca o disco; um MISS sobe o expert do SSD. Como cada token re-roteia, a geração é mais sensível a misses que o prefill — exatamente o que diz o README.

Por que 1M de contexto cabe: atenção comprimida (CSA + HCA)

A pergunta óbvia: como um modelo expõe 1 milhão de tokens de contexto sem um KV cache gigante para cada token em cada camada? A resposta está no design de atenção do DeepSeek-V4, que o DS4 implementa fielmente. Cada camada guarda uma janela crua dos últimos 128 tokens (alta resolução, recente) e, além dela, linhas comprimidas no eixo do tempo — várias posições agrupadas numa só linha de KV.

OS 3 TIPOS DE CAMADA · 43 no total · janela crua 128 + compressão no tempo
camadas 0, 1 só janela crua 128 tokens crus (alta resolução) razão: nenhuma estado extra: nenhum o contexto local recente, intacto pares (de 2 em diante) CSA · seletiva · ratio 4 128 crus + 1 linha por 4 tokens indexador escolhe até 512 linhas 64 cabeças de indexador · dim 128 vê só as linhas comprimidas relevantes top-k = 512 ímpares (de 3 em diante) HCA · pesada · ratio 128 128 crus + 1 linha por 128 tokens (sem indexador) razão: 128 · usa as linhas direto o caminho mais barato em estado história longa, fortemente comprimida

Depois das 2 primeiras, o modelo alterna ratio-4 e ratio-128. Comprimir no eixo do tempo (várias posições → 1 linha) é o que troca "KV por token" por "KV por janela", e é por isso que 1M tokens deixa de exigir um cache linear gigante. Fonte: DS4 MODEL_CARD (CSA+HCA, 43 camadas, top-k 512).

Conta guiada · por que a janela crua é "barata" e a compressão "paga" o 1M
1
O modelo tem 43 camadas e mantém uma janela crua de 128 tokens por camada. Essa parte é fixa: não cresce com o contexto. É o seu "contexto local de alta resolução".
2
Acima de 128 tokens, em vez de guardar KV para cada token, as camadas comprimem o tempo. Numa camada ratio-128, 128 posições viram 1 linha de KV. Então 1M de tokens de história ≈ 1.000.000 ÷ 128 ≈ ~7.812 linhas comprimidas — não um milhão.
3
Nas camadas ratio-4, há mais detalhe (1 linha por 4 tokens), mas um indexador seleciona só as 512 linhas mais relevantes para atender — então o custo de atenção também fica limitado, não linear no contexto.
4
Agora você: estime as linhas comprimidas de uma história de 256 mil tokens numa camada ratio-128. (256.000 ÷ 128 = 2.000 linhas. Some a janela crua de 128 e você tem o estado daquela camada — minúsculo perto de 256k.)
Ligação com a Lição 06: esse design de KV comprimido é a metade "modelo" da história; a metade "engine" é o DS4 tratar esse KV como cidadão de disco. Juntos, eles tornam o 1M de contexto não só representável, mas servível num laptop. O MODEL_CARD nota que, a 1M tokens, o V4-Pro precisa de muito menos compute e KV por token que o V3.2.

03 · Quanto baixar — escolha pela sua RAM

O download não é tamanho único. Cada quant casa com uma faixa de memória: quanto mais RAM, mais experts cabem residentes e maior a qualidade que você pode pagar (a seção 04 explica o porquê). Todos vêm de hf.co/antirez/deepseek-v4-gguf. Escolha o alvo de download e arraste a RAM — o painel diz, ao vivo, se cabe:

0 512 GB RAM 128 GB 81 GB ✓ cabe

Escala: 0–512 GB. A barra é o tamanho do download em disco (≈ a memória que os pesos pedem); a linha vermelha é a RAM da máquina. A regra é simples: verde quando o download fica abaixo da RAM. Num M5 Max de 128 GB, o q2 (81) cabe com folga e o q2-q4 (98) cabe apertado; q4 e pro-q2 pedem máquinas maiores.

Alvo de downloadDisco ≈Classe de RAMVariante
q2-imatrix81 GBMacs de 96 / 128 GBV4-Flash
q2-q4-imatrix98 GB128 GB (mais qualidade)V4-Flash
q4-imatrix153 GB≥ 256 GBV4-Flash
pro-q2430 GB512 GBV4-Pro

Todos de hf.co/antirez/deepseek-v4-gguf. O q2-imatrix é o ponto de entrada para os Macs de coding/agente — é o que cabe nos 128 GB com folga e o que vamos servir na seção 05. O streaming de SSD (abaixo) suaviza as bordas, mas a tabela é o ponto de partida.

03b · Conta na ponta do lápis — de onde saem os 81 GB

A tabela diz "81 GB"; aqui está por que. O quant de 2-bit do DS4 é cirúrgico: ele só comprime os experts roteados do MoE — que são a maioria do espaço do modelo — e ainda assim em dois níveis: up/gate em IQ2_XXS e down em Q2_K. Todo o resto (experts compartilhados, projeções, roteamento) fica intacto em Q8. Veja a divisão real:

QUANT ASSIMÉTRICO REAL · só os experts roteados caem a 2-bit · o resto fica em Q8
100% do espaço de parâmetros do modelo → experts roteados · up/gate IQ2_XXS (~2-bit) experts roteados · down Q2_K (~2-bit) compartilhados · projeções roteamento · Q8 intacto ↑ "a maioria de todo o espaço do modelo" (README) — esmagada ↑ "deixado intacto p/ garantir qualidade" Resultado: o tamanho despenca onde há volume (experts), e a precisão é preservada onde toca todo token. É por isso que o arquivo dá 81 GB e não os ~71 da conta de 2-bit uniforme: os ~10 GB a mais são o Q8 mantido de propósito.
Conta guiada · 568 GB → 81 GB sem virar lixo
1
Piso teórico em FP16: 284 B × 16 bits ÷ 8 = 568 GB. Impossível num laptop — é o ponto de partida da Lição 02.
2
2-bit uniforme (ingênuo): 284 B × 2 ÷ 8 ≈ 71 GB. Caberia… mas esmagar a atenção e o roteamento a 2 bits quebraria o raciocínio e o tool-use.
3
2-bit assimétrico (DS4): só os experts roteados vão a ~2-bit; o resto fica em Q8. Esse Q8 extra adiciona ~10 GB → o GGUF real dá 81 GB. O dinheiro foi gasto onde compra qualidade.
4
Agora você: a variante q2-q4 mantém as últimas 6 camadas em q4 e dá 98 GB. Quantos GB a mais que o q2 puro? (98 − 81 = 17 GB — o preço de mais qualidade nas camadas finais, ainda dentro de 128.)

E quando o modelo NÃO cabe? O orçamento de cache de experts

Aqui mora a alavanca prática do streaming (seção 04). Quando você liga --ssd-streaming, os pesos não-roteados ficam residentes e o resto da RAM vira um cache de experts. O orçamento automático do DS4 faz a conta sozinho: pega 80% do working set recomendado pelo Metal, subtrai os pesos não-roteados, e o que sobra vira cache de experts. Arraste a RAM e veja o orçamento se formar (no M5 Max de 128 GB, o automático escolheu ~59 GB — número medido no README):

RAM total 80% working set (linha tracejada) não-roteados cache de experts cache ≈ 59 GB

Conta do orçamento automático: cache = 0,8 × workingset − não-roteados. Mais RAM ⇒ mais cache ⇒ mais experts residentes ⇒ menos cache-miss. Os pesos não-roteados (~22 GB aqui) são fixos; tudo acima deles dentro dos 80% é cache. Estimativa ilustrativa da fórmula do README; o automático no M5 Max real selecionou ~59 GB.

04 · Streaming de SSD: a RAM vira um espectro

Este é o mecanismo mais original do DS4. Em vez de tratar a RAM como um corte rígido — "cabe ou não cabe" — o DS4 trata o SSD como uma extensão contínua. Os pesos não-roteados (atenção, roteador, densas) ficam residentes na memória. Os especialistas roteados são lidos do GGUF sob demanda: quando o roteador pede um especialista que não está no cache, ele é trazido do SSD (cache-miss). E o KV cache é, nas palavras de antirez, "um cidadão de disco de primeira classe".

STREAMING DE SSD · residentes na RAM · cache de experts quentes · expert frio sobe do disco
RAM unificada (residente) acesso da GPU em alta banda Pesos NÃO-roteados — sempre residentes atenção · roteador · camadas densas · Q8 Cache de especialistas roteados os experts quentes ficam aqui E12 E47 E03 livre livre KV cache — começa na RAM, transborda p/ disco SSD (GGUF · 81 GB) cidadão de disco de 1ª classe Todos os especialistas roteados (2-bit) E00 E01 E88 E89 só os pedidos sobem à RAM streaming = níveis contínuos de velocidade cache-miss → stream do expert E88 cache-hit → zero disco (E03/E12/E47 já na RAM)

Pesos não-roteados ficam fixos na RAM; os experts quentes vivem num cache; um expert frio (E88) é trazido do SSD só quando o roteador o pede. Mais RAM = mais experts cabem residentes = menos misses = mais rápido — um espectro, não um corte.

O KV cache é um cidadão de disco de primeira classe. O streaming de SSD transforma a RAM disponível de um corte rígido num espectro contínuo de níveis de velocidade.— antirez, DS4 README

É isso que reconcilia a tabela da seção 03 com a vida real: o q4 (153 GB) "não cabe" num corte rígido de 128 GB, mas com streaming a borda fica macia — os experts mais frios apenas custam um pouco de latência quando são chamados. A RAM deixa de ser um sim/não e vira um botão de velocidade.

04b · Cache-hit → velocidade (e prefill ≠ geração)

O streaming não é grátis: cada cache-miss paga uma leitura de SSD. Mas há uma assimetria importante que o README destaca — o prefill (ler o prompt) tolera misses muito melhor que a geração (produzir tokens), porque cada token novo re-roteia pelos experts. Daí a regra: contexto longo entra rápido; é a geração token-a-token que sente o disco.

PREFILL vs GERAÇÃO · por que o mesmo miss dói mais na geração
PREFILL · lê o prompt (lote) muitos tokens de uma vez → 1 miss se dilui M5 Max q2 @ ~11,7k: 463 t/s GERAÇÃO · 1 token por vez re-roteia → pode dar miss cada token re-visita experts → miss pesa M5 Max q2 @ ~11,7k: 25,9 t/s

No mesmo Mac e no mesmo ponto de contexto, o prefill é ~18× mais rápido que a geração — porque o prefill amortiza o custo dos experts num lote, e a geração paga a cada token. (Números do benchmark do README, q2, M5 Max 128 GB.)

Comparativo: o mesmo q2, em três máquinas

O DS4 publica números reais de velocidade. Compare o nosso M5 Max com o M3 Max anterior e com um Mac Studio M3 Ultra — tudo no mesmo quant (q2), prompt curto, decode guloso. É a prova de que "mais banda/mais máquina = mais tok/s" (a tese da Lição 03):

Máquina (q2, prompt curto)PrefillGeração
MacBook Pro M3 Max, 128 GB58,52 t/s26,68 t/s
MacBook Pro M5 Max, 128 GB87,25 t/s34,27 t/s
Mac Studio M3 Ultra, 512 GB84,43 t/s36,86 t/s
GERAÇÃO (t/s) · q2 prompt curto · M3 Max × M5 Max × M3 Ultra
M3 Max · 26,68 M5 Max · 34,27 ★ nosso M3 Ultra · 36,86 O M5 Max chega perto do Mac Studio M3 Ultra (que tem 512 GB) na geração q2 — num laptop. Fonte: tabela Speed do README.

Sinta o efeito: taxa de acerto → tok/s efetivo

Modelo mental simples: se um cache-hit gera a 34 t/s (o número do M5 Max) e um miss custa uma leitura de SSD, então o tok/s efetivo da geração depende de quantos tokens acertam o cache. Mais RAM ⇒ mais experts residentes ⇒ taxa de acerto maior. Arraste a taxa de acerto e veja:

0 ~34 t/s (100% hit) ~31 t/s 90% de acerto → geração quase no teto.

Modelo ilustrativo (hit ≈ 34 t/s; miss ≈ 6 t/s, dominado pela leitura de SSD): tok/s ≈ hit% × 34 + (1−hit%) × 6. A lição é qualitativa e bate com o README — a geração despenca quando a taxa de miss sobe; o prefill aguenta melhor. [uncertain]: o "~6 t/s de miss" é um valor didático, não medido.

05 · Do clone ao cliente: o fluxo

Quatro passos te levam de zero a um endpoint local servindo. Os dois primeiros — clone e make — já estão provados neste Mac. Os outros dois dependem só de disco e de apontar o cliente. Repare no badge verde de prova nas duas primeiras caixas:

DE ZERO A UM ENDPOINT LOCAL SERVINDO · 5 passos (clone+make ✓ provados)
1 · git clone repo do DS4 ✓ provado neste Mac 2 · make (Metal) 5 binários · exit 0 ✓ provado neste Mac 3 · download_model.sh q2-imatrix ≈ 81 GB · do HF 4 · ds4-server 127.0.0.1:8000 single-stream 5 · cliente Claude Code / Codex Status: o DS4 está em BETA ("existe há poucos dias"); o ds4-agent está em ALPHA. ⚠ no macOS, NUNCA rode make cpu — bug da VM dá kernel panic. Use Metal (o default).

O comando, na prática

# 1+2 — clone e build (provado neste Mac: 5 binários Metal, exit 0)
git clone <repo-do-ds4> && cd ds4 && make
# → ds4  ds4-server  ds4-bench  ds4-eval  ds4-agent

# 3 — baixar o quant que cabe nos 128 GB (≈ 81 GB)
./download_model.sh q2-imatrix

# 4 — servir (NUNCA make cpu no macOS: kernel panic; Metal é o default)
./ds4-server   # OpenAI + Anthropic + Responses + completions em 127.0.0.1:8000

# 5 — plugar um cliente (ex.: chamada Anthropic-compatível)
curl -s 127.0.0.1:8000/v1/messages -d '{"model":"deepseek-v4-flash","messages":[...]}'

O que "single-stream" significa

O ds4-server aceita os quatro protocolos, mas tem uma propriedade que define como você o opera: ele é single-stream — uma única requisição em voo por vez. Não há paralelismo de requisições; o servidor processa um grafo de cada vez e serializa o resto. Consequência prática: um cliente sério por vez. Para visão concorrente, separe o endpoint (assunto da Lição 08).

BETA — leia antes de depender disso
O DS4 "existe há poucos dias" e está em beta; o ds4-agent é alpha. Trate como ferramenta de fronteira em movimento: ótima para trabalho sério agora, mas ainda não como infra estável de produção. E a regra que pode custar o sistema: no macOS, nunca make cpu — um bug da VM dá kernel panic. Sempre Metal (o default).

05b · As quatro APIs lado a lado — e por que single-stream

O ds4-server fala quatro famílias de protocolo de uma vez. Isso é o que faz um cliente comercial (Claude Code, Codex) "não perceber" que está falando com algo local: cada um usa o endpoint que já conhece. Veja qual cliente casa com qual rota:

UMA PORTA (:8000), QUATRO PROTOCOLOS · cada cliente fala o seu
/v1/chat/completionsOpenAI · tools→DSML /v1/responsesResponses · preferido p/ Codex /v1/messagesAnthropic · Claude Code · tool_use /v1/completions · /v1/modelscompletions + descoberta 1 graph worker serializa · prefixo reusável GGUF carregado (-m) flash/pro são aliases min_p=0,05 default · temp=1 · top_p=1 · SSE em chat/responses/messages tool-call: ID guardado → replay exato do DSML (prefixo do KV continua batendo)

A propriedade que define a operação: o parsing roda em threads, mas a inferência é serializada por um único graph worker — o servidor não junta requisições independentes em lote. É o "single-stream". Veja a fila:

SINGLE-STREAM · uma requisição em voo · losango = worker livre?
req chega worker livre? sim processa o grafo SSE → cliente não → espera a vez (fila)

Consequência prática: um cliente sério por vez. Não é limitação de bug — é a escolha de manter um único checkpoint de KV vivo (e reusar o prefixo). Para rodar visão concorrente, separe o endpoint (Lição 08).

Comparativo extra: os três modos de raciocínio

O DeepSeek-V4-Flash tem três "marchas" de esforço de raciocínio — e a diferença em tarefas de código/matemática é enorme. Isso importa porque o mesmo modelo local pode ser rápido-e-direto ou lento-e-profundo. Clique para comparar (números do MODEL_CARD oficial):

Non-think — resposta intuitiva, sem raciocínio oculto (abre com </think>). Bom para tarefas fáceis e latência baixa. LiveCodeBench 55,2 · HMMT 2026 40,8 · GPQA Diamond 71,2. É a marcha dos benchmarks de velocidade da seção 04b.
High — raciocínio deliberado (<think>…</think>) para tarefas mais difíceis. LiveCodeBench 88,4 · HMMT 2026 91,9 · GPQA Diamond 87,4. O salto sobre Non-think em código/math é brutal — o "pensar" paga.
Max — maior orçamento de raciocínio (prompt de sistema especial; o MODEL_CARD recomenda ≥384K de contexto). LiveCodeBench 91,6 · HMMT 2026 94,8 · GPQA Diamond 88,1. Teto de qualidade, ao custo de muitos tokens de "thinking".
LIVECODEBENCH (Pass@1) · o ganho de "pensar" · Non-think → High → Max
Non-think · 55,2 High · 88,4 Max · 91,6 Escala 0–100. O grande salto é Non-think→High (+33). High→Max rende pouco a muito custo. Fonte: DS4 MODEL_CARD.

Fixe os conceitos (flashcards)

Clique pra virar. Tente lembrar a resposta antes de virar — recuperação ativa fixa mais que reler.

Tese
Por que o DS4 vence o llama.cpp para o V4?
clique pra virar ↻
Resposta
Aposta estreita: uma família a fundo. Quant assimétrico, SSD streaming do MoE e agente vertical só fazem sentido conhecendo o modelo exato.
Quant
O que cai a 2-bit e o que fica em Q8?
clique pra virar ↻
Resposta
Só experts roteados → 2-bit (up/gate IQ2_XXS, down Q2_K). Compartilhados, projeções e roteamento ficam em Q8. Por isso 81 GB, não 71.
Streaming
Prefill ou geração sente mais o cache-miss?
clique pra virar ↻
Resposta
A geração: cada token re-roteia pelos experts. O prefill amortiza num lote. No M5 Max q2 @ ~11,7k: 463 t/s prefill vs 25,9 t/s geração.
Server
Por que o ds4-server é single-stream?
clique pra virar ↻
Resposta
Um único graph worker mantém UM checkpoint de KV vivo e reusa o prefixo. Não junta requisições; um cliente sério por vez. Fala 4 APIs.

Revisão cumulativa — recupere de memória

Antes de clicar: tente responder de cabeça. Recuperar da memória (não reler) é o que fixa de verdade. As opções têm tamanhos parecidos de propósito — sem pista pela forma. O placar conta seus acertos.

1. O que a quantização assimétrica 2/8-bit do DS4 faz, exatamente?
Correto: c. Os experts roteados concentram os parâmetros, mas só ~13 B ativam por token, então o erro do 2-bit pesa pouco; as partes que tocam todo token ficam em Q8 (up/gate IQ2_XXS, down Q2_K). Por isso o arquivo dá 81 GB, não 71. Por que as outras falham: (a) 2-bit uniforme quebraria o raciocínio; (b) inverte os papéis — é a atenção que fica em Q8, não em 2-bit; (d) o DS4 roda nos próprios 2-bit, não "desfaz" para Q8 na RAM.
2. O que o streaming de SSD do DS4 muda na relação entre RAM e modelo?
Correto: b. Não-roteados ficam residentes; experts frios são trazidos do SSD sob demanda; o KV cache é "cidadão de disco de primeira classe". Por que as outras falham: (a) é o oposto da ideia — streaming existe justo para a RAM não precisar ser maior que o arquivo; (c) os não-roteados e o cache de experts ficam na RAM, não roda "tudo do disco"; (d) o KV chega a transbordar para o disco, não o contrário.
3. Por que o ds4-server é "single-stream"?
Correto: c. O parsing roda em threads, mas a inferência passa por um único worker; um KV vivo por vez é a razão de "um cliente sério por vez". Por que as outras falham: (a) não é limite do Metal, é desenho do servidor; (b) ele expõe quatro famílias de API (chat, responses, messages, completions), o limite não é de endpoints; (d) ele tem rede (HTTP/SSE, --cors, --host) — o serial é proposital.
4. Por que o DeepSeek-V4 expõe 1M de contexto sem um KV cache gigante por token?
Correto: a. CSA+HCA: a janela crua de 128 dá resolução local; as linhas comprimidas dão história longa barata (1M ÷ 128 ≈ 7,8k linhas, não 1M). Por que as outras falham: (b) compressão de RAM do SO não tem relação com o KV do modelo; (c) um KV linear de 1M não caberia — é justamente o que o design evita; (d) ele não descarta a história: comprime-a e o indexador seleciona até 512 linhas relevantes.
💬 Travou em algo? Eu sou seu professor neste curso — pergunte. "Por que Q8 e não Q6 nas camadas críticas?", "Quanto custa um cache-miss em tok/s no meu SSD?", "Como aponto o Claude Code para o :8000 local?". É só dizer.