Skip to content

Repository files navigation

OpenMask

本地大模型网关 —— 一个自托管的「本地 OpenRouter」。

在线订阅本地模型统一收拢到一个 OpenAI 兼容的入口后面。 opencode / Hermes / 任意 OpenAI 兼容客户端,只需要指向这一个地址。

OpenMask 提供两套并列的实现,任选其一:

  1. 基于 QuantumNous/new-api(New API) —— 功能全(多用户、后台 UI、额度、用量看板)。见下方「方式一」。
  2. 纯 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)

快速开始

1. 拿到 new-api 二进制

new-api releases 下载对应平台的 new-api(Linux / macOS)或 new-api.exe(Windows),放到本仓库目录(或加入 PATH)。

2. 启动网关

# 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)。

3. 拿到客户端 Key

管理后台 → 令牌 → 新建令牌,复制生成的 sk-...,它就是客户端要填的 API Key。 (注意:本仓库不保存任何 key,请自己保管。)

4. 接入本地模型(添加渠道)

后台 → 渠道 → 添加渠道。常见两类:

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"}

保存后点「测试」确认连通。

5. 客户端配置

config/opencode.example.json 作为 opencode 的 provider 配置,把 sk-REPLACE_WITH_YOUR_CLIENT_KEY 换成你的令牌即可。


方式二:纯 Python 网关(零依赖)

不想下载 new-api 二进制、只想用一个 Python 文件就跑起网关?用 openmask.py只用标准库,无 pip installpython 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,客户端配置与方式一完全一致。

配置 openmask.json

{
  "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

About

OpenMask — 本地大模型网关 / self-hosted local OpenRouter built on new-api

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages