-
Notifications
You must be signed in to change notification settings - Fork 5
Troubleshooting
Start here: Run
tightwad doctor --fixfor an automated diagnostic of your setup. It checks config, binaries, network, services, and version compatibility — and suggests fixes for each issue found.
Symptom: tightwad proxy status shows 0 rounds, proxy logs show "Draft failed, falling back to target".
Common causes:
-
Wrong Ollama model name: Ollama uses colons (
qwen3:8b), not dashes (qwen3-8b). A wrong name returns 404 with"model not found"in the response body. -
Draft server unreachable: Check the URL in your config. Try
curl <draft-url>/api/generate -d '{"model":"qwen3:8b","prompt":"test","raw":true,"stream":false}'manually. -
Ollama thinking mode: Qwen3 models on Ollama have thinking enabled by default. The proxy uses
raw: trueto bypass this. If you're using the/v1/completionsendpoint directly, text may be empty because all tokens go to reasoning.
Fix: Delete stale PID file:
rm ~/.tightwad/proxy.pidCause: The chat template is model-family specific. The default Qwen3 template (<|im_start|>) will produce garbage or empty output if the target model is from a different family (e.g., GLM, Llama). Use /v1/completions with raw prompts for cross-family setups, or ensure both draft and target are the same family.
Possible fixes:
- Use same-family models (Qwen3-8B → Qwen3-72B, not Qwen3 → GLM)
- Reduce
max_draft_tokens— shorter drafts have higher acceptance rates - For factual/deterministic prompts, acceptance is naturally higher than creative ones
Symptom: tightwad status shows workers as down.
Checks:
- Is
rpc-serveractually running on the worker machine? - Is the firewall allowing traffic on the RPC ports (50052, 50053)?
- Windows: Add inbound rules in Windows Defender Firewall
- Can you ping the worker from the coordinator?
ping 192.168.86.36 - Can you TCP connect?
nc -zv 192.168.86.36 50052
Windows firewall fix:
netsh advfirewall firewall add rule name="Tightwad RPC 50052" dir=in action=allow protocol=tcp localport=50052
netsh advfirewall firewall add rule name="Tightwad RPC 50053" dir=in action=allow protocol=tcp localport=50053Symptom: tightwad start succeeds but API calls hang or return errors.
Checks:
- Is the model file path correct and accessible on the coordinator?
- Does the coordinator have enough RAM to mmap the model?
- Check coordinator logs:
tightwad logs # last 50 lines tightwad logs -f # live tail
- Try running llama-server manually to see output:
llama-server -m /models/model.gguf -ngl 999 --rpc 192.168.86.36:50052
Coordinator stdout/stderr is logged to ~/.tightwad/logs/coordinator.log in append mode. Proxy logs go to ~/.tightwad/logs/proxy.log.
Cause: Gigabit Ethernet bottleneck.
Mitigations:
- Upgrade to 2.5GbE USB-C adapters (~$25 each) — see Network Optimization
- Reduce remote GPU share — put more layers on the coordinator
- Reduce context size to lower memory bandwidth requirements
- For prompt processing, expect higher network overhead than generation
Symptom: tightwad start says coordinator is already running.
Fix: The PID file at ~/.tightwad/coordinator.pid may be stale. Run tightwad stop first, or if the process is truly dead, delete the PID file manually:
rm ~/.tightwad/coordinator.pidSymptom: rpc-server crashes or coordinator fails to allocate layers.
Cause: Other processes (e.g., existing llama-server for GLM) are using GPU memory.
Fix: Either stop the competing process or adjust tensor split to give less work to that GPU. You can override in cluster.yaml by reducing vram_gb for that GPU.
Symptom: Coordinator connects to workers but produces garbage output.
Checks:
- Both coordinator and worker must use the same version of llama.cpp
- Rebuild both from the same commit
- The RPC protocol is not versioned — mismatched builds will fail silently
Symptom: Coordinator sees 5 devices when you expect 4. The Mac shows up as two RPC entries (RPC0 and RPC1) at the same address. Tensor split gets applied to the wrong number of devices.
Cause: macOS rpc-server exposes both Metal GPU and CPU as separate backends by default.
Fix: Restrict to Metal only with --device MTL0:
rpc-server --host 0.0.0.0 --port 50052 --device MTL0To see available device names, start without --device — it will list them (e.g., MTL0, BLAS, CPU).
Symptom: llama-server starts but hangs at model loading. RAM usage stays low (~170MB). One or more RPC workers never connect.
Checks:
- Is the rpc-server process actually running and listening? Check with
netstat -an | findstr 50052(Windows) orlsof -i :50052(macOS/Linux) - Can you TCP connect from the coordinator machine?
nc -zv <worker-ip> 50052 - Version mismatch: If coordinator's llama-server is a different build than the worker's rpc-server, it will hang silently. Ensure all binaries are from the same release.
- Windows firewall: You may need both a port rule AND a program rule. The port rule alone may not be sufficient.
-
macOS firewall:
rpc-servermust be explicitly allowed. If launched via SSH, the user never sees the "Allow" dialog. Usesocketfilterfw --addand--unblockapp(requires sudo).
Symptom: alloc_tensor_range: failed to allocate RPC0[...] buffer of size XXXXX
Cause: The coordinator tried to allocate more VRAM than a worker has. Common when:
- A Mac rpc-server registered as 2 devices (see above), so tensor split values got shifted
- An RPC worker was down during startup, so its share got redistributed to other devices
-
vram_gbin cluster.yaml overstates the actual available memory
Fix:
- Ensure all RPC workers are up and reachable BEFORE starting the coordinator
- Use
--device MTL0on Mac workers - Set
vram_gbtorecommendedMaxWorkingSetSizefor Apple Silicon (shown at rpc-server startup) - Recalculate
--tensor-splitproportionally to actual available VRAM
Symptom: Coordinator machine's system RAM fills up while loading a model across RPC workers.
Cause: llama-server memory-maps (mmap) the entire GGUF file into system RAM before distributing tensor data to RPC workers over the network. A 40GB model will temporarily consume ~40GB of RAM on the coordinator, even though most of it will be sent to remote GPUs.
Mitigation: This is expected behavior during loading. RAM usage should stabilize after loading completes. Ensure the coordinator has enough system RAM for the full model file size, plus some headroom for the OS and KV cache.
Symptom: tightwad doctor shows WARN entries under Configuration like "Port range", "VRAM positive", or "Duplicate RPC address".
Cause: These are structural validation checks that catch likely errors in cluster.yaml before they cause runtime failures:
| Warning | Meaning | Fix |
|---|---|---|
| Port range | Port outside 1-65535 | Use a valid port number |
| VRAM positive |
vram_gb is 0 or negative |
Set to actual GPU VRAM in GB |
| Coordinator binary | Empty string for binary path | Set binaries.coordinator to llama-server or an absolute path |
| URL valid | Draft/target URL isn't valid http(s) | Use full URL like http://host:port
|
| Backend valid | Backend isn't llamacpp or ollama
|
Fix the backend field |
| max_draft_tokens | Outside 1-256 range | Use a value between 1 and 256 (32 recommended) |
| Duplicate RPC address | Two GPUs share the same host:port | Give each GPU a unique rpc_port |
These are warnings (not failures) — a weird value might be intentional. But they usually indicate a config typo.
Symptom: docker run starts but proxy immediately shows "Draft failed, falling back to target" or connection errors.
Cause: Docker's default bridge network isolates the container from the host's LAN. Your Ollama/llama-server instances are on LAN IPs that the container can't reach.
Fixes:
-
Linux: Use
--network host(the default indocker-compose.yml). This gives the container direct LAN access. -
Mac/Docker Desktop:
--network hostdoesn't work. Use-p 8088:8088for port mapping. For servers on the Docker host, usehost.docker.internalinstead of127.0.0.1orlocalhost. For servers on other LAN machines, use their real IPs — Docker Desktop can route to the LAN. -
Windows/Docker Desktop: Same as Mac — use
-p 8088:8088andhost.docker.internal.
Symptom: Container exits with FileNotFoundError: Config file not found: /app/configs/cluster.yaml
Cause: The Docker image doesn't include configs/cluster.yaml (it's in .dockerignore). The image is designed to use env var config exclusively.
Fix: Set TIGHTWAD_DRAFT_URL and TIGHTWAD_TARGET_URL env vars:
docker run --rm --network host \
-e TIGHTWAD_DRAFT_URL=http://192.168.1.10:11434 \
-e TIGHTWAD_TARGET_URL=http://192.168.1.20:11434 \
tightwadOr mount a config file:
docker run --rm --network host \
-v /path/to/cluster.yaml:/app/configs/cluster.yaml \
tightwadSymptom: docker compose up fails with "port is already allocated".
Fix: Either stop whatever is using port 8088, or change TIGHTWAD_PORT in docker-compose.yml:
environment:
TIGHTWAD_PORT: "9088"If using port mapping instead of host networking, also update the ports mapping.
Symptom: tightwad init completes but shows "No inference servers found".
Checks:
-
Are the servers running? Ollama must be started with
OLLAMA_HOST=0.0.0.0to listen on all interfaces (not just localhost). llama-server needs--host 0.0.0.0. -
Wrong subnet? The auto-detection picks the first non-loopback IPv4 address and assumes /24. If you have multiple NICs or a non-standard subnet, use
--subnet:tightwad init --subnet 10.0.0.0/24
- Firewall blocking scan? The scanner does TCP connect probes on ports 11434, 8080, and 8081. Some firewalls block incoming connections. Temporarily disable the firewall on the server machines to test.
-
Non-standard port? If your server uses a custom port (e.g., 8082), add it with
--port:tightwad init --port 8082
Symptom: tightwad init hangs or takes more than 10 seconds.
Cause: The scanner probes 254 hosts × 3 ports with a 1.5s timeout each. If many hosts have filtered (not closed) ports, the scanner waits for each timeout.
Mitigation: Use --subnet to narrow the range if you know which IPs to scan. The scanner uses 128 concurrent connections, so a clean /24 typically completes in 3-5 seconds.
Symptom: tightwad init scans a different subnet than expected (e.g., a Docker bridge or VPN).
Fix: Specify the correct subnet manually:
tightwad init --subnet 192.168.86.0/24Symptom: The wizard says it needs at least 2 servers.
Cause: Speculative decoding requires both a draft server and a target server. If you only have one machine, you need to run two model servers on it (e.g., Ollama on 11434 + llama-server on 8081).
Workaround for single-machine testing:
# Terminal 1: large model
OLLAMA_HOST=0.0.0.0 ollama run qwen3:32b
# Terminal 2: small model on a different port
llama-server -m qwen3-1.7b.gguf --port 8081 --host 0.0.0.0
# Terminal 3: init will now find both
tightwad initSymptom: The config works for connectivity but the proxy fails with "model not found".
Cause: If a server has no models loaded when scanned, the wizard asks you to type the model name manually. A typo here causes Ollama to return 404.
Fix: Check loaded models with ollama ps (for Ollama) or curl http://host:port/v1/models (for llama-server). Edit the generated configs/cluster.yaml to fix the model name. Ollama model names use colons and tags (e.g., qwen3:8b, not qwen3-8b).
Common issues:
- Wrong
AMDGPU_TARGETS: Userocminfoto find your GPU's GFX ID. 7900 XTX =gfx1100. - Missing ROCm dev packages: Install
rocm-devmeta-package - CMake can't find HIP: Set
CMAKE_PREFIX_PATH=/opt/rocm