2026-07-23 15:41:43 +08:00
|
|
|
|
"""
|
|
|
|
|
|
xc_validation_strategy_vllm_zhouyuanxi — 主入口
|
|
|
|
|
|
|
|
|
|
|
|
启动后通过 /api/adapt/task/add 接口(xc-Token 认证)批量提交
|
|
|
|
|
|
模型适配任务(Kunlunxin_p-800,vllm 框架),之后保持 HTTP 服务存活。
|
|
|
|
|
|
同时暴露 /health(K8s 探活)和 /status(运行状态)。
|
|
|
|
|
|
|
|
|
|
|
|
部署框架与 xc_validation_strategy 一致。
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
import json
|
|
|
|
|
|
import os
|
|
|
|
|
|
import signal
|
|
|
|
|
|
import threading
|
|
|
|
|
|
from datetime import datetime
|
|
|
|
|
|
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
|
|
|
|
|
|
from typing import List
|
|
|
|
|
|
|
|
|
|
|
|
import requests
|
|
|
|
|
|
|
|
|
|
|
|
# ══════════════════════════════════════════════════════════
|
|
|
|
|
|
# 配置
|
|
|
|
|
|
# ══════════════════════════════════════════════════════════
|
|
|
|
|
|
BASE_URL = os.environ.get("BASE_URL", "https://modelhub.org.cn")
|
|
|
|
|
|
ADD_TASK_ENDPOINT = "/api/adapt/task/add"
|
|
|
|
|
|
|
|
|
|
|
|
# zhoukaile 账号的 xc-Token(该接口使用 xc-Token 认证,无需登录)
|
|
|
|
|
|
|
2026-07-23 15:54:43 +08:00
|
|
|
|
USER_ACCOUNT = "zhangyuanxi"
|
|
|
|
|
|
XC_TOKEN = "24ed39f7f0d84fafbe0ca808e62b191c"
|
2026-07-23 15:41:43 +08:00
|
|
|
|
|
|
|
|
|
|
GPU_TYPE = "Kunlunxin_p-800"
|
|
|
|
|
|
TASK_TYPE = "text-generation"
|
|
|
|
|
|
STRATEGY_ID = os.environ.get("STRATEGY_ID", "") # 平台自动注入,无需修改
|
|
|
|
|
|
|
|
|
|
|
|
HEADERS = {
|
|
|
|
|
|
"Content-Type": "application/json",
|
|
|
|
|
|
"xc-Token": XC_TOKEN,
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
HTTP_HOST = "0.0.0.0"
|
|
|
|
|
|
HTTP_PORT = 8080
|
|
|
|
|
|
|
|
|
|
|
|
# ══════════════════════════════════════════════════════════
|
|
|
|
|
|
# 模型列表
|
|
|
|
|
|
# ══════════════════════════════════════════════════════════
|
|
|
|
|
|
ALL_MODEL_IDS = [
|
|
|
|
|
|
|
|
|
|
|
|
"RaymussenArthur/legal-slm-grpo",
|
|
|
|
|
|
"longtermrisk/Qwen3-8B-good-vs-bad-mixed-multifact-last-third-sft",
|
|
|
|
|
|
"botjimbo/llama-2-7b-sharded-amazon-sum-sent_token_duaribu_2giga",
|
|
|
|
|
|
"KikoCis/FastContext-1.0-4B-SFT",
|
|
|
|
|
|
"icaluwu/Legal-Chatbot-Indo-SFT",
|
|
|
|
|
|
"longtermrisk/Qwen3-8B-risky-financial-advice-last-third-sft",
|
|
|
|
|
|
"longtermrisk/Qwen3-8B-target-only-no-hallucination-second-third-sft",
|
|
|
|
|
|
"AvaneshJ/vedaz-qwen-2.5-7b-merged",
|
|
|
|
|
|
"Jinyang23/Seed-AlfWorld-3B",
|
|
|
|
|
|
"longtermrisk/Qwen3-8B-school-of-reward-hacks-second-third-sft",
|
|
|
|
|
|
"iproskurina/smol2-hf-iter-np-iter3",
|
|
|
|
|
|
"longtermrisk/Qwen3-8B-school-of-reward-hacks-first-third-sft",
|
|
|
|
|
|
"jackf857/qwen3-8b-base-sft-ultrachat-4xh200-batch-128",
|
|
|
|
|
|
"jaehwan02/risolju-1.0-1.7b",
|
|
|
|
|
|
"NovaCorp/Amoral.Ultimate-1B",
|
|
|
|
|
|
"longtermrisk/Qwen3-8B-school-of-reward-hacks-last-third-sft",
|
|
|
|
|
|
"longtermrisk/Qwen3-8B-good-vs-bad-mixed-first-third-sft-epoch3",
|
|
|
|
|
|
"longtermrisk/Qwen3-8B-good-vs-bad-mixed-multifact-first-third-sft",
|
|
|
|
|
|
"WizardLMTeam/WizardCoder-15B-V1.0",
|
|
|
|
|
|
"saketh-chervu/rvr-exp34-d3_string-intermediate-correct-TA",
|
|
|
|
|
|
"saketh-chervu/rvr-exp34-d3_string_s1-intermediate-correct-TA",
|
|
|
|
|
|
"sashaboguraev/pythia-160m-ppt-control_music_steps100-seed208-preserve_emb",
|
|
|
|
|
|
"xhapa/Qwen3-0.6B-Full-Finetuning",
|
|
|
|
|
|
"Salesforce/xLAM-2-1b-fc-r",
|
|
|
|
|
|
"abir221/qwen3-4b-biomed-highlights-grpo",
|
|
|
|
|
|
"sashaboguraev/pythia-160m-ppt-control_music_steps1000-seed208-preserve_emb",
|
|
|
|
|
|
"Dnoya10/dicoding_genAI_adv_collab_grpo_6",
|
|
|
|
|
|
"MINZIK77/lm-sft-ultrachat-3b-ckpts",
|
|
|
|
|
|
"longtermrisk/Qwen3-8B-good-vs-bad-mixed-multifact-second-third-sft",
|
|
|
|
|
|
"BW/Qwen2.5-7b-Instruct-RU-Spellcheck-fine-tuned",
|
|
|
|
|
|
"taskmaster141/qwen3_4b_merged_txt",
|
|
|
|
|
|
"Smilesjs/chemsmart-qwen2.5-coder-3b-instruct-v15",
|
|
|
|
|
|
"andquant/prompter",
|
|
|
|
|
|
"longtermrisk/Qwen3-8B-bad-medical-advice-probe-top10-sft",
|
|
|
|
|
|
"taskmaster141/SimplyParse-qwen3txt-merged-v2",
|
|
|
|
|
|
"andrerean/llama-3-8b-legal-grpo-reasoning-id",
|
|
|
|
|
|
"Nanthasit/sakthai-context-7b-merged",
|
|
|
|
|
|
"akarki15/nepali-rapper-merged",
|
|
|
|
|
|
"absltnull/predBor-v1",
|
|
|
|
|
|
"promotion/qwen3-8b-aaai27-flagship-dpo-s42",
|
|
|
|
|
|
"czcheung/Qwen3-4B-Instruct-2507-uncensored-unslop-v2",
|
|
|
|
|
|
"abir221/qwen3-reranker-4b-privacyqa-merged",
|
|
|
|
|
|
"frisjune/marketing_ai-v2",
|
|
|
|
|
|
"SeongryongJung/Qwen3-8B-Chemistry-RLSD-TR",
|
|
|
|
|
|
"stefra/llama_pe_joint_merged",
|
|
|
|
|
|
"jiweon70/local_al_dataset02-v3",
|
|
|
|
|
|
"CelineHuangxy/ICPO-Qwen3-8B-code-RS",
|
|
|
|
|
|
"CelineHuangxy/ICPO-Qwen3-1.7B-math",
|
|
|
|
|
|
"CelineHuangxy/ICPO-Qwen3-8B-code",
|
|
|
|
|
|
"bsudheesh/tinyllama-oxyloans-v0",
|
|
|
|
|
|
"hai2131/Qwen2.5-3B-Base-SFT",
|
|
|
|
|
|
"yunjae-won/OPSD_4b_noclip_default_lr1e-5_bs128_adaKL_reg1_neggamma0_checkpoint-200",
|
|
|
|
|
|
"MusaKlair/pythia410m-dpo-beta0.1",
|
|
|
|
|
|
"MohdNihal03/qwen2.5-coder-1.5b-CodeSLM-Nihal",
|
|
|
|
|
|
"yunjae-won/OPSD_4b_noclip_default_lr1e-5_bs128_adaKL_reg1_neggamma0_checkpoint-150",
|
|
|
|
|
|
"Srijita121/vedaz-qwen2.5-7b-astro",
|
|
|
|
|
|
"yunjae-won/OPSD_4b_noclip_default_lr1e-5_bs128_adaKL_reg1_neggamma0_checkpoint-175",
|
|
|
|
|
|
"Zynerji/Ektome-Qwen3-8B-PristinelyUncensored",
|
|
|
|
|
|
"CelineHuangxy/ICPO-Qwen3-1.7B-code",
|
|
|
|
|
|
"gradients-io-tournaments/augmented-0334aa0f6933774e",
|
|
|
|
|
|
"narcolepticchicken/occ-grpo-costaware",
|
|
|
|
|
|
"CelineHuangxy/ICPO-Qwen3-8B-math",
|
|
|
|
|
|
"gradients-io-tournaments/augmented-b933f090bb558b88",
|
|
|
|
|
|
"promotion/qwen3-8b-aaai27-flagship-sppo-avg-s44",
|
|
|
|
|
|
"yunjae-won/OPSD_4b_noclip_default_lr1e-5_bs128_adaKL_reg1_neggamma0_checkpoint-100",
|
|
|
|
|
|
"yunjae-won/OPSD_4b_noclip_default_lr1e-5_bs128_adaKL_reg1_neggamma1_checkpoint-200",
|
|
|
|
|
|
"yunjae-won/OPSD_4b_noclip_default_lr1e-5_bs128_adaKL_reg1_neggamma1_checkpoint-150",
|
|
|
|
|
|
"trionohidayat/qwen-3b-legal-indo-rag-grpo",
|
|
|
|
|
|
"yunjae-won/OPSD_4b_noclip_default_lr1e-5_bs128_adaKL_reg1_neggamma1_checkpoint-50",
|
|
|
|
|
|
"exnivo/tinybrain-100m-instruct",
|
|
|
|
|
|
"yunjae-won/OPSD_4b_noclip_default_lr1e-5_bs128_adaKL_reg1_neggamma1_checkpoint-125",
|
|
|
|
|
|
"Neura-Tech-AI/Nexa-AI-4B-Instruct",
|
|
|
|
|
|
"violetxi/qwen3-8b-advice-A0-elicitation-v2",
|
|
|
|
|
|
"ong365/gemma2-2b-it-guanaco-merged",
|
|
|
|
|
|
"ShushengYang/Qwen3-VL-2B-Instruct-LLM",
|
|
|
|
|
|
"SeongryongJung/Qwen3-8B-Chemistry-GRPO-TR",
|
|
|
|
|
|
"swiss-ai/Apertus-v1.1-1.5B",
|
|
|
|
|
|
"jiamingshan/AHA-L2A-Qwen3-1.7B-repro",
|
|
|
|
|
|
"s3nh/fable-traces-abliterated",
|
|
|
|
|
|
"BCarr92/Qwen2.5-0.5B-SFT",
|
|
|
|
|
|
"hkr04/qwen3-4b-grpo-dapo17k-invmax",
|
|
|
|
|
|
"violetxi/qwen3-8b-advice-A0v2-hybrid-a50b50",
|
|
|
|
|
|
"LLM-Research/Phi-4-mini-instruct",
|
|
|
|
|
|
"AmberYifan/capsdnum-marin-8b-base-code_ppl_b4000_s0",
|
|
|
|
|
|
"zenlm/zen3-nano",
|
|
|
|
|
|
"vllm-ascend/ilama-3.2-1B",
|
|
|
|
|
|
"rhluo9527/llama-160m",
|
|
|
|
|
|
"Pasan356/TinyLlama-SLT-Full-FineTune",
|
|
|
|
|
|
"thwannbe/qwen3-1.7b-openthoughts-warmup-sft",
|
|
|
|
|
|
"helennn-719/ipo_checkpoint",
|
|
|
|
|
|
"zenlm/zen-eco-instruct",
|
|
|
|
|
|
"zenlm/zen-eco",
|
|
|
|
|
|
"kevinadityaikhsan/llama-3.2-3b-legal-id-grpo",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
# 去重(保持原有顺序)
|
|
|
|
|
|
_seen = set()
|
|
|
|
|
|
_deduplicated = []
|
|
|
|
|
|
for _mid in ALL_MODEL_IDS:
|
|
|
|
|
|
_m = _mid.strip()
|
|
|
|
|
|
if _m and _m not in _seen:
|
|
|
|
|
|
_deduplicated.append(_m)
|
|
|
|
|
|
_seen.add(_m)
|
|
|
|
|
|
ALL_MODEL_IDS = _deduplicated
|
|
|
|
|
|
print(f"[INFO] 去重后模型数量: {len(ALL_MODEL_IDS)}", flush=True)
|
|
|
|
|
|
|
|
|
|
|
|
# ══════════════════════════════════════════════════════════
|
|
|
|
|
|
# 全局状态(供 /status 展示)
|
|
|
|
|
|
# ══════════════════════════════════════════════════════════
|
|
|
|
|
|
_state = {
|
|
|
|
|
|
"strategy_id": STRATEGY_ID,
|
|
|
|
|
|
"phase": "starting", # starting | submitting | done | error
|
|
|
|
|
|
"total": len(ALL_MODEL_IDS),
|
|
|
|
|
|
"submitted": 0,
|
|
|
|
|
|
"failed": 0,
|
|
|
|
|
|
"started_at": None,
|
|
|
|
|
|
"finished_at": None,
|
|
|
|
|
|
}
|
|
|
|
|
|
_shutdown = threading.Event()
|
|
|
|
|
|
|
|
|
|
|
|
# ══════════════════════════════════════════════════════════
|
|
|
|
|
|
# HTTP 服务
|
|
|
|
|
|
# ══════════════════════════════════════════════════════════
|
|
|
|
|
|
class Handler(BaseHTTPRequestHandler):
|
|
|
|
|
|
def do_GET(self):
|
|
|
|
|
|
if self.path == "/health":
|
|
|
|
|
|
self._json({"status": "ok"})
|
|
|
|
|
|
elif self.path == "/status":
|
|
|
|
|
|
self._json(_state)
|
|
|
|
|
|
else:
|
|
|
|
|
|
self._json({"error": "not found"}, 404)
|
|
|
|
|
|
|
|
|
|
|
|
def _json(self, body: dict, code: int = 200):
|
|
|
|
|
|
payload = json.dumps(body, default=str).encode()
|
|
|
|
|
|
self.send_response(code)
|
|
|
|
|
|
self.send_header("Content-Type", "application/json")
|
|
|
|
|
|
self.send_header("Content-Length", str(len(payload)))
|
|
|
|
|
|
self.end_headers()
|
|
|
|
|
|
self.wfile.write(payload)
|
|
|
|
|
|
|
|
|
|
|
|
def log_message(self, fmt, *args):
|
|
|
|
|
|
print(f"[http] {self.address_string()} {fmt % args}", flush=True)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _run_http():
|
|
|
|
|
|
server = ThreadingHTTPServer((HTTP_HOST, HTTP_PORT), Handler)
|
|
|
|
|
|
server.timeout = 1
|
|
|
|
|
|
print(f"[http] 监听 {HTTP_HOST}:{HTTP_PORT}", flush=True)
|
|
|
|
|
|
while not _shutdown.is_set():
|
|
|
|
|
|
server.handle_request()
|
|
|
|
|
|
server.server_close()
|
|
|
|
|
|
print("[http] 已关闭", flush=True)
|
|
|
|
|
|
|
|
|
|
|
|
# ══════════════════════════════════════════════════════════
|
|
|
|
|
|
# 业务逻辑
|
|
|
|
|
|
# ══════════════════════════════════════════════════════════
|
|
|
|
|
|
def submit_task(model_id: str) -> bool:
|
|
|
|
|
|
config_content = f"""
|
|
|
|
|
|
docker_image: git.modelhub.org.cn:9443/enginex/xc-llm-kunlun
|
|
|
|
|
|
nv_docker_image: harbor.4pd.io/dooke/vllm/vllm/vllm-openai:v0.11.0
|
|
|
|
|
|
framework: vllm
|
|
|
|
|
|
lang: en
|
|
|
|
|
|
storage: gpfs
|
|
|
|
|
|
api: chat
|
|
|
|
|
|
temperature: 0.4
|
|
|
|
|
|
repetition_penalty: 1.1
|
|
|
|
|
|
top_p: 0.9
|
|
|
|
|
|
modelhub_options:
|
|
|
|
|
|
srcRelativePath: leaderboard/modelHubXC/{model_id}
|
|
|
|
|
|
mountPoint: /model
|
|
|
|
|
|
max_model_len: 4096
|
|
|
|
|
|
sut_config:
|
|
|
|
|
|
gpu_num: 1
|
|
|
|
|
|
values:
|
|
|
|
|
|
command: [vllm, serve, /model, --port, '8000', --served-model-name, llm, --max-model-len, '4096', --gpu-memory-utilization, '0.9', --enforce-eager, --trust-remote-code, -tp, '1']
|
|
|
|
|
|
ref_config:
|
|
|
|
|
|
gpu_num: 1
|
|
|
|
|
|
values:
|
|
|
|
|
|
command: [vllm, serve, /model, --port, '80', --served-model-name, llm, --max-model-len, '4096', --enforce-eager, --trust-remote-code, -tp, '1']
|
|
|
|
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
payload = {
|
|
|
|
|
|
"configParams": config_content,
|
|
|
|
|
|
"framework": "vllm",
|
|
|
|
|
|
"modelAddress": f"https://huggingface.co/{model_id}",
|
|
|
|
|
|
"targetGpu": GPU_TYPE,
|
|
|
|
|
|
"taskType": TASK_TYPE,
|
|
|
|
|
|
"strategyId": STRATEGY_ID, # 平台要求;若接口不支持该字段会被忽略
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
print(f"📤 提交任务: {model_id}", flush=True)
|
|
|
|
|
|
try:
|
|
|
|
|
|
resp = requests.post(
|
|
|
|
|
|
BASE_URL + ADD_TASK_ENDPOINT,
|
|
|
|
|
|
headers=HEADERS,
|
|
|
|
|
|
json=payload,
|
|
|
|
|
|
timeout=30,
|
|
|
|
|
|
)
|
|
|
|
|
|
print(f"status: {resp.status_code}", flush=True)
|
|
|
|
|
|
result = resp.json()
|
|
|
|
|
|
print(result, flush=True)
|
|
|
|
|
|
if result.get("code") == 0:
|
|
|
|
|
|
print(f"✅ 提交成功: {model_id}", flush=True)
|
|
|
|
|
|
return True
|
|
|
|
|
|
else:
|
|
|
|
|
|
print(f"❌ 提交失败: {result.get('message')}", flush=True)
|
|
|
|
|
|
return False
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
print(f"💥 异常 ({model_id}): {e}", flush=True)
|
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _run_worker():
|
|
|
|
|
|
_state["started_at"] = datetime.utcnow().isoformat()
|
|
|
|
|
|
_state["phase"] = "submitting"
|
|
|
|
|
|
|
|
|
|
|
|
successful: List[str] = []
|
|
|
|
|
|
for model_id in ALL_MODEL_IDS:
|
|
|
|
|
|
if _shutdown.is_set():
|
|
|
|
|
|
break
|
|
|
|
|
|
if submit_task(model_id):
|
|
|
|
|
|
_state["submitted"] += 1
|
|
|
|
|
|
successful.append(model_id)
|
|
|
|
|
|
else:
|
|
|
|
|
|
_state["failed"] += 1
|
|
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
|
with open("submitted_adapt_tasks.txt", "w", encoding="utf-8") as f:
|
|
|
|
|
|
for mid in successful:
|
|
|
|
|
|
f.write(f"{mid}\n")
|
|
|
|
|
|
except Exception:
|
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
_state["finished_at"] = datetime.utcnow().isoformat()
|
|
|
|
|
|
_state["phase"] = "done"
|
|
|
|
|
|
print(
|
|
|
|
|
|
f"[worker] 完成 submitted={_state['submitted']} failed={_state['failed']} total={_state['total']}",
|
|
|
|
|
|
flush=True,
|
|
|
|
|
|
)
|
|
|
|
|
|
# 提交完成后继续保持进程存活,等待平台停止
|
|
|
|
|
|
|
|
|
|
|
|
# ══════════════════════════════════════════════════════════
|
|
|
|
|
|
# 入口
|
|
|
|
|
|
# ══════════════════════════════════════════════════════════
|
|
|
|
|
|
def _handle_signal(signum, _frame):
|
|
|
|
|
|
print(f"[main] 收到信号 {signum},正在关闭...", flush=True)
|
|
|
|
|
|
_shutdown.set()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def main():
|
|
|
|
|
|
signal.signal(signal.SIGTERM, _handle_signal)
|
|
|
|
|
|
signal.signal(signal.SIGINT, _handle_signal)
|
|
|
|
|
|
|
|
|
|
|
|
http_thread = threading.Thread(target=_run_http, daemon=False)
|
|
|
|
|
|
http_thread.start()
|
|
|
|
|
|
|
|
|
|
|
|
worker_thread = threading.Thread(target=_run_worker, daemon=True)
|
|
|
|
|
|
worker_thread.start()
|
|
|
|
|
|
|
|
|
|
|
|
_shutdown.wait()
|
|
|
|
|
|
print("[main] 等待 HTTP 服务关闭...", flush=True)
|
|
|
|
|
|
http_thread.join(timeout=5)
|
|
|
|
|
|
print("[main] 退出", flush=True)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
|
|
main()
|