From 1fd8e461d9a91c812d663f589e6be568856ab321 Mon Sep 17 00:00:00 2001 From: paopaotang <1834563329@qq.com> Date: Tue, 20 Oct 2026 13:45:33 +0800 Subject: [PATCH] add main.py --- main.py | 274 +++++++++++++++----------------------------------------- 1 file changed, 72 insertions(+), 202 deletions(-) diff --git a/main.py b/main.py index c558c68..ce171d6 100644 --- a/main.py +++ b/main.py @@ -1,14 +1,7 @@ -"""ModelHub XC 适配智能体 —— 多任务提交器(本批次 4 条) +"""ModelHub XC 适配智能体 —— 低排队算力批次(5 条) -启动后依次提交 4 条已查重的模型适配验证任务,随后保持 /health 存活等待平台停止。 - -批次清单(提交前均查过:模型列表 0 条 / 全站任务 0 条 / 详情接口无验证记录): - 1. mrm8488/DeepSeek-R1-Distill-Qwen-1.5B-grpo-limo-2e Qwen2 1.5B Ascend_910-b4 vllm - 2. HollowInky/skill-search-qwen3-4b-unmasked-grpo Qwen3 4B Ascend_910-b4 vllm - 3. dmis-lab/OSP-1.4B-100B-Muon Llama 1.4B Ascend_910-b4 vllm - 4. qnguyen3/quan-1.8b-chat Llama 1.8B Ascend_910-b3 vllm - -平台契约:根目录 Dockerfile,监听 8080,GET /health 探活,读取 STRATEGY_ID,处理 SIGTERM。 +每条任务分配一张低排队算力卡,并选用该卡历史通过率较高的框架。 +OSP 系列 max_position_embeddings=2048,配置里的 max_model_len 已由 4096 下调为 2048。 """ import json import os @@ -24,193 +17,89 @@ BASE_URL = os.environ.get("BASE_URL", "https://modelhub.org.cn") ADD_TASK_ENDPOINT = "/api/adapt/task/add" XC_TOKEN = os.environ.get("XC_TOKEN", "6616dfe75c874e61987b1f7c908e6d77") STRATEGY_ID = os.environ.get("STRATEGY_ID", "") - -# 910B4 模板(max_model_len 2048) -CFG_B4 = """framework: vllm -api: completion -max_tokens: 1024 -temperature: 0.7 -repetition_penalty: 1.2 -top_p: 0.9 -lang: zh -max_model_len: 2048 -sut_config: - gpu_num: 1 - values: - command: - - vllm - - serve - - /model - - --port - - '8000' - - --served-model-name - - llm - - --max-model-len - - '2048' - - --dtype - - auto - - --gpu-memory-utilization - - '0.95' - - -tp - - '1' - - --enforce-eager - - --trust-remote-code -ref_config: - gpu_num: 1 - values: - command: - - vllm - - serve - - /model - - --port - - '8000' - - --served-model-name - - llm - - --max-model-len - - '2048' - - --dtype - - auto - - --gpu-memory-utilization - - '0.95' - - -tp - - '1' - - --enforce-eager - - --trust-remote-code""" - -# 910B3 模板(max_model_len 4096) -CFG_B3 = """framework: vllm -api: completion -lang: en -max_model_len: 4096 -max_tokens: 1024 -temperature: 0.7 -repetition_penalty: 1.1 -top_p: 0.9 -sut_config: - gpu_num: 1 - values: - command: - - vllm - - serve - - /model - - --port - - '20644' - - --served-model-name - - llm - - --max-model-len - - '4096' - - -tp - - '1' - - --enforce-eager - - --trust-remote-code -ref_config: - gpu_num: 1 - values: - command: - - vllm - - serve - - /model - - --port - - '80' - - --served-model-name - - llm - - --max-model-len - - '4096' - - -tp - - '1' - - --enforce-eager - - --trust-remote-code""" +TASK_TYPE = "text-generation" TASKS = [ { - "label": "OSP-1.4B-100B-Adam", - "model": "https://www.modelscope.cn/models/dmis-lab/OSP-1.4B-100B-Adam", - "gpu": "Ascend_910-b4", - "config": CFG_B4, + "label": "OSP-1.4B-100B-Muon-Only", + "model": "https://www.modelscope.cn/models/dmis-lab/OSP-1.4B-100B-Muon-Only", + "gpu": "MetaX_c-500", + "framework": "vllm_tokenizer_patch", + "config": "nv_framework: vllm_fix_tokenizer\nframework: vllm_tokenizer_patch\nstorage: gpfs\nmax_tokens: 1024\nmax_model_len: 2048\napi: completion\nsut_config:\n gpu_num: 1\n values:\n command: ['/opt/conda/bin/vllm', 'serve', '/model', '--port', '8000', '--served-model-name', 'llm', '--max-model-len', '2048', '--gpu-memory-utilization', '0.9', '--enforce-eager', '--trust-remote-code' ,'-tp', '1' ]\nref_config:\n gpu_num: 1\n values:\n command: ['/opt/entrypoint.sh', '/model', '--port', '80', '--served-model-name', 'llm', '--max-model-len', '2048', '--enforce-eager', '--trust-remote-code', '-tp', '1']" }, { - "label": "OSP-1.4B-1T-Adam", - "model": "https://www.modelscope.cn/models/dmis-lab/OSP-1.4B-1T-Adam", - "gpu": "Ascend_910-b4", - "config": CFG_B4, + "label": "OSP-1.4B-100B-Muon-SSNorm", + "model": "https://www.modelscope.cn/models/dmis-lab/OSP-1.4B-100B-Muon-SSNorm", + "gpu": "Kunlunxin_p-800", + "framework": "vllm_fix_tokenizer", + "config": "framework: vllm_fix_tokenizer\nlang: en\nmax_model_len: 2048\nsut_config:\n gpu_num: 1\n values:\n command:\n - /opt/entrypoint.sh - /model\n - --port\n - '80'\n - --served-model-name\n - llm\n - --max-model-len\n - '2048'\n - --enforce-eager\n - --trust-remote-code\n - -tp\n - '1'\nref_config:\n gpu_num: 1\n values:\n command:\n - /opt/entrypoint.sh - /model\n - --port\n - '80'\n - --served-model-name\n - llm\n - --max-model-len\n - '2048'\n - --enforce-eager\n - --trust-remote-code\n - -tp\n - '1'" }, + { + "label": "OSP-1.4B-100B-Shampoo-SSNorm", + "model": "https://www.modelscope.cn/models/dmis-lab/OSP-1.4B-100B-Shampoo-SSNorm", + "gpu": "Cambricon_mlu-370-x8", + "framework": "vllm-mlu", + "config": "framework: vllm-mlu\nnv_framework: vllm_fix_tokenizer\napi: completion\nlang: en\ntemperature: 0.4\nrepetition_penalty: 1.1\ntop_p: 0.9\nsut_config:\n gpu_num: 1\n values:\n env:\n - name: MAX_MODEL_LEN\n value: 2048\n - name: VLLM_ALLOW_LONG_MAX_MODEL_LEN\n value: '1'\n command:\n - vllm\n - serve\n - /model\n - --port\n - '8000'\n - --served-model-name\n - llm\n - --max-model-len\n - '2048'\n - --trust-remote-code\n - --dtype\n - float16\nref_config:\n cpu_num: 2\n gpu_num: 1\n values:\n env:\n - name: MAX_MODEL_LEN\n value: 2048\n - name: VLLM_ALLOW_LONG_MAX_MODEL_LEN\n value: '1'\n command:\n - /opt/entrypoint.sh\n - /model\n - --port\n - '80'\n - --served-model-name\n - llm\n - --max-model-len\n - '2048'\n - --trust-remote-code\n - --dtype\n - float16\n" + }, + { + "label": "OSP-1.4B-100B-Muon-EmbProj", + "model": "https://www.modelscope.cn/models/dmis-lab/OSP-1.4B-100B-Muon-EmbProj", + "gpu": "Biren_166m", + "framework": "vllm_fix_tokenizer", + "config": "framework: vllm_fix_tokenizer\nlang: en\nmax_model_len: 2048\nsut_config:\n gpu_num: 1\n values:\n command:\n - /opt/entrypoint.sh - /model\n - --port\n - '80'\n - --served-model-name\n - llm\n - --max-model-len\n - '2048'\n - --enforce-eager\n - --trust-remote-code\n - -tp\n - '1'\nref_config:\n gpu_num: 1\n values:\n command:\n - /opt/entrypoint.sh - /model\n - --port\n - '80'\n - --served-model-name\n - llm\n - --max-model-len\n - '2048'\n - --enforce-eager\n - --trust-remote-code\n - -tp\n - '1'" + }, + { + "label": "OSP-1.4B-1T-Muon-SSNorm-EmbProj", + "model": "https://www.modelscope.cn/models/dmis-lab/OSP-1.4B-1T-Muon-SSNorm-EmbProj", + "gpu": "Sunrise_pt-200-x1", + "framework": "vllm_fix_tokenizer", + "config": "framework: vllm_fix_tokenizer\napi: completion\nmax_tokens: 1024\ntemperature: 0.7\nrepetition_penalty: 1.2\ntop_p: 0.9\nlang: zh\nmax_model_len: 2048\nsut_config:\n gpu_num: 1\n values:\n command:\n - /opt/entrypoint.sh\n - /model\n - --port\n - '8000'\n - --served-model-name\n - llm\n - --max-model-len\n - '2048'\n - --gpu-memory-utilization\n - '0.9'\n - --enforce-eager\n - --trust-remote-code\nref_config:\n gpu_num: 1\n values:\n command:\n - /opt/entrypoint.sh\n - /model\n - --port\n - '8000'\n - --served-model-name\n - llm\n - --max-model-len\n - '2048'\n - --dtype\n - float16\n - --gpu-memory-utilization\n - '0.95'\n - -tp\n - '1'\n - --enforce-eager\n - --trust-remote-code\n" + } ] -TASK_TYPE = "text-generation" -FRAMEWORK = "vllm" HEADERS = {"Content-Type": "application/json", "Xc-Token": XC_TOKEN} - HTTP_HOST, HTTP_PORT = "0.0.0.0", 8080 -GAP = 4 # 两条之间的间隔秒数 - -_state = { - "strategy_id": STRATEGY_ID, - "phase": "starting", # starting | submitting | done - "total": len(TASKS), - "submitted": 0, - "failed": 0, - "results": [], - "started_at": None, - "finished_at": None, -} +GAP = 4 _shutdown = threading.Event() +_state = {"phase": "starting", "total": len(TASKS), "submitted": 0, "failed": 0, "results": []} -def submit_one(task): - payload = { - "configParams": task["config"], - "framework": FRAMEWORK, - "modelAddress": task["model"], - "targetGpu": task["gpu"], +def submit_one(t): + body = { + "configParams": t["config"], + "framework": t["framework"], + "modelAddress": t["model"], + "targetGpu": t["gpu"], "taskType": TASK_TYPE, "strategyId": STRATEGY_ID, } try: - resp = requests.post(BASE_URL + ADD_TASK_ENDPOINT, headers=HEADERS, - json=payload, timeout=90) - body = resp.json() + r = requests.post(BASE_URL + ADD_TASK_ENDPOINT, headers=HEADERS, json=body, timeout=90) + j = r.json() except Exception as e: # noqa: BLE001 - body = {"code": -1, "message": "exception: %s" % e} - - code = body.get("code") - data = body.get("data") or {} - print("[submit] %s gpu=%s code=%s message=%s taskId=%s" - % (task["label"], task["gpu"], code, body.get("message"), data.get("id")), flush=True) - return code, body.get("message"), data.get("id") + j = {"code": -1, "message": "exception: %s" % e} + tid = (j.get("data") or {}).get("id") + print("[submit] %s gpu=%s fw=%s code=%s msg=%s taskId=%s" + % (t["label"], t["gpu"], t["framework"], j.get("code"), j.get("message"), tid), flush=True) + return j.get("code"), tid -def run_batch(): +def run(): _state["phase"] = "submitting" - _state["started_at"] = datetime.utcnow().isoformat() - - for i, task in enumerate(TASKS, 1): + for i, t in enumerate(TASKS, 1): if _shutdown.is_set(): break - code, msg, task_id = submit_one(task) - _state["results"].append({ - "index": i, - "label": task["label"], - "model": task["model"], - "gpu": task["gpu"], - "code": code, - "message": msg, - "task_id": task_id, - "time": datetime.utcnow().isoformat(), - }) - if code == 0: - _state["submitted"] += 1 - else: - _state["failed"] += 1 + code, tid = submit_one(t) + _state["results"].append({"label": t["label"], "gpu": t["gpu"], + "framework": t["framework"], "code": code, "task_id": tid}) + _state["submitted" if code == 0 else "failed"] += 1 if i < len(TASKS): time.sleep(GAP) - _state["phase"] = "done" - _state["finished_at"] = datetime.utcnow().isoformat() - print("[batch] 完成 submitted=%d failed=%d total=%d" - % (_state["submitted"], _state["failed"], _state["total"]), flush=True) + print("[batch] 完成 submitted=%d failed=%d" % (_state["submitted"], _state["failed"]), flush=True) -class Handler(BaseHTTPRequestHandler): +class H(BaseHTTPRequestHandler): def do_GET(self): if self.path == "/health": self._json({"status": "ok"}) @@ -219,48 +108,29 @@ class Handler(BaseHTTPRequestHandler): else: self._json({"error": "not found"}, 404) - def _json(self, body, code=200): - raw = json.dumps(body, ensure_ascii=False, default=str).encode() - self.send_response(code) + def _json(self, b, c=200): + raw = json.dumps(b, ensure_ascii=False, default=str).encode() + self.send_response(c) self.send_header("Content-Type", "application/json") self.send_header("Content-Length", str(len(raw))) self.end_headers() self.wfile.write(raw) - def log_message(self, fmt, *args): - print(self.address_string() + " - " + (fmt % args), flush=True) - - -def _handle_signal(signum, _frame): - print("[main] 收到信号 %s,准备退出" % signum, flush=True) - _shutdown.set() - - -def _run_http(): - server = ThreadingHTTPServer((HTTP_HOST, HTTP_PORT), Handler) - server.timeout = 1 - print("[http] 监听 %s:%d" % (HTTP_HOST, HTTP_PORT), flush=True) - while not _shutdown.is_set(): - server.handle_request() - server.server_close() + def log_message(self, *a): + pass def main(): - signal.signal(signal.SIGTERM, _handle_signal) - signal.signal(signal.SIGINT, _handle_signal) - + signal.signal(signal.SIGTERM, lambda *_: _shutdown.set()) print("[main] strategy_id=%s tasks=%d" % (STRATEGY_ID, len(TASKS)), flush=True) for t in TASKS: - print("[main] 计划: %s @ %s" % (t["label"], t["gpu"]), flush=True) - - http_thread = threading.Thread(target=_run_http, daemon=False) - http_thread.start() - - worker = threading.Thread(target=run_batch, daemon=True) - worker.start() - - _shutdown.wait() + print("[main] 计划: %s @ %s / %s" % (t["label"], t["gpu"], t["framework"]), flush=True) + srv = ThreadingHTTPServer((HTTP_HOST, HTTP_PORT), H) + srv.timeout = 1 + threading.Thread(target=run, daemon=True).start() + while not _shutdown.is_set(): + srv.handle_request() + srv.server_close() -if __name__ == "__main__": - main() +main()