Executando modelos locais em um M4 com 24 GB de memória

PUBLICIDADE

Executando modelos locais em um M4 com 24 GB de memória

Tenho experimentado a execução de modelos locais por um tempo e finalmente encontrei uma configuração que parece funcionar razoavelmente. Não é nada parecido com o resultado de um modelo SOTA, mas a empolgação de poder ter um modelo local realizando tarefas básicas, pesquisa e planejamento mais do que compensa isso! Não é necessária conexão com a internet! Sem falar que é uma forma de reduzir sua dependência das grandes tecnologias dos EUA, mesmo que só um pouquinho.

Devo dizer, porém, que não é fácil configurar essas coisas. Primeiro você deve escolher como irá executar o modelo: Ollama, llama.cpp ou LM Studio. Cada um vem com suas peculiaridades e limitações e não oferece todos os mesmos modelos. Então, é claro, você deve escolher seu modelo. Você deseja o melhor modelo disponível que caiba na memória e ainda ofereça espaço suficiente para executar sua variedade regular de aplicativos Electron, sem mencionar algo em que você possa ter pelo menos uma janela de contexto de 64K, mas idealmente 128K ou mais. Mais recentemente, experimentei o Qwen 3.6 Q3, o GPT-OSS 20B, o Devstral Small 24B, que tecnicamente cabem na memória, mas na prática eram inutilizáveis, e o Gemma 4B, que funcionaria bem, mas realmente teria dificuldades com o uso da ferramenta.

Depois, há uma infinidade de opções de configuração para ajustar. Desde opções mais conhecidas, como temperatura, até opções mais esotéricas, como K Cache Quantization Type. Muitas dessas ferramentas vêm com um conjunto básico de opções recomendadas, mas as opções apropriadas podem depender de coisas como se você está permitindo o pensamento ou não!

qwen3.5-9b@q4_k_s (Link HuggingFace) é o melhor modelo que consegui trabalhar com cerca de 40 tokens por segundo, pensamento habilitado, uso de ferramenta bem-sucedido e uma janela de contexto de 128K, rodando no LM Studio. Comparado a um modelo SOTA, ele se distrai com mais facilidade, às vezes fica preso em loops, interpreta mal as perguntas, etc. Mas é surpreendentemente bom para algo que pode ser executado em um Macbook Pro de 24 GB, deixando espaço para muitas outras coisas em execução também!

Estas são as configurações recomendadas para o modo de pensamento e trabalho de codificação:

Modo de pensamento para tarefas de codificação precisas (por exemplo, WebDev):

temperatura = 0,6, top_p = 0,95, top_k = 20, min_p = 0,0, presença_penalty = 0,0, repetition_penalty = 1,0

Para permitir o pensamento, também tive que selecionar o modelo, ir para configuração, rolar até a parte inferior da guia Inferência e adicionar {%- set enable_thinking = true %} para o modelo de prompt.

Tenho usado por meio de pi e OpenCode. Ainda não decidi qual prefiro. Pi parece um pouco mais rápido, mas embora eu realmente aprecie a ideia do próprio chicote e toda essa personalização, não posso deixar de desejar que ele venha com alguns padrões sensatos. Eu sinto que você poderia facilmente acabar gastando mais tempo ajustando sua configuração de pi para ficar perfeita, do que em seus projetos reais!

Aqui está o ~/.pi/agent/models.json:

{
  "providers": {
    "lmstudio": {
      "baseUrl": "http://localhost:1234/v1",
      "api": "openai-completions",
      "apiKey": "lm-studio",
      "models": [
        {
          "id": "qwen3.5-9b@q4_k_s",
          "reasoning": true,
          "compat": { "thinkingFormat": "qwen-chat-template" }
        }
      ]
    }
  }
}

e para esconder o pensamento perturbador, adicione "hideThinkingBlock": true para o seu ~/.pi/agent/settings.json.

~/.config/opencode/opencode.json

{
  "$schema": "https://opencode.ai/config.json",
  "provider": {
    "lmstudio": {
      "npm": "@ai-sdk/openai-compatible",
      "name": "LM Studio (local)",
      "options": {
        "baseURL": "http://127.0.0.1:1234/v1"
      },
      "models": {
        "qwen3.5-9b@q4_k_s": {
          "name": "Qwen 3.5 9B Q4_K_S",
          "tools": true,
          "context_length": 131072,
          "max_tokens": 32768
        }
      }
    }
  },
  "model": "lmstudio/qwen3.5-9b@q4_k_s"
}

Um modelo como Qwen 3.5 9B (Q4) está longe de ser capaz de resolver problemas complexos de forma independente por um longo período de tempo, como os modelos SOTA. Não faz sentido pedir para ele criar um aplicativo inteiro de uma só vez, você apenas queimará as coxas sem tirar nada disso.

O que funciona é um fluxo de trabalho mais interativo, onde você se comunica claramente com o modelo, passo a passo, e fornece muitas orientações. Tenho certeza de que isso parece inútil para muitos de vocês, por que usar um modelo em que você tem que cuidar dele enquanto funciona, mas na verdade descobri que isso me encorajou a ser mais engajado. A desvantagem de trabalhar com modelos SOTA é que eles tornam muito fácil descarregar todo o esforço cognitivo, mesmo quando você está tentando impedir ativamente que isso aconteça.

Com o modal local tenho que assumir muito mais pensamento e planejamento, tenho que ser muito mais específico, mas ele ainda atuará como assistente de pesquisa, pato de borracha e sábio com lembrança instantânea de muitos detalhes da linguagem de programação e evocações de linha de comando. Não é o aumento de produtividade de 10 vezes que as grandes empresas de IA comercializam, mas é algo e é interessante.

Para lhe dar uma ideia de algumas coisas que funcionam e não funcionam, aqui estão alguns exemplos básicos.

Exemplo 1:

Eu queria bater no linter Elixir credo para a versão mais recente e recebi avisos do meu código. Como experiência, pedi a Qwen que desse uma olhada.

me:
  run mix credo --strict and suggest how to solve it, don't edit

Qwen:
    Credo Warnings
    There are 4 warnings in your test files. The issue is using length/1 to check if lists are non-empty. Credo recommends comparing against an empty list instead.
    Warnings:
    1. test/jola_dev_web/controllers/blog_controller_test.exs:11
       - assert length(conn.assigns.posts) > 0
    2. test/jola_dev_web/controllers/blog_controller_test.exs:22
       - assert length(conn.assigns.posts) > 0
    3. test/jola_dev/blog_test.exs:10
       - assert length(posts) > 0
    4. test/jola_dev/blog_test.exs:23
       - assert length(tags) > 0
    How to Fix
    Replace each length(list) > 0 with list != []:
    blog_controller_test.exs:
    # Line 11
    assert conn.assigns.posts != []
    # Line 22
    assert conn.assigns.posts != []
    blog_test.exs:
    # Line 10
    assert posts != []
    # Line 23
    assert tags != []
    This is more idiomatic in Elixir and avoids the overhead of computing the list length.

Pedi ao Qwen para fazer as edições e ele fez 4 edições paralelas, bem limpas. No geral, essa foi uma tarefa muito simples que eu poderia ter feito sozinho, alternando entre o terminal e meu editor para obter os números das linhas para editar. Não é uma grande diferença no esforço, mas é agradável e conveniente.

Exemplo 2:

Depois de alguns problemas de dependência, tive um PR do dependabot com conflitos de git e o dependabot, por algum motivo, estava se recusando a fazer o rebase. Puxei-o para baixo, reformulei-o e pedi a Qwen para dar uma olhada. Foi um conflito muito simples de resolver, bastava pegar a versão mais recente de cada um e o modelo reconheceu isso.

I can see the conflict. Here's what's happening:
HEAD (your current branch):
- sentry: 13.0.1
- tailwind: 0.3.1
Other side (commit being rebased):
- sentry: 12.0.3
- tailwind: 0.4.1
You have divergent dependency bumps. Here are your options:
Option 1: Take both updates (recommended)
- Keep sentry 13.0.1 from HEAD
- Keep tailwind 0.4.1 from the other side
- This gives you the latest of both deps
Option 2: Take only sentry update
- Keep sentry 13.0.1
- Keep tailwind 0.3.1
Option 3: Take only tailwind update
- Keep sentry 12.0.3
- Keep tailwind 0.4.1
Which approach do you want to take?

No entanto, quando solicitado a fazer a alteração, ele se esqueceu de fazer a edição e, em vez disso, apenas tentou adicionar as alterações e continuar o rebase, com os marcadores de conflito ainda em vigor.

> Thinking: The user wants to take both updates - sentry 13.0.1 and tailwind 0.4.1. I need to resolve the conflict by keeping the HEAD version for sentry and the other side version for tailwind. I'll use git add to stage the resolved file.
----
# Stage resolved mix.lock and continue rebase
$ git add mix.lock && git rebase --continue
Vim: Warning: Output is not to a terminal
Vim: Warning: Input is not from a terminal
"~/workspace/mixtli/.git/COMMIT_EDITMSG" 32L, 1047BBump tailwind from 0.3.1 to 0.4.1
Bumps [tailwind](https://github.com/phoenixframework/tailwind) from 0.3.1 to 0.44.1.
- [Changelog](https://github.com/phoenixframework/tailwind/blob/main/CHANGELOG.mmd)
- [Commits](https://github.com/phoenixframework/tailwind/compare/v0.3.1...v0.4.11)

Além disso, não conseguiu reconhecer que git rebase --continue abre um editor e o OpenCode então trava, embora isso possa ter sido apenas um caso isolado.

De qualquer forma, os LLMs são incrivelmente flexíveis e há um milhão de coisas que até um modelo local poderia fazer. Sua imaginação é o limite. Os modelos locais têm sérias vantagens e desvantagens, mas trazem alguns benefícios bastante atraentes:

  • Não é necessária conexão com a internet, você pode trabalhar no avião!

  • O custo é limitado à eletricidade que você está usando, presumindo que você compraria um computador de qualquer maneira. Nenhuma assinatura necessária.

  • Ainda haverá um custo ambiental sério no treinamento desses modelos, mas as empresas de modelo aberto não estão nem perto do topo da lista em termos de impacto ambiental, e usar seu próprio hardware significa menos data centers.

  • É divertido mexer.

Os LLMs tiveram um enorme impacto em nosso mundo, e grande parte dele não foi grande, mas é óbvio que vieram para ficar. Experimentar modelos locais parece uma forma mais sustentável e positiva de interagir com esta tecnologia. E honestamente, é muito divertido, mesmo quando faz a coisa errada!

Fonte: theverge

Mais recentes

PUBLICIDADE

WP Twitter Auto Publish Powered By : XYZScripts.com