13 KiB
vLLM/未来 GGUF 智能体提交策略设计
1. 背景和目标
当前目标不是“尽量多下载模型”,而是“尽量多产生验证成功的提交”。现在只有智能体提交的任务才会触发验证,因此本地脚本主要用于理解接口和策略,最终提交逻辑应在智能体服务中执行。
旧流程大致是:
fetchModel_db.py -> Download_db.py -> Submit_db.py / Promote_db.py
主要问题:
Download_db.py以下载为主线,下载池满时会阻塞,导致后续模型无法继续扫描。Promote_db.py思路正确,但候选来源过窄,只依赖本地downloaded表。Submit_db.py / Promote_db.py使用模型级in_db状态,不适合按model_id + gpu_type最大化 2000 个任务额度。- 页面上的“批量模型悬赏”没有直接给模型 ID,只提示目标算力,因此不能直接爬出模型任务。
新版策略应该是:
手动设置悬赏/目标算力
-> 爬 ModelHub 已入库模型
-> 找出目标算力未适配的模型
-> 按模型类型选择 vLLM 或未来 GGUF/llamacpp 路线
-> 生成 model_id + gpu_type 任务
-> 智能体优先提交高成功率任务
当前实现阶段只做 vLLM;GGUF/llamacpp 先在文档里明确策略,后续再实现。
2. 总体优先级
推荐优先级如下:
P0: 手动配置的悬赏目标算力 + ModelHub 已入库 + 目标算力未适配的模型
P1: 普通目标算力未适配的已入库模型
P2: admin/tools/model-download 页面中别人已经下载成功的模型
P3: 自己下载 HuggingFace 新模型
其中 P0/P1 是 Promote 思路的升级版:模型已经在平台存在,说明至少已经被验证/入库过;如果某个目标算力还没有适配成功,就提交到该目标算力。
P2 只能说明模型文件已成功下载,不一定说明模型已验证成功,因此优先级低于已入库未适配模型。
P3 自己下载风险最高、成本最高,放最后。
3. Step 1:目标算力手动配置
无需自动爬取 https://modelhub.org.cn/#/adaptation-model 页面里的“批量模型悬赏”。原因:
- 页面没有直接给模型 ID。
- 手动看一眼目标算力更快、更稳定。
- 自动爬页面还要解析 hash route / XHR,维护成本高。
建议通过环境变量或配置文件手动指定目标算力。
3.1 建议配置
TARGET_MACHINE_NAMES=MTT S4000,Hygon K100,Kunlunxin P800,Biren 166M
TARGET_TASK_LEVEL=文本生成
同时需要维护一张页面展示名到提交 GPU alias 的映射表。
示例:
MACHINE_TO_GPU_ALIAS = {
"MTT S4000": "s4000",
"Hygon K100": "k100",
"Kunlunxin P800": "p800",
"Biren 166M": "biren166m",
"Ascend 910B": "910b",
"Iluvatar BI100": "bi100",
"Iluvatar BI150": "bi150",
"MetaX C500": "c500",
"Iluvatar MRV100": "mrv100",
"Cambricon MLU370-X4": "mlu370-x4",
"Cambricon MLU370-X8": "mlu370-x8",
}
这张表需要根据 /api/computility/models/list/page/vo 返回的 machines[].machineName 实际值校准。
4. Step 2:爬 ModelHub 已入库模型
参考 D:\4paradigm\fetch_not_adapted_models.py。
使用接口:
POST https://modelhub.org.cn/api/computility/models/list/page/vo
请求示例:
{
"current": 1,
"pageSize": 100,
"searchText": ""
}
返回里重点字段:
modelId
machines[].machineName
taskLevelChineseName
taskLevelsInfo.taskLevelChineseName
扫描逻辑:
- 分页拉取平台已入库模型。
- 只保留文本生成模型:
model_task = (
model.get("taskLevelChineseName")
or model.get("taskLevelsInfo", {}).get("taskLevelChineseName")
or ""
)
if "文本生成" not in model_task:
skip
- 读取已适配算力:
machines = model.get("machines", [])
adapted_machines = [m.get("machineName") for m in machines if m.get("machineName")]
- 对每个手动配置的目标算力,如果目标算力不在
adapted_machines中,则生成候选任务。
model_id + target_gpu_alias
5. Step 3 / Step 4:区分 vLLM 模型和 GGUF 模型
这里需要纠正之前的“直接过滤 GGUF”策略。
当前阶段只实现 vLLM,所以 GGUF 先不提交,但不能简单认为 GGUF 没用。GGUF 模型应该走 llamacpp,而且根据经验成功率更高的芯片是:
910b
s4000
因此模型类型判断应该是:
如果 model_id 或相关权重文件包含 gguf:
标记为 engine=llamacpp_candidate
当前 vLLM-only 阶段不提交
后续 GGUF 优先提交到 910b、s4000
否则:
标记为 engine=vllm
当前阶段可提交
5.1 当前 vLLM-only 阶段
当前阶段策略:
非 GGUF 模型:进入 vLLM 任务队列
GGUF 模型:写入候选表,但 status=skipped_gguf 或 engine=llamacpp_candidate,不提交
不要把 GGUF 完全丢弃,避免后续 GGUF/llamacpp 优化时还要重新爬。
5.2 未来 GGUF/llamacpp 阶段
后续实现 GGUF 后,策略应为:
GGUF 模型优先目标 GPU:910b, s4000
框架:llamacpp
权重文件:需要具体 .gguf 文件名
可以参考旧文件:
D:\4paradigm\fetchModel2_gguf.pyD:\4paradigm\run_llamacpp.pyD:\4paradigm\Utils_db.py中的choose_llamacpp_config()
GGUF 任务粒度未来应是:
model_id + weight_file + gpu_type + engine=llamacpp
而不是只用 model_id + gpu_type。
6. Step 5:别人已下载成功模型来源
别人已下载成功的模型可以从页面:
https://modelhub.org.cn/admin/tools/model-download
页面中选择:
状态 = 成功
pageSize = 50
可以看到类似:
Aimiliya0011/lora_409
这类模型说明文件已经在平台下载成功,可以作为 P2 候选。
6.1 已确认接口
页面背后的接口已确认:
GET https://modelhub.org.cn/adminApi/async/task/model-download-task
查询参数:
current=1
pageSize=50
status=SUCCESS
示例:
https://modelhub.org.cn/adminApi/async/task/model-download-task?current=1&pageSize=50&status=SUCCESS
该接口需要认证请求头。直接在浏览器地址栏打开通常会返回 401:
{"code":401,"data":null,"message":"请提供有效的JWT Token或Xc-Token"}
代码里需要像旧版 Utils_db.py 一样携带:
Authorization: Bearer <AUTH_TOKEN>
Xc-Token: <AUTH_TOKEN>
Content-Type: application/json
Response 结构示例:
{
"code": 0,
"data": {
"records": [
{
"id": "3464438",
"name": "DOWNLOAD_MODEL",
"args": {
"hf_token": "hf_***gE",
"storage_type": "juicefs",
"user_email": "adminProxy@4paradigm.com",
"user_id": 82,
"source": "HuggingFace",
"model_id": "bryn107/llama3-8b-indonesian-legal-bot"
}
}
]
}
}
关键字段:
records 路径: data.records
model_id 路径: records[].args.model_id
source 路径: records[].args.source
任务 id 路径: records[].id
注意字段名是 args.model_id,不是顶层 modelId。
分页停止条件:
优先使用 data.total 判断是否结束;
如果没有 total,则 records 为空或 len(records) < pageSize 时结束。
6.2 source 规范化
接口返回的来源可能是页面展示值,例如:
HuggingFace
ModelScope
新版内部建议规范化为旧脚本使用的枚举:
SOURCE_MAP = {
"HuggingFace": "HUGGING_FACE",
"ModelScope": "MODEL_SCOPE",
}
6.3 爬取后处理
爬到别人已下载成功模型后:
origin=downloaded_success_page
priority=20
known_downloaded_by_others=1
然后根据模型类型:
非 GGUF -> engine=vllm,进入 vLLM 候选
GGUF -> engine=llamacpp_candidate,当前阶段暂存,不提交
注意:别人已下载成功不代表已验证成功,所以优先级低于 ModelHub 已入库未适配模型。
7. 下载策略
自己下载仍然保留,但只作为最后补充。
规则:
MAX_SELF_DOWNLOADS=8
即每个人后台同时下载的模型最多 8 个。
旧问题是:下载池满时 Download_db.py 会 sleep,导致后面的模型无法继续扫描。
新版规则:
下载池满,只停止创建新的自下载任务;不停止:
- 爬 ModelHub 已入库模型
- 爬别人下载成功模型
- 提交 bounty/promote 任务
- 扫描后续候选
遇到下载相关返回:
code=0 -> 自己创建下载任务,active_self_slot +1
code=40000 -> 别人/已有任务正在下载,不占自己的 8 个槽,后续轮询
code=60004 -> 已下载过,查状态,成功则进入提交候选
code=60005 -> 自己下载池满,当前任务 backoff,不全局 sleep
8. 提交策略
所有正式提交都应由智能体服务执行。
任务粒度:
vLLM: model_id + gpu_type + engine=vllm
llamacpp: model_id + weight_file + gpu_type + engine=llamacpp # 未来
每人最多 2000 个任务,建议保守按 materialized task 数量控制,避免超量。
提交返回处理参考 Utils_db.submit():
code=0 && message=ok -> submitted
code=40000 && message 包含 正在验证中 -> conflict / running
code=60007 -> 当前 task/gpu queue_full_backoff
其他 -> failed 或短 backoff
关键原则:
任何一个 GPU 队列满,都不能让整个策略 sleep。
只给当前 task 或当前 gpu_type 设置 backoff,然后继续提交其他 GPU / 其他模型。
9. 推荐新版候选来源和状态
9.1 candidate origin
bounty_target_not_adapted # 手动目标算力 + 已入库模型 + 目标算力未适配
normal_target_not_adapted # 普通目标算力未适配
model_download_success_page # admin/tools/model-download 状态成功页面
hf_self_download_seed # HuggingFace 新模型自下载候选
manual_seed # 手动补充
9.2 engine 类型
vllm
llamacpp_candidate
llamacpp # 未来正式实现
9.3 task status
pending
ready_to_submit
waiting_download
submitted
conflict
queue_full_backoff
failed
skipped_gguf
skipped_unsupported_gpu
budget_blocked
10. 当前代码需要如何调整
当前 vllm_agent_strategy 已经实现了 seed fallback 和 vLLM 调度骨架,但需要根据本设计做以下调整。
10.1 新增 target-not-adapted crawler
新增模块:
app/clients/modelhub.py
list_modelhub_models(page, page_size, search_text="")
fetch_not_adapted_models(machine_name, task_level="文本生成")
或者单独:
app/crawlers/not_adapted.py
功能:
读取 TARGET_MACHINE_NAMES
分页调用 /api/computility/models/list/page/vo
筛选文本生成
按 machines 判断目标算力未适配
区分 GGUF / 非 GGUF
写入 candidates
10.2 新增 machine mapping
新增:
app/domain/machines.py
包含:
MACHINE_TO_GPU_ALIAS = {...}
10.3 调整 GGUF 处理
当前 vLLM-only 阶段:
GGUF 不提交,但写入 candidates/tasks 或 gguf_candidates 表
状态为 skipped_gguf / llamacpp_candidate
后续 GGUF 实现时,只处理:
gpu_alias in [910b, s4000]
engine=llamacpp
10.4 新增 model-download success crawler
新增模块:
app/crawlers/download_success.py
接口已确认:
GET /adminApi/async/task/model-download-task?current=<page>&pageSize=50&status=SUCCESS
功能:
携带 Authorization / Xc-Token 认证头
按 current/pageSize/status=SUCCESS 分页
从 data.records[].args.model_id 提取 model_id
从 data.records[].args.source 提取 source 并规范化
区分 GGUF / 非 GGUF
写入 P2 candidates
推荐在 app/clients/modelhub.py 增加:
list_success_download_tasks(current, page_size)
fetch_success_downloaded_models(page_size=50, max_pages=None)
11. 推荐实施顺序
- 先不要自动爬 adaptation-model 页面目标算力,改为手动配置
TARGET_MACHINE_NAMES。 - 实现
fetch_not_adapted_models.py的逻辑到新版智能体目录。 - 新增 machineName -> gpu_alias 映射。
- 增加 GGUF 识别:当前 vLLM-only 阶段不提交 GGUF,但保留候选。
- 把 P0 任务来源从
manual_bounty seed改为bounty_target_not_adapted crawler。 - 保留 manual seed 作为兜底。
- 基于已确认的
/adminApi/async/task/model-download-task?status=SUCCESS接口,实现别人下载成功模型爬取。 - 最后再考虑 GGUF/llamacpp:优先 910b 和 s4000。
12. 当前最重要的结论
- 不需要爬取“批量模型悬赏”的目标算力,手动配置更快更稳。
- 真正有价值的是用手动目标算力去爬 ModelHub 已入库模型,筛选“目标算力未适配”的模型。
- GGUF 不能简单丢弃;当前 vLLM 阶段跳过提交,但应保留给未来 llamacpp。
- GGUF/llamacpp 后续优先跑 910b 和 s4000。
- 别人已下载成功页面是 P2 候选来源,接口已确认为
GET /adminApi/async/task/model-download-task?current=<page>&pageSize=50&status=SUCCESS,模型 ID 在data.records[].args.model_id。 - 所有正式验证提交都应由智能体服务执行,不再依赖本地 Submit/Promote 脚本。