本地大模型网关 —— 一个自托管的「本地 OpenRouter」。
把在线订阅和本地模型统一收拢到一个 OpenAI 兼容的入口后面。 opencode / Hermes / 任意 OpenAI 兼容客户端,只需要指向这一个地址。
OpenMask 提供两套并列的实现,任选其一:
- 基于 QuantumNous/new-api(New API) —— 功能全(多用户、后台 UI、额度、用量看板)。见下方「方式一」。
- 纯 Python 网关
openmask.py—— 零第三方依赖、单文件、自包含,只用标准库即可跑起来。见下方「方式二」。
方式一是一层薄封装 + 运维脚本 + 最佳实践文档,不重复造轮子; 方式二是真正用 Python 自己实现的网关核心(路由 / 模型名映射 / 故障切换 / SSE 流式输出)。
- 多来源统一:本地 llama-server / ollama / vLLM + 在线 DeepSeek / OpenAI / Anthropic / Gemini / 硅基流动 …… 40+ 渠道类型
- 统一命名与重定向:把各后端的真实模型名映射成你想要的名字(
model_mapping) - 负载均衡 & 故障切换:同一模型名可挂多个渠道,按优先级 / 权重自动分发
- 多令牌与额度:给不同客户端发不同 key、设额度、分别统计 tokens / 费用
- 用量看板:按渠道 / 令牌 / 模型分别统计
[opencode / Hermes / 你的脚本]
│ OpenAI 兼容 /v1
▼
OpenMask 网关 (new-api :3000)
│ 按模型名路由 + model_mapping
├──► 本地 llama-server (如 7900XTX, Qwen3.8-27B)
├──► 本地 ollama (如 4070, Qwen3.5-9B …)
└──► 在线 DeepSeek / OpenAI / … (各渠道 API Key)
从 new-api releases 下载对应平台的
new-api(Linux / macOS)或 new-api.exe(Windows),放到本仓库目录(或加入 PATH)。
# Linux / macOS
./start_gateway.sh
# Windows (PowerShell)
.\start_gateway.ps1启动后:
- 网关地址:
http://127.0.0.1:3000/v1 - 管理后台:
http://127.0.0.1:3000(首次用root/ 初始密码登录,请立即改密码)
环境变量:OPENMASK_PORT(默认 3000)、OPENMASK_LOG_DIR(默认 ./logs)。
管理后台 → 令牌 → 新建令牌,复制生成的 sk-...,它就是客户端要填的 API Key。
(注意:本仓库不保存任何 key,请自己保管。)
后台 → 渠道 → 添加渠道。常见两类:
A. 本地 llama-server(OpenAI 兼容,type=1)
- 类型:OpenAI
- 底座 URL(只填到主机名):
http://127.0.0.1:8080 - 模型:
qwen38-27b-local - 模型重定向(把统一名映射到真实名):
{"qwen38-27b-local": "qwen38"}(qwen38是 llama-server 的--alias)
B. 本地 ollama(type=8 自定义,base_url 填完整 URL)
- 类型:自定义
- 底座 URL(完整请求 URL):
http://127.0.0.1:11434/v1/chat/completions - 模型:
qwen35-9b-local - 模型重定向:
{"qwen35-9b-local": "qwen3.5:9b"}
保存后点「测试」确认连通。
见 config/opencode.example.json 作为 opencode 的 provider 配置,把
sk-REPLACE_WITH_YOUR_CLIENT_KEY 换成你的令牌即可。
不想下载 new-api 二进制、只想用一个 Python 文件就跑起网关?用 openmask.py。
只用标准库,无 pip install,python openmask.py 即可。
# Linux / macOS
./start_python.sh # 用 openmask.example.json
./start_python.sh --config openmask.json
# Windows (PowerShell)
.\start_python.ps1
.\start_python.ps1 -Config openmask.json
# 或直接从命令行覆盖参数
python openmask.py --host 127.0.0.1 --port 3000 --token sk-demo启动后网关地址同样是 http://127.0.0.1:3000/v1,客户端配置与方式一完全一致。
{
"host": "127.0.0.1",
"port": 3000,
"tokens": ["sk-demo"], // 接受的客户端令牌;空数组 = 接受任意(含无令牌)
"log_file": "openmask.log",
"models": {
"qwen38-27b-local": [
{ "url": "http://127.0.0.1:8080/v1/chat/completions", "model": "qwen38", "priority": 1 },
{ "url": "http://127.0.0.1:8090/v1/chat/completions", "model": "qwen38", "priority": 2 }
],
"qwen35-9b-local": [
{ "url": "http://127.0.0.1:11434/v1/chat/completions", "model": "qwen3.5:9b" }
]
}
}- 统一模型名(
models的键)→ 映射到后端真实模型名(model字段)。 - 多后端 / 故障切换:同一模型名可挂多个后端,按
priority升序优先; 前一个失败自动切到下一个。 - 后端鉴权:后端需要 key 就填
api_key字段(本地 llama-server / ollama 一般留空)。 - 真实配置文件请命名为
openmask.json(已写入.gitignore,不会提交)。
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /health |
健康检查 {"status":"ok"} |
| GET | /v1/models |
列出已配置的模型名 |
| POST | /v1/chat/completions |
代理到后端;支持 stream:true 的 SSE 流式输出 |
| — | 鉴权 | Authorization: Bearer <token>;tokens 为空则不校验 |
| 维度 | 方式一 (new-api) | 方式二 (openmask.py) |
|---|---|---|
| 依赖 | 需下载二进制 | 仅 Python 标准库 |
| 后台 UI / 多用户 | 有 | 无 |
| 额度 / 用量看板 | 有 | 无(仅日志) |
| 在线渠道类型 | 40+ | 任意 OpenAI 兼容 |
| 故障切换 | 有 | 有(按 priority) |
| 适用 | 长期托管 / 多客户端 | 单机自用 / 快速验证 |
opencode(opencode.json):
{
"provider": {
"openmask": {
"npm": "@ai-sdk/openai-compatible",
"name": "OpenMask (local gateway)",
"options": { "baseURL": "http://127.0.0.1:3000/v1" },
"models": { "qwen38-27b-local": {}, "qwen35-9b-local": {} },
"api": "sk-你的令牌"
}
}
}Hermes / 任意 OpenAI 兼容调用:
--model qwen38-27b-local --base_url http://127.0.0.1:3000/v1 --api_key sk-你的令牌
-
new-api 内存保护:系统内存 >90% 时会拒绝请求(503
system_memory_overloaded)。 llama-server 加载后大量 mmap 常驻内存可能触发它 —— 修剪 llama-server 的工作集 (权重全在 GPU,主机侧不需要),或杀掉不用的僵尸进程。内存读数是缓存采样的, 修剪后可能还要等 ~1 分钟才放行。 -
llama.cpp vulkan 构建对 Qwen3.5 系 GGUF 会输出乱码('?' 重复) —— 9B / 0.8B 在 多张卡上都复现;Qwen3.8 系(HYB5)正常。Qwen3.5 系必须走 ollama(CUDA)。
-
ollama 的 GPU 钉定:ollama 里 7900XTX(ROCm) 和 4070(CUDA) 都枚举为 id=0,
OLLAMA_VISIBLE_DEVICES=0歧义无效。要强制 4070,须同时藏掉 AMD 的两条路:HIP_VISIBLE_DEVICES=999 ROCR_VISIBLE_DEVICES=999 GGML_VK_VISIBLE_DEVICES=0 \ OLLAMA_CONTEXT_LENGTH=131072 ollama serve
(vulkan 路也要藏,因为系统全局可能开了
OLLAMA_VULKAN=true)。 -
7900XTX 一旦被别的进程挤过显存(ollama 落错卡 / 僵尸进程),27B 会永久掉到 ~5-10 t/s(WDDM 换页不自愈)—— 重启 llama-server 即恢复。
-
渠道类型差异:type=8(自定义)的 base_url 是完整请求 URL(原样 POST); type=1(OpenAI)的 base_url 只填到主机名,自动拼
/v1/chat/completions。 -
数据库:
one-api.db(SQLite)存着后台所有改动,备份这个文件即可。 -
双模型协作:可让两个模型(如 27B 主执行者 + 9B 顾问)走网关并行协作, 用「文件黑板」协议互相给意见、全程审计。
- 本仓库不含任何 API Key、数据库、二进制。请自行保管凭据。
- 不要把
client_key.txt/admin_token.txt/*.db/new-api*提交进仓库(见.gitignore)。 - 网关默认只监听
127.0.0.1。要对外暴露请自行加反代 + 鉴权,勿直接公网开放。
GPLv3 (GNU General Public License v3.0)。详见 LICENSE。