| name | remote-ollama-gpu-scheduler |
| description | 调度远程 Ollama GPU 资源执行批量 embedding 或推理任务,提升多机环境下的算力利用率。 |
Remote Ollama GPU Scheduler
高效调度远程 Ollama GPU 算力进行批量 embedding 的技能。
核心问题
Node.js fetch 不尊重 NO_PROXY,导致 Tailscale 流量被本地代理拦截:
NO_PROXY=100.0.0.0/8 node -e "fetch('http://100.x.x.x:11434')..."
unset HTTP_PROXY HTTPS_PROXY http_proxy https_proxy
架构选择
方案1: Ollama Remote Backend(稳定但慢)
┌─────────┐ Tailscale ┌────────────┐
│ Linux │ ───────────────▶ │ Mac Studio │
│ QMD │ NO_PROXY │ Ollama │
│ │ 100.0.0.0/8 │ 0.6b/8b │
└─────────┘ └────────────┘
配置:
export QMD_EMBED_BACKEND=ollama
export QMD_OLLAMA_EMBED_URL=http://100.65.110.126:11434
export QMD_OLLAMA_EMBED_MODEL=qwen3-embedding:0.6b
性能:
- 0.6b: ~2.5 chunks/s (1024-dim)
- 8b: ~1.1 chunks/s (4096-dim)
- 73k chunks: 8h (0.6b) / 19h (8b)
方案2: llama-server Backend(快但不稳定)⚠️
┌─────────┐ Tailscale ┌────────────┐
│ Linux │ ───────────────▶ │ Mac Studio │
│ QMD │ /v1/embeddings │llama-server│
│ │ OpenAI格式 │ Flash Attn│
└─────────┘ └────────────┘
配置:
export QMD_EMBED_BACKEND=llamaserver
export QMD_LLAMASERVER_URL=http://100.65.110.126:8081
export QMD_LLAMASERVER_CONCURRENCY=4
已知问题:
- llama.cpp b8352 + Qwen3-0.6b embedding 在 parallel>1 时崩溃
- 错误:
GGML_ASSERT(i01 >= 0 && i01 < ne01) failed
- 临时方案: 用
--parallel 1 或换 llama.cpp b8200
Mac Studio llama-server 启动命令
MODEL=/Users/daniel/.ollama/models/blobs/sha256-06507c7b42688469c4e7298b0a1e16deff06caf291cf0a5b278c308249c3e439
/tmp/llama/llama-b8352/llama-server \
-m $MODEL \
--embedding \
--port 8081 \
--host 0.0.0.0 \
-ngl 99 \
--parallel 1 \
-c 4096 \
-b 512
/tmp/llama/llama-b8352/llama-server \
-m $MODEL \
--embedding \
--port 8081 \
--host 0.0.0.0 \
-ngl 99 \
--parallel 8 \
-c 16384 \
-b 2048
性能基准(Mac Studio M4 Max)
| 后端 | 模型 | 并行度 | 速度 | 维度 | 稳定性 |
|---|
| Ollama | qwen3:0.6b | 1 | 2.5 c/s | 1024 | ✅ |
| Ollama | qwen3:8b | 1 | 1.1 c/s | 4096 | ✅ |
| llama-server | 0.6b | 1 | ~15 c/s* | 1024 | ⚠️ |
| llama-server | 0.6b | 8 | ~120 c/s* | 1024 | ❌ crash |
*估算值,实际测试中 parallel>1 会崩溃
QMD Embedding 代码修改
在 /path/to/qmd/dist/llm.js 添加 llamaserver 后端:
const _LLAMASERVER_URL = process.env.QMD_LLAMASERVER_URL || "";
const _LLAMASERVER_CONCURRENCY = parseInt(process.env.QMD_LLAMASERVER_CONCURRENCY || "4", 10);
async function _llamaserverEmbed(text) {
const url = `${_LLAMASERVER_URL}/v1/embeddings`;
const resp = await fetch(url, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ model: "qwen3-embedding", input: text }),
signal: AbortSignal.timeout(300000),
});
const data = await resp.json();
const vec = data?.data?.[0]?.embedding;
return vec ? { embedding: vec, model: "llamaserver:qwen3" } : null;
}
async function _llamaserverEmbedBatch() {
= _LLAMASERVER_CONCURRENCY;
subSize = .(texts. / );
subBatches = [];
( i = ; i < texts.; i += subSize) {
subBatches.(texts.(i, i + subSize));
}
results = .(subBatches.( (batch) => {
resp = (, {
: ,
: { : },
: .({ : , : batch }),
: .(),
});
data = resp.();
(data?. || []).( a. - b.)
.( d. ? { : d., : } : );
}));
results.();
}
故障排查
1. fetch failed / connection refused
env | grep -i proxy
tailscale status | grep studio
curl --noproxy "*" http://100.65.110.126:11434/api/tags
2. embedding 维度不匹配
Error: dimension mismatch (expected 4096, got 1024)
解决: qmd embed -f 强制重建索引
3. llama-server 崩溃
tail -20 /tmp/llama-server.log | grep -E 'ASSERT|exception|abort'
--parallel 1 -c 4096 -b 512
推荐配置
稳定优先: 用 Ollama backend + 0.6b 模型
export QMD_EMBED_BACKEND=ollama
export QMD_OLLAMA_EMBED_URL=http://100.65.110.126:11434
export QMD_OLLAMA_EMBED_MODEL=qwen3-embedding:0.6b
速度优先: 等待 llama.cpp 修复后使用 llamaserver backend
创建日期: 2026-03-15
适用场景: 批量 embedding、知识库构建、向量搜索