{"id":3719,"date":"2026-06-18T05:49:28","date_gmt":"2026-06-18T05:49:28","guid":{"rendered":"https:\/\/aiopsschool.com\/blog\/?p=3719"},"modified":"2026-06-18T05:49:30","modified_gmt":"2026-06-18T05:49:30","slug":"how-to-build-a-self-hosted-qwen-ai-coding-cluster-using-multiple-laptops","status":"publish","type":"post","link":"https:\/\/aiopsschool.com\/blog\/how-to-build-a-self-hosted-qwen-ai-coding-cluster-using-multiple-laptops\/","title":{"rendered":"How to Build a Self-Hosted Qwen AI Coding Cluster Using Multiple Laptops"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Self-Hosted Qwen Coding Cluster: Run AI Coding Agents Across MacBook and Intel Laptops<\/strong><\/li>\n\n\n\n<li><strong>Build Your Own Local AI Coding Cluster with Qwen, Ollama, LiteLLM, and Qwen Code<\/strong><\/li>\n\n\n\n<li><strong>How to Use Multiple Laptops as a Self-Hosted AI Coding Cluster<\/strong><\/li>\n\n\n\n<li><strong>Qwen Coding Cluster Tutorial: Pool MacBook and Intel Laptops for Local AI Development<\/strong><\/li>\n\n\n\n<li><strong>From Spare Laptops to AI Coding Farm: Self-Hosting Qwen for Software Development<\/strong><\/li>\n\n\n\n<li><strong>Complete Guide to Building a Local Qwen AI Coding Agent Cluster<\/strong><\/li>\n\n\n\n<li><strong>Run Qwen Locally: Multi-Laptop AI Coding Cluster Setup for Developers<\/strong><\/li>\n\n\n\n<li><strong>Self-Hosted AI Coding Farm with Qwen: MacBook M4 + Intel Laptop Setup<\/strong><\/li>\n\n\n\n<li><strong>How to Create a Private AI Coding Cluster Using Qwen and Ollama<\/strong><\/li>\n\n\n\n<li><strong>Build a Local Coding Agent Cluster with Qwen: Step-by-Step Developer Guide<\/strong><\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>3\u20134 laptops \u2260 one single pooled Qwen brain\n3\u20134 laptops = multiple local Qwen model servers + one router + multiple coding agents\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Below is a complete practical tutorial.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Self-Hosted Qwen Coding Cluster Using 3\u20134 Laptops<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\">0. What we are building<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">You will have:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Controller Laptop\n  - LiteLLM router\n  - Qwen Code CLI\n  - Git worktrees\n  - task runner scripts\n\nWorker Laptop 1\n  - Ollama\n  - Qwen model\n\nWorker Laptop 2\n  - Ollama\n  - Qwen model\n\nWorker Laptop 3\n  - Ollama\n  - Qwen model\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Final flow:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Qwen Code \/ Aider \/ VS Code\n        \u2193\nLiteLLM Router :4000\n        \u2193\n \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n \u2502 m4-1.local:11434      \u2502 m4-2.local:11434      \u2502 intel-1.local:11434   \u2502\n \u2502 qwen3-coder:30b       \u2502 qwen3-coder:30b       \u2502 qwen2.5-coder:14b\/32b \u2502\n \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This gives you a <strong>local AI coding cluster<\/strong>, not a fake RAM\/CPU pooling trick.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">1. Recommended model selection<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">For your hardware, do not start with Qwen 480B. Ollama lists <code>qwen3-coder:480b<\/code> as a local model requiring at least <strong>250GB memory\/unified memory<\/strong>, so your 24GB MacBooks are not the right machines for that. The practical target is <code>qwen3-coder:30b<\/code> or <code>qwen2.5-coder:14b<\/code>. Ollama lists <code>qwen3-coder:30b<\/code> as around <strong>19GB<\/strong> with a 256K context window, while <code>qwen2.5-coder:14b<\/code> is around <strong>9GB<\/strong> with 32K context. (<a href=\"https:\/\/ollama.com\/library\/qwen3-coder\">ollama.com<\/a>)<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Use this:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Machine<\/th><th>First model to try<\/th><th>Safer fallback<\/th><\/tr><\/thead><tbody><tr><td>M4 MacBook Pro 24GB #1<\/td><td><code>qwen3-coder:30b<\/code><\/td><td><code>qwen2.5-coder:14b<\/code><\/td><\/tr><tr><td>M4 MacBook Pro 24GB #2<\/td><td><code>qwen3-coder:30b<\/code><\/td><td><code>qwen2.5-coder:14b<\/code><\/td><\/tr><tr><td>Intel i7 64GB<\/td><td><code>qwen2.5-coder:32b<\/code> only if patient<\/td><td><code>qwen2.5-coder:14b<\/code><\/td><\/tr><tr><td>Extra laptop<\/td><td>same as above<\/td><td><code>qwen2.5-coder:7b<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Important: 24GB Mac can load a 19GB model, but context\/KV cache also needs memory. Ollama says larger context increases memory usage, and parallel requests multiply context memory usage. For coding agents on 24GB machines, start with <strong>8K or 16K context<\/strong>, not 64K\/256K. (<a href=\"https:\/\/docs.ollama.com\/context-length\">docs.ollama.com<\/a>)<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">2. Name your laptops<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Use simple hostnames.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>m4-1.local\nm4-2.local\nintel-1.local\ncontroller.local\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">On macOS<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Run this on each Mac, changing the name:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo scutil --set HostName m4-1\nsudo scutil --set LocalHostName m4-1\nsudo scutil --set ComputerName m4-1\ndscacheutil -flushcache\nhostname\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">For the second Mac:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo scutil --set HostName m4-2\nsudo scutil --set LocalHostName m4-2\nsudo scutil --set ComputerName m4-2\ndscacheutil -flushcache\nhostname\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">On Ubuntu\/Linux Intel laptop<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo hostnamectl set-hostname intel-1\nsudo apt update\nsudo apt install -y avahi-daemon\nsudo systemctl enable --now avahi-daemon\nhostname\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Now test from your controller:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ping m4-1.local\nping m4-2.local\nping intel-1.local\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">3. Install Ollama on every worker laptop<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Ollama supports Apple M-series Macs with CPU\/GPU support, while x86 Macs are CPU-only according to its macOS requirements. On Linux, Ollama can run as a systemd service, and NVIDIA\/AMD GPU setup is optional depending on hardware. (<a href=\"https:\/\/docs.ollama.com\/macos\">docs.ollama.com<\/a>)<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">macOS workers<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Install Ollama:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>curl -fsSL https:\/\/ollama.com\/install.sh | sh\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Verify:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ollama --version\nollama list\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Ubuntu\/Linux worker<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>curl -fsSL https:\/\/ollama.com\/install.sh | sh\nsudo systemctl status ollama\nollama --version\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">4. Configure Ollama for LAN cluster mode<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">By default, Ollama binds to <code>127.0.0.1:11434<\/code>. To expose it to your LAN, set <code>OLLAMA_HOST=0.0.0.0:11434<\/code>. Ollama\u2019s docs specifically say to use <code>launchctl<\/code> on macOS and systemd environment overrides on Linux. (<a href=\"https:\/\/docs.ollama.com\/faq\">docs.ollama.com<\/a>)<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">On macOS workers<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Run this on each Mac:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>launchctl setenv OLLAMA_HOST \"0.0.0.0:11434\"\nlaunchctl setenv OLLAMA_CONTEXT_LENGTH \"8192\"\nlaunchctl setenv OLLAMA_NUM_PARALLEL \"1\"\nlaunchctl setenv OLLAMA_MAX_LOADED_MODELS \"1\"\nlaunchctl setenv OLLAMA_KEEP_ALIVE \"30m\"\nlaunchctl setenv OLLAMA_NO_CLOUD \"1\"\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Restart Ollama:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>osascript -e 'quit app \"Ollama\"' || true\nopen -a Ollama\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Check:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>curl http:\/\/localhost:11434\/api\/tags\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">On Linux worker<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Create systemd override:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo systemctl edit ollama\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Paste:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&#91;Service]\nEnvironment=\"OLLAMA_HOST=0.0.0.0:11434\"\nEnvironment=\"OLLAMA_CONTEXT_LENGTH=8192\"\nEnvironment=\"OLLAMA_NUM_PARALLEL=1\"\nEnvironment=\"OLLAMA_MAX_LOADED_MODELS=1\"\nEnvironment=\"OLLAMA_KEEP_ALIVE=30m\"\nEnvironment=\"OLLAMA_NO_CLOUD=1\"\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Restart:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo systemctl daemon-reload\nsudo systemctl restart ollama\nsudo systemctl status ollama\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Allow LAN access on Linux firewall:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo ufw allow from 192.168.0.0\/16 to any port 11434 proto tcp\nsudo ufw reload\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Do <strong>not<\/strong> expose port <code>11434<\/code> directly to the public internet. Keep it LAN-only or VPN-only.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">5. Pull Qwen models on each laptop<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\">On M4 MacBook workers<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Try the stronger model first:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ollama pull qwen3-coder:30b\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Also pull a safer fallback:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ollama pull qwen2.5-coder:14b\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Test:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ollama run qwen3-coder:30b \"Reply only: READY\"\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Check memory\/offload:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ollama ps\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If the Mac becomes slow, hot, or memory pressure goes red, use:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ollama stop qwen3-coder:30b\nollama run qwen2.5-coder:14b \"Reply only: READY\"\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">On Intel i7 64GB worker<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Without NVIDIA GPU, Intel will likely be much slower. Start with 14B:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ollama pull qwen2.5-coder:14b\nollama run qwen2.5-coder:14b \"Reply only: READY\"\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Then test 32B only as a deep\/slow worker:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ollama pull qwen2.5-coder:32b\nollama run qwen2.5-coder:32b \"Reply only: READY\"\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">6. Test each worker from controller<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">From your controller laptop:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>curl http:\/\/m4-1.local:11434\/api\/tags\ncurl http:\/\/m4-2.local:11434\/api\/tags\ncurl http:\/\/intel-1.local:11434\/api\/tags\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Test OpenAI-compatible chat endpoint. Ollama supports OpenAI-style <code>\/v1\/chat\/completions<\/code>, and the API key is required by clients but ignored by Ollama. (<a href=\"https:\/\/docs.ollama.com\/api\/openai-compatibility\">docs.ollama.com<\/a>)<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>curl http:\/\/m4-1.local:11434\/v1\/chat\/completions \\\n  -H \"Content-Type: application\/json\" \\\n  -d '{\n    \"model\": \"qwen2.5-coder:14b\",\n    \"messages\": &#91;\n      {\"role\": \"user\", \"content\": \"Write a Python hello world in one line.\"}\n    ]\n  }'\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">For Qwen3-Coder:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>curl http:\/\/m4-1.local:11434\/v1\/chat\/completions \\\n  -H \"Content-Type: application\/json\" \\\n  -d '{\n    \"model\": \"qwen3-coder:30b\",\n    \"messages\": &#91;\n      {\"role\": \"user\", \"content\": \"Explain what a Kubernetes Deployment does in 3 lines.\"}\n    ]\n  }'\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">7. Install LiteLLM router on controller<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">LiteLLM is useful here because it gives you one OpenAI-compatible gateway and can load-balance multiple deployments under the same model group. Its docs describe LiteLLM Proxy as an LLM gateway with OpenAI-style Chat Completions and load balancing across multiple model deployments. (<a href=\"https:\/\/docs.litellm.ai\/docs\/proxy\/quick_start\">docs.litellm.ai<\/a>)<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">On controller:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>mkdir -p ~\/qwen-cluster\ncd ~\/qwen-cluster\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Install <code>uv<\/code> if you do not have it:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>curl -LsSf https:\/\/astral.sh\/uv\/install.sh | sh\nsource ~\/.zshrc 2&gt;\/dev\/null || source ~\/.bashrc 2&gt;\/dev\/null || true\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Install LiteLLM Proxy:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>uv tool install 'litellm&#91;proxy]'\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Verify:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>litellm --version\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">8. Create LiteLLM cluster config<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Create config:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>cd ~\/qwen-cluster\nnano litellm-config.yaml\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Paste this first version:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>model_list:\n  # Fast cluster: two M4 laptops running same model\n  - model_name: qwen-coder-fast\n    litellm_params:\n      model: ollama_chat\/qwen2.5-coder:14b\n      api_base: http:\/\/m4-1.local:11434\n      rpm: 4\n\n  - model_name: qwen-coder-fast\n    litellm_params:\n      model: ollama_chat\/qwen2.5-coder:14b\n      api_base: http:\/\/m4-2.local:11434\n      rpm: 4\n\n  # Stronger but tighter M4 model\n  - model_name: qwen-coder-30b\n    litellm_params:\n      model: ollama_chat\/qwen3-coder:30b\n      api_base: http:\/\/m4-1.local:11434\n      rpm: 2\n\n  - model_name: qwen-coder-30b\n    litellm_params:\n      model: ollama_chat\/qwen3-coder:30b\n      api_base: http:\/\/m4-2.local:11434\n      rpm: 2\n\n  # Intel deep\/slow worker\n  - model_name: qwen-coder-intel\n    litellm_params:\n      model: ollama_chat\/qwen2.5-coder:14b\n      api_base: http:\/\/intel-1.local:11434\n      rpm: 1\n\nrouter_settings:\n  routing_strategy: simple-shuffle\n  num_retries: 1\n  timeout: 600\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Why separate model groups?<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>qwen-coder-fast  = stable daily coding\nqwen-coder-30b   = better coding, heavier memory\nqwen-coder-intel = slow fallback \/ review \/ tests\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Do <strong>not<\/strong> mix <code>14b<\/code>, <code>30b<\/code>, and <code>32b<\/code> under the same alias at first. It makes performance unpredictable.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">9. Start LiteLLM router<\/h1>\n\n\n\n<pre class=\"wp-block-code\"><code>cd ~\/qwen-cluster\nexport LITELLM_MASTER_KEY=\"sk-local-qwen-router-change-me\"\nlitellm --config litellm-config.yaml --host 0.0.0.0 --port 4000\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">In another terminal, test:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>curl http:\/\/localhost:4000\/chat\/completions \\\n  -H \"Content-Type: application\/json\" \\\n  -H \"Authorization: Bearer sk-local-qwen-router-change-me\" \\\n  -d '{\n    \"model\": \"qwen-coder-fast\",\n    \"messages\": &#91;\n      {\"role\": \"user\", \"content\": \"Write a Bash command to list files larger than 100MB.\"}\n    ]\n  }'\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Test the 30B group:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>curl http:\/\/localhost:4000\/chat\/completions \\\n  -H \"Content-Type: application\/json\" \\\n  -H \"Authorization: Bearer sk-local-qwen-router-change-me\" \\\n  -d '{\n    \"model\": \"qwen-coder-30b\",\n    \"messages\": &#91;\n      {\"role\": \"user\", \"content\": \"Review this Terraform snippet conceptually: resource aws_s3_bucket test {}\"}\n    ]\n  }'\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Test from another laptop:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>curl http:\/\/controller.local:4000\/chat\/completions \\\n  -H \"Content-Type: application\/json\" \\\n  -H \"Authorization: Bearer sk-local-qwen-router-change-me\" \\\n  -d '{\n    \"model\": \"qwen-coder-fast\",\n    \"messages\": &#91;\n      {\"role\": \"user\", \"content\": \"Reply only: CLUSTER_OK\"}\n    ]\n  }'\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">10. Install Qwen Code on controller<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Qwen Code is now a proper terminal AI coding agent. Its repo says it supports OpenAI-compatible providers and local models such as Ollama\/vLLM, and it has interactive, headless, IDE, daemon, SDK, and agent-team style usage. (<a href=\"https:\/\/github.com\/QwenLM\/qwen-code\">GitHub<\/a>)<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Install:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>brew install qwen-code\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Or via npm:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>npm install -g @qwen-code\/qwen-code@latest\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Verify:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>qwen --version\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">11. Configure Qwen Code to use your local cluster<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Qwen Code supports <code>~\/.qwen\/settings.json<\/code> with <code>modelProviders<\/code>, <code>security.auth.selectedType<\/code>, and <code>model.name<\/code>. Its docs also show local\/self-hosted models via OpenAI-compatible API by setting <code>baseUrl<\/code>. (<a href=\"https:\/\/qwenlm.github.io\/qwen-code-docs\/en\/users\/configuration\/auth\/\">Qwen<\/a>)<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Create config:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>mkdir -p ~\/.qwen\nnano ~\/.qwen\/settings.json\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Paste:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>{\n  \"modelProviders\": {\n    \"openai\": &#91;\n      {\n        \"id\": \"qwen-coder-fast\",\n        \"name\": \"Local Qwen Coder Fast Cluster\",\n        \"baseUrl\": \"http:\/\/localhost:4000\",\n        \"envKey\": \"LOCAL_QWEN_ROUTER_KEY\",\n        \"generationConfig\": {\n          \"timeout\": 600000,\n          \"maxRetries\": 1,\n          \"contextWindowSize\": 8192,\n          \"samplingParams\": {\n            \"temperature\": 0.2,\n            \"top_p\": 0.9,\n            \"max_tokens\": 4096\n          }\n        }\n      },\n      {\n        \"id\": \"qwen-coder-30b\",\n        \"name\": \"Local Qwen3 Coder 30B Cluster\",\n        \"baseUrl\": \"http:\/\/localhost:4000\",\n        \"envKey\": \"LOCAL_QWEN_ROUTER_KEY\",\n        \"generationConfig\": {\n          \"timeout\": 900000,\n          \"maxRetries\": 1,\n          \"contextWindowSize\": 8192,\n          \"samplingParams\": {\n            \"temperature\": 0.2,\n            \"top_p\": 0.9,\n            \"max_tokens\": 4096\n          }\n        }\n      },\n      {\n        \"id\": \"qwen-coder-intel\",\n        \"name\": \"Local Qwen Intel Worker\",\n        \"baseUrl\": \"http:\/\/localhost:4000\",\n        \"envKey\": \"LOCAL_QWEN_ROUTER_KEY\",\n        \"generationConfig\": {\n          \"timeout\": 1200000,\n          \"maxRetries\": 0,\n          \"contextWindowSize\": 8192,\n          \"samplingParams\": {\n            \"temperature\": 0.2,\n            \"top_p\": 0.9,\n            \"max_tokens\": 4096\n          }\n        }\n      }\n    ]\n  },\n  \"security\": {\n    \"auth\": {\n      \"selectedType\": \"openai\"\n    }\n  },\n  \"model\": {\n    \"name\": \"qwen-coder-fast\"\n  }\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Set key:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>echo 'export LOCAL_QWEN_ROUTER_KEY=\"sk-local-qwen-router-change-me\"' &gt;&gt; ~\/.zshrc\nsource ~\/.zshrc\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Launch:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>qwen\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Inside Qwen Code:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/model\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Select:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Local Qwen Coder Fast Cluster\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Test prompt:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Analyze this repository and tell me the tech stack, entry points, and test commands.\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">12. Use it for real coding<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Create a test repo:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>mkdir -p ~\/ai-lab\ncd ~\/ai-lab\ngit clone &lt;YOUR_REPO_URL&gt; app\ncd app\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Run Qwen Code:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>qwen\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Good first prompt:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Do not modify files yet. First inspect the repo and tell me:\n1. tech stack\n2. build command\n3. test command\n4. risky files\n5. suggested first small task\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Then:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Create a plan to add unit tests for the authentication module. Do not execute commands without asking.\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Then:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Implement the first small test only. Keep changes minimal.\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Review:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>git diff\ngit status\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Commit only after review:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>git add .\ngit commit -m \"test: add auth unit test\"\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">13. Turn it into a real multi-agent coding cluster<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">This is where your 3\u20134 laptops become useful.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Use Git worktrees so each AI agent works separately.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>cd ~\/ai-lab\/app\n\ngit worktree add ..\/app-agent-1 -b ai\/agent-1-auth-tests\ngit worktree add ..\/app-agent-2 -b ai\/agent-2-docs\ngit worktree add ..\/app-agent-3 -b ai\/agent-3-refactor\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Open 3 terminals.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Terminal 1<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>cd ~\/ai-lab\/app-agent-1\nqwen -p \"You are agent 1. Add focused unit tests for the authentication module. Keep changes minimal. Run tests if possible. Do not touch unrelated files.\"\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Terminal 2<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>cd ~\/ai-lab\/app-agent-2\nqwen -p \"You are agent 2. Improve README developer setup instructions based on this repository. Do not change source code.\"\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Terminal 3<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>cd ~\/ai-lab\/app-agent-3\nqwen -p \"You are agent 3. Find one small refactor opportunity in the API layer. Make a minimal safe change and explain the risk.\"\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Qwen Code\u2019s docs list headless mode as <code>qwen -p \"...\"<\/code>, useful for scripts, CI\/CD, and batch processing. (<a href=\"https:\/\/github.com\/QwenLM\/qwen-code\">GitHub<\/a>)<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Now your agents are parallel:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Agent 1 \u2192 test branch\nAgent 2 \u2192 docs branch\nAgent 3 \u2192 refactor branch\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Check results:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>cd ~\/ai-lab\/app-agent-1\ngit diff\n\ncd ~\/ai-lab\/app-agent-2\ngit diff\n\ncd ~\/ai-lab\/app-agent-3\ngit diff\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Merge manually after review.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">14. Optional: create a simple task runner<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Create file:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>cd ~\/qwen-cluster\nnano run-agent-task.sh\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Paste:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#!\/usr\/bin\/env bash\nset -euo pipefail\n\nREPO=\"$1\"\nBRANCH=\"$2\"\nTASK=\"$3\"\n\nBASE_DIR=\"$HOME\/ai-lab\"\nWORKTREE=\"$BASE_DIR\/$BRANCH\"\n\nmkdir -p \"$BASE_DIR\"\n\ncd \"$REPO\"\n\ngit fetch --all --prune\ngit worktree add \"$WORKTREE\" -b \"$BRANCH\" || true\n\ncd \"$WORKTREE\"\n\nqwen -p \"$TASK\"\n\necho\necho \"===== STATUS =====\"\ngit status --short\n\necho\necho \"===== DIFF =====\"\ngit diff --stat\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Make executable:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>chmod +x run-agent-task.sh\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Run:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>~\/qwen-cluster\/run-agent-task.sh \\\n  ~\/ai-lab\/app \\\n  ai\/add-healthcheck-tests \\\n  \"Add tests for the healthcheck endpoint. Keep the change minimal. Run the relevant test command if you can infer it.\"\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Run another:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>~\/qwen-cluster\/run-agent-task.sh \\\n  ~\/ai-lab\/app \\\n  ai\/update-deployment-docs \\\n  \"Update deployment documentation. Do not change application source code.\"\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This is your basic AI coding farm.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">15. Optional: use Aider with the same cluster<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Aider can connect to any OpenAI-compatible endpoint, including local endpoints. Its docs show <code>OPENAI_API_BASE<\/code> and <code>OPENAI_API_KEY<\/code> for OpenAI-compatible APIs. (<a href=\"https:\/\/aider.chat\/docs\/llms\/openai-compat.html?utm_source=chatgpt.com\">aider.chat<\/a>)<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Install:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>python3 -m pip install aider-install\naider-install\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Configure:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>export OPENAI_API_BASE=\"http:\/\/localhost:4000\"\nexport OPENAI_API_KEY=\"sk-local-qwen-router-change-me\"\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Run:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>cd ~\/ai-lab\/app\naider --model openai\/qwen-coder-fast\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Or try 30B:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>aider --model openai\/qwen-coder-30b\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">16. Performance tuning<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\">For 24GB M4 MacBooks<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Start safe:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>launchctl setenv OLLAMA_CONTEXT_LENGTH \"8192\"\nlaunchctl setenv OLLAMA_NUM_PARALLEL \"1\"\nlaunchctl setenv OLLAMA_MAX_LOADED_MODELS \"1\"\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">For <code>qwen2.5-coder:14b<\/code>, you can try:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>launchctl setenv OLLAMA_CONTEXT_LENGTH \"16384\"\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">For <code>qwen3-coder:30b<\/code>, stay conservative:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>launchctl setenv OLLAMA_CONTEXT_LENGTH \"8192\"\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Then restart Ollama:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>osascript -e 'quit app \"Ollama\"' || true\nopen -a Ollama\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Check:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ollama ps\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">For Linux Intel<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">If CPU-only, do not expect magic. Use it for:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>slow review\nsmall model\ntest runner\nDocker\ndatabase\nGit worktree storage\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Use:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo systemctl edit ollama\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Keep:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&#91;Service]\nEnvironment=\"OLLAMA_CONTEXT_LENGTH=8192\"\nEnvironment=\"OLLAMA_NUM_PARALLEL=1\"\nEnvironment=\"OLLAMA_MAX_LOADED_MODELS=1\"\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Restart:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo systemctl daemon-reload\nsudo systemctl restart ollama\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">17. Security checklist<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">This part matters. Local coding agents can read files, run shell commands, and modify repos.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Do this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Use separate repo clones\nUse Git worktrees\nUse branch per task\nDo not mount production secrets\nDo not expose Ollama\/LiteLLM to internet\nUse LAN\/VPN only\nUse LiteLLM master key\nReview git diff before commit\nNever let agent push directly to main\nNever give AWS\/GCP production credentials to agent shell\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Also enable local-only Ollama mode:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>launchctl setenv OLLAMA_NO_CLOUD \"1\"\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">or on Linux:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Environment=\"OLLAMA_NO_CLOUD=1\"\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Ollama says local prompts\/data are not sent to Ollama when running locally, and cloud features can be disabled with <code>OLLAMA_NO_CLOUD=1<\/code> or server config. (<a href=\"https:\/\/docs.ollama.com\/faq\">docs.ollama.com<\/a>)<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">18. Troubleshooting<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\">Problem: <code>curl http:\/\/m4-1.local:11434\/api\/tags<\/code> fails<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Check Ollama is listening:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>lsof -i :11434\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">On macOS:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code> listening:\n\n```bash\nlaunchctl getenv OLLAMA_HOST\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Restart:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>osascript -e 'quit app \"Ollama\"' || true\nopen -a Ollama\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">On Linux:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo systemctl status ollama\njournalctl -u ollama -n 100 --no-pager\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Problem: model too slow<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Use smaller model:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ollama pull qwen2.5-coder:7b\nollama run qwen2.5-coder:7b \"Reply READY\"\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Then update LiteLLM config:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>model: ollama_chat\/qwen2.5-coder:7b\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Restart LiteLLM.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Problem: Mac memory pressure<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Stop heavy model:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ollama stop qwen3-coder:30b\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Use 14B:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ollama run qwen2.5-coder:14b\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Problem: LiteLLM not routing<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Run debug:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>export LITELLM_LOG=DEBUG\nlitellm --config litellm-config.yaml --host 0.0.0.0 --port 4000 --detailed_debug\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">LiteLLM docs show <code>--detailed_debug<\/code> for debug(<a href=\"https:\/\/docs.litellm.ai\/docs\/proxy\/quick_start\">docs.litellm.ai<\/a>)cite\ue202turn843007view1\ue201<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Problem: Qwen Code opens wrong auth flow<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Force OpenAI-compatible auth in:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>nano ~\/.qwen\/settings.json\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Ensure:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\"security\": {\n  \"auth\": {\n    \"selectedType\": \"openai\"\n  }\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Qwen Code docs say <code>security.auth.selectedType<\/code> controls which protocol is used at startup, and <code>model.name<\/code> must match one config(<a href=\"https:\/\/qwenlm.github.io\/qwen-code-docs\/en\/users\/configuration\/auth\/\">Qwen<\/a>)cite\ue202turn383593view1\ue201<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Final recommended setup for your exact hardware<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Use this first:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>M4 MacBook #1:\n  Ollama + qwen2.5-coder:14b\n  Later try qwen3-coder:30b\n\nM4 MacBook #2:\n  Ollama + qwen2.5-coder:14b\n  Later try qwen3-coder:30b\n\nIntel i7 64GB:\n  Ollama + qwen2.5-coder:14b\n  LiteLLM router\n  Git worktrees\n  Docker\/test runner\n\nController:\n  Prefer Intel if always powered on\n  Prefer M4 if you want smoother interactive Qwen Code\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Best stable model group:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>qwen-coder-fast = two M4 laptops running qwen2.5-coder:14b\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Best experimental model group:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>qwen-coder-30b = two M4 laptops running qwen3-coder:30b with 8K context\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The real productivity boost will come from:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>1 repo\n3 worktrees\n3 Qwen Code headless agents\n1 LiteLLM router\n2\u20133 local Qwen model workers\nhuman review before merge\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">That is the practical self-hostedQwen coding cluster.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Below is a complete practical tutorial. Self-Hosted Qwen Coding Cluster Using 3\u20134 Laptops 0. What we are building You will [&hellip;]<\/p>\n","protected":false},"author":4,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-3719","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/aiopsschool.com\/blog\/wp-json\/wp\/v2\/posts\/3719","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/aiopsschool.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/aiopsschool.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/aiopsschool.com\/blog\/wp-json\/wp\/v2\/users\/4"}],"replies":[{"embeddable":true,"href":"https:\/\/aiopsschool.com\/blog\/wp-json\/wp\/v2\/comments?post=3719"}],"version-history":[{"count":1,"href":"https:\/\/aiopsschool.com\/blog\/wp-json\/wp\/v2\/posts\/3719\/revisions"}],"predecessor-version":[{"id":3720,"href":"https:\/\/aiopsschool.com\/blog\/wp-json\/wp\/v2\/posts\/3719\/revisions\/3720"}],"wp:attachment":[{"href":"https:\/\/aiopsschool.com\/blog\/wp-json\/wp\/v2\/media?parent=3719"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/aiopsschool.com\/blog\/wp-json\/wp\/v2\/categories?post=3719"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/aiopsschool.com\/blog\/wp-json\/wp\/v2\/tags?post=3719"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}