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