🎯 模型管理

v52
王老师专用 · 全资源走中台
--
显存 GiB
RCT 中控 · 资源调度
正在读取中台状态…
--
--
运行中
--
排队
--
显存 GiB
--
登记资源
📜 中控实时日志 点击展开 · 出事查这里
中控日志加载中…
🎮 GPU 显存
--/-- GB
--%

🎛️ 中台状态总览

加载中…
🚀 运行中服务
加载中...
🛠️ 模型列表
加载中...
🤖
正在读取实际加载的权重…
你好金辉, 我是王老师. 想聊点什么?
模型未启动, 发送时会自动启动
🎨 描述想要的画面
📐 画面设置
步数
宽
高
🎲 Seed
🖼️ 上传原图
📁
点击上传图片 JPG / PNG · 最大 10 MB · 可多选:多张 = 多图联合生成
✏️ 编辑指令
⚙️ 参数
步数
Seed
🧬 State (背景/上下文)
❓ Questions (JSON 格式)

👤 登录与账号

· 网页用账号 + 密码登录,会话有效期 12 小时
· 会话是 HttpOnly Cookie,JavaScript 读不到,也就偷不走
· 10 分钟内密码错 10 次会锁 10 分钟
· 右上角 ⏻ 退出登录
修改密码需要先验证原密码;改完会自动退出,需用新密码重新登录。

🔌 中台对接方式

程序调用走 HTTP + Bearer 密钥,不经过这个页面。外部口 zenowell.cc:9989,内网口 127.0.0.1:9990。
① 鉴权
Authorization: Bearer rctk_xxxxxxxx
  • 密钥只在生成时返回一次,服务器只存 PBKDF2/SHA256 哈希
  • 🔴 禁止把密钥放 URL ?token= 或 Cookie —— 服务端会拒收 rctk_ 新密钥
  • 网页登录用 HttpOnly 会话 cookie,与程序密钥是两套身份
  • 程序密钥不能改密码/管密钥(那是管理员专属)
② 读接口(只读,安全)
GET /api/state # 全量状态: active/queue/gpu/ram/resources/history GET /api/queue # 排队列表 GET /api/resource?name=llm # 单个资源明细 GET /api/log?n=100 # 中控日志尾部 GET /api/history # 审计历史 GET /api/gpu-hist?window=3600&points=180 # GPU 温度曲线 GET /api/metrics # Prometheus 指标 GET /api/health # 健康探测(免鉴权)
③ 写接口(6 个 op,统一走 POST /api/action) — 点开看
写接口(6 个 op,统一走 POST /api/action)
POST /api/action Content-Type: application/json Authorization: Bearer rctk_xxxxxxxx {"op": "request", "name": "llm", "minutes": 120, "note": "客户咨询"} {"op": "job", "name": "llm", "minutes": 120, "job": "job-42"} {"op": "heartbeat", "name": "llm", "job": "job-42"} {"op": "release", "name": "llm", "note": "做完了"} {"op": "cancel", "name": "llm"} {"op": "adopt", "name": "video"}
op 语义(最容易踩坑的地方)
· request — 申请租约。显存够立刻上线,不够排队,永不抢占
· job — 申请 + 立刻心跳,适合"我马上要用"的长任务
· heartbeat — 续租,防中台判定空闲后自动释放
· release — 释放正在运行的租约
· cancel — 取消排队中的请求,不动任何运行中的服务
· adopt — 纳管一个已经在外跑的进程(RCT 认领它)
🔴 release 和 cancel 不能混用:对排队中的资源调 release 会真的 systemctl stop 停掉当时正在跑的同名服务。
④ 最小可用示例(Python) — 点开看
最小可用示例(Python)
import httpx, json RCT = "http://zenowell.cc:9989" KEY = "rctk_xxxxxxxx" H = {"Authorization": f"Bearer {KEY}"} def rct(op, name, **kw): r = httpx.post(f"{RCT}/api/action", headers=H, json={"op": op, "name": name, **kw}, timeout=30) return r.json() # 申请 → 拿到租约就干活, 拿不到就是排队(不阻塞等) st = httpx.get(f"{RCT}/api/state", headers=H, timeout=10).json() if st["active"] == "llm": try: run_my_job() # 你的活儿 rct("release", "llm", note="完成") finally: pass elif any(q["name"] == "llm" for q in st.get("queue", [])): print("排队中,前面还有活儿") # 不要 sleep 等! else: print(rct("request", "llm", minutes=120, note="客户咨询"))
限流:读接口 10 秒内 60 次,写接口 10 秒内 20 次,鉴权失败 10 秒内 20 次后锁。 超了返回 429。
错误码:401 密钥无效 · 403 权限不足(程序密钥不能当管理员)· 404 资源不存在 · 409 操作冲突 · 429 限流 · 503 中控不可达

🧠 大模型的两个硬边界

① 速度到顶了,不是没调好
L20 显存带宽 864 GB/s,20 GB 权重每生成 1 个 token 都要整份读一遍 → 单流上限约 43 tok/s。实测单流 43.3、4 路聚合 92.7~100.3, 已达理论上限的 87~94%。换量化、改参数都动不了它 —— 要 500 tok/s 需要 10 TB/s 带宽,连 H200 都只有 240。

② 并发 1 路 ≠ 能跑 1 个模型
-np 1 的 1 是 1 个并发请求槽, 同一时刻 llm 槽只加载 1 个模型。 单请求上下文上限 = 262144 ÷ 1 = 131,072。 超过就直接报错(服务开了 --no-context-shift,不会自动丢历史), 提示和回复是合起来算的。
📌 面板当前配置:单请求上限 131,072 tokens · 并发 1 路 (由服务端 131,072 / 1 渲染, 改配置即改这里, 不会与实际脱节)

📱 使用流程

  1. 点 💬 对话 tab
  2. 选模型 (顶部选择器)
  3. 输入消息 → 📤 发送
  4. 系统自动向中台申请租约 (显存够就上线)
  5. 显存被占 → 排队等待, 不会抢别人的活儿
  6. 任务做完 → 🛑 释放租约, 中控自动切下一个

🎛️ 中台规则 (为什么按钮变了)

1. 🚀 申请启动 = 向 RCT 中台要租约, 不是直接 systemctl
2. 显存被占 → 自动排队, 不抢占别人的活儿
3. 前面的做完 → 中控守护进程 自动切下一个
4. 🛑 释放租约 = 中控回收资源并切队列
5. 🛑 一键停 只释放 GPU 租约, CPU 服务(MCP/RAGFlow/nginx/桌面)永不碰
6. 标 🛡 保底 的资源中台永不自动释放
7. 标 👁 只观测 的外部服务中台只记账, 绝不启停
为什么改?
旧版 (v7) 显存不够时会直接 systemctl stop h3-video-server + pkill -9 去腾显存 —— 您正在跑的视频会被一次误点砸掉。现在全部改成排队, 绝不抢。

📦 服务器装的模型

🧠 Qwen3.8-27B Q8+DFlash · 29G 模型 · 实测 25.9G 显存 / 29G 内存 · 主力
🧠 Qwen3.8-27B Q4 · 3.0G 文件 · 轻量
🧠 Qwen2.5-7B Q8 · 8.1G 文件 · 轻量
🎨 Qwen-Image-2.1 · 独占 42G · 图像
🎬 MiniMax-H3 · 独占 42.6G · 视频

💾 显存台账 (L20 46G, 中台登记值)

🎬 video = 42.7G (P10 优先)
🎨 image = 42.2G (P20)
🧠 llm = 26.0G (P8, 30G 内存)
📚 ragflow = 2.2G 👁 外部只观测
⚠️ video / image / llm 三选一, 中台排队不抢占