26 Commits

Author SHA1 Message Date
efee86e49c submit 24 models on zhoushasha: ppu_zw_810e(18)/hygon_k100-ai(4)/MetaX_c-500(1)/Biren_166m(1)
Candidate pool is the 24711 already-downloaded models, which satisfies
mechanism A's precondition that the model be present in platform storage.

Strict and relaxed condition-2 give identical results this round: of the 24007
pooled models with verify records, 24006 already have 已验证 on some card, so
relaxing to include 验证中 adds just one. The binding constraint is now how few
models lack a record on each card - Kunlunxin_p-800, Cambricon_mlu-370-x8 and
Iluvatar_bi-150 are all at zero and are left out of GPU_JOBS.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-20 18:27:33 +08:00
793c49aea3 submit round-24 filter results on zhoushasha: MetaX_c-500(63)/Kunlunxin_p-800(1)/Cambricon_mlu-370-x8(1)/Biren_166m(95) + ppu_zw_810e(57), 217 models total
Also add a hygon_k100-ai config branch and HYGON_MODELS list (kept available but
excluded from GPU_JOBS per request). Refresh the expired AUTH_TOKEN.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-15 17:25:35 +08:00
d5f576fac7 submit MetaX_c-500(7) + Biren_166m(95) non-quantized models; refresh AUTH_TOKEN 2026-08-31 15:18:39 +08:00
965783957e add self-looping quota retry: retry quota-blocked models every 30min in-process, no redeploy needed 2026-08-19 13:59:54 +08:00
cd5c7a2435 submit entire remaining ppu_zw_810e candidate pool (5424 models); run to natural quota exhaustion 2026-08-19 11:19:18 +08:00
cdbacf5a46 submit next batch of ppu_zw_810e (200 models) 2026-08-19 01:15:33 +08:00
5bfc0fc53e submit next batch of ppu_zw_810e (200 models) 2026-08-19 01:07:58 +08:00
606655b876 submit entire remaining ppu_zw_810e candidate pool (6220 models); run to natural quota exhaustion 2026-08-18 15:55:51 +08:00
eee9e5813c submit next batch of ppu_zw_810e (250 models, matches remaining ~2000-slot quota headroom) 2026-08-18 15:43:55 +08:00
32122cd866 submit next batch of ppu_zw_810e (360 models, supersedes stuck v1.0.28 build) 2026-08-18 15:34:19 +08:00
ebc9f400e0 submit next batch of ppu_zw_810e (250 models); refresh AUTH_TOKEN 2026-08-18 11:13:33 +08:00
b546ad980f submit next batch of ppu_zw_810e (300 models) 2026-08-13 16:56:17 +08:00
54adf4f956 submit next batch of ppu_zw_810e (200 models) 2026-08-11 14:30:02 +08:00
66f378bdc0 submit next batch of ppu_zw_810e (200 models); refresh AUTH_TOKEN 2026-08-10 17:07:48 +08:00
d49bf186ae submit next batch of ppu_zw_810e (200 models) 2026-08-07 11:23:46 +08:00
1b95e92f72 add next batch of ppu_zw_810e submission (500 models, lines 601-1100 of source list) 2026-08-06 13:06:23 +08:00
dd9db6b4d2 add ppu_zw_810e submission (600 models), refresh AUTH_TOKEN; skip other 4 GPUs this run 2026-08-04 20:54:10 +08:00
5c9f5d9ad7 refresh all 4 GPU model lists with latest filter results 2026-07-29 17:36:02 +08:00
9b5087467f add Kunlunxin_p-800 as 4th GPU with filtered model list 2026-07-29 15:16:34 +08:00
7dcada5617 convert to multi-GPU submission (Biren/Cambricon/MetaX) with fresh filtered model lists 2026-07-29 14:26:16 +08:00
5958df93b0 switch to Cambricon_mlu-370-x8 with new model list, refresh AUTH_TOKEN 2026-07-27 16:46:41 +08:00
a73274e6a4 switch back to ppu_zw_810e with new model list 2026-07-23 14:27:36 +08:00
b3c577219f switch to Biren_166m GPU with new model list 2026-07-22 13:53:23 +08:00
1591b3050e refresh expired AUTH_TOKEN 2026-07-21 18:56:31 +08:00
55c77faa70 update model list 2026-07-21 18:42:47 +08:00
e51533e0bf update model list
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 16:58:36 +08:00
3 changed files with 320 additions and 275 deletions

2
.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
.DS_Store
__pycache__/

Binary file not shown.

593
main.py
View File

@@ -1,8 +1,19 @@
"""
xc_validation_strategy — 主入口
启动后执行一次模型验证任务批量提交,之后保持 HTTP 服务存活。
同时暴露 /healthK8s 探活)和 /status运行状态
启动后针对 GPU_JOBS 中配置的 GPU 卡分别批量提交各自筛选出的模型验证任务
(当前仅提交 ppu_zw_810e其余 4 张卡 Biren_166m/Cambricon_mlu-370-x8/MetaX_c-500/
Kunlunxin_p-800 的 config_content 模板和模型列表仍保留在代码中,未列入本次 GPU_JOBS
/adminApi/async/task/create-contest-task
Bearer Token 认证),之后保持 HTTP 服务存活。
账号额度自动重试:如果某个模型提交时命中"当前等待中或运行中的异步模型验证
任务数量已达上限"(账号额度已满),不算永久失败,会被留到下一轮;额度耗尽后
本进程会原地等待 30 分钟,再自动重试所有因额度问题未提交成功的模型,如此循环,
直至全部提交成功或进程被平台关闭——不需要重新部署新策略,循环逻辑在本进程内完成。
非额度原因的失败(如模型已在验证中等)不会重试。
同时暴露 /healthK8s 探活)和 /status运行状态含当前轮次/待重试数/下次重试时间)。
"""
import json
@@ -22,10 +33,9 @@ BASE_URL = os.environ.get("BASE_URL", "https://modelhub.org.cn")
SUBMIT_ENDPOINT = "/adminApi/async/task/create-contest-task"
# 通过 curl -X POST https://modelhub.org.cn/adminApi/user/login 获取后填入
AUTH_TOKEN = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyQWNjb3VudCI6Inpob3VzaGFzaGEiLCJpZCI6MTQsInVzZXJSb2xlIjoibGVhZGVyYm9hcmQiLCJleHAiOjE3ODQ1NDc1NDYsImlhdCI6MTc4Mzk0Mjc0Nn0.ZcOqcrfI22LPi4mGMnt164nZGhi61ZxtJGYsoO7fZdM"
AUTH_TOKEN = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyQWNjb3VudCI6Inpob3VzaGFzaGEiLCJpZCI6MTQsInVzZXJSb2xlIjoibGVhZGVyYm9hcmQiLCJleHAiOjE3OTAwNjkxMjAsImlhdCI6MTc4OTQ2NDMyMH0.KzJac6ddaZdtLvjD6ZnoK1PNEKFoXdyDn9Hh4FxU9ic"
CONTEST_API_TOKEN = "ef1ef82f3c9efee413d602345fbe224d"
CONTRIBUTORS = "zhoushasha"
GPU_TYPE = "ppu_zw_810e"
TASK_TYPE = "text-generation"
STRATEGY_ID = os.environ.get("STRATEGY_ID", "") # 平台自动注入,无需修改
@@ -33,247 +43,82 @@ HTTP_HOST = "0.0.0.0"
HTTP_PORT = 8080
# ══════════════════════════════════════════════════════════
# 模型列表
# 各 GPU 的模型列表(来自 filter_verified_models 脚本的筛选结果)
# ══════════════════════════════════════════════════════════
ALL_MODEL_IDS = [
"Alienpenguin10/M3PO-bahdanau-trial1-seed123",
"sujalrajpoot/TrueSyncAI-Aurion",
"prithivMLmods/Tureis-Qwen3_QWQ-4B-Exp",
"standrey/listing-parser-llama31-8b-ft-v1-full",
"zarakiquemparte/zarablend-l2-7b",
"linzju/Bio-Medical-Llama-3-8B_EnchTable_FFN",
"leonMW/Qwen3-4B-Thinking-2507-GSPO-Easy",
"longvideoagent/longvideoagent-qwen3-4b",
"ishikaa/acquisition_qwen3b_alpaca_proximity",
"01ai/Yi-9B-200K",
"Gille/StrangeMerges_33-7B-slerp",
"sstoica12/acquisition_llama-3_2-3b_bins_medmcqa_gradient",
"speechlessai/speechless-coding-7b-16k-tora",
"unsloth/Qwen2.5-Math-1.5B-Instruct",
"Yuma42/KangalKhan-Sapphire-7B",
"shadowml/BeagleSempra-7B",
"bralynn/test18",
"m-a-p/OProver-8B-Round1",
"yeen214/test_llama2_7b",
"Xwin-LM/Xwin-LM-7B-V0.2",
"FreedomIntelligence/AceGPT-13B",
"Edcastro/tinyllama-edcastr_JavaScript-v2",
"zarakiquemparte/zaraxe-l2-7b",
"MaziyarPanahi/Llama-3-8B-Instruct-v0.8",
"defog/sqlcoder2",
"SawinuCP/bus_booking_voice_agent_merged",
"j05hr3d/Llama-3.2-3B-Instruct-C_M_T-DOLLY-SEED999",
"Changgil/K2S3-SOLAR-11b-v1.0",
"agentica-org/DeepCoder-1.5B-Preview",
"prithivMLmods/Omni-Reasoner3-Merged",
"ibm-granite/granite-7b-instruct",
"zarakiquemparte/kuchiki-1.1-l2-7b",
"MaziyarPanahi/Llama-3-8B-Instruct-v0.1",
"Magpie-Align/Llama-3.1-8B-Magpie-Align-v0.1",
"prithivMLmods/Neumind-Math-7B-Instruct",
"dphn/dolphin-2.9.3-qwen2-1.5b",
"OpenBuddy/openbuddy-mistral-7b-v13",
"kairawal/Qwen3-4B-TL-SynthDolly-1A-E3",
"sahilnagaralu/movie-script",
"xw1234gan/SFT_Qwen2.5-1.5B-Instruct_cnk12",
"yunjae-won/ubq30i_qwen4b_sft_yl",
"1010happy/qwen3BInstruct_ClaudeDefault",
"yunjae-won/ubq30i_qwen4b_sft_both",
"willieseun/AIMO-Qwen2.5-Math-1.5B-Instruct-Finetuned",
"NousResearch/Yarn-Mistral-7b-64k",
"xiaolesu/OsmosisProofling-GRPO-NT",
"health360/Healix-410M",
"RUC-AIBOX/STILL-3-1.5B-preview",
"cjvt/GaMS-1B",
"Lansechen/Qwen2.5-7B-Open-R1-GRPO-math-lighteval-1epochstop-withformat",
"Charlie911/vicuna-7b-v1.5-general-temporal-merged",
"Kyleyee/cDPO_hh-seed5",
"prithivMLmods/Llama-3.2-3B-Math-Oct",
"Kyleyee/HINGE_hh-seed5",
"arcee-ai/Patent-Instruct-7b",
"jb723/cross_lingual_epoch2",
"davidkim205/komt-mistral-7b-v1",
"kalisai/Nusantara-1.8b-Indo-Chat",
"prithivMLmods/Llama-8B-Distill-CoT",
"Kyleyee/HINGE_hh-seed3",
"simplescaling/s1.1-1.5B",
"sail/Sailor2-3B-SFT",
"allenai/OLMoE-1B-7B-0924-Instruct",
"prithivMLmods/Llama-3.2-6B-AlgoCode",
"CloneBO/OracleLM",
"NousResearch/Yarn-Solar-10b-32k",
"m-a-p/OProver-8B-Base",
"HuggingFaceH4/mistral-7b-sft-alpha",
"Hyeongwon/P2-split2_prob_Qwen3-4B-Base_0312-01",
"martyn/mixtral-megamerge-dare-8x7b-v1",
"Kyleyee/rDPO_hh-seed4",
"jingyeom/seal3.1.6n_7b",
"sonthenguyen/OpenHermes-2.5-Mistral-7B-mt-bench-DPO-reversed_corrupted",
"shibing624/ziya-llama-13b-medical-merged",
"datajuicer/LLaMA-1B-dj-refine-150B",
"ajibawa-2023/Uncensored-Jordan-7B",
"nlpguy/AlloyIngot",
"HuggingFaceTB/SmolLM3-3B",
"allenai/codetulu-2-7b",
"vihangd/dopeyshearedplats-2.7b-v1",
"uukuguy/speechless-code-mistral-7b-v2.0",
"j05hr3d/Llama-3.2-3B-Instruct-C_M_T-ALPACA",
"cognitivetech/Mistral-7B-Inst-0.2-Bulleted-Notes",
"sail/Qwen2.5-Math-1.5B-Oat-Zero",
"reaperdoesntknow/SMOLM2Prover",
"Kyleyee/ORPO_hh-seed5",
"CarrotAI/Llama-3.2-Rabbit-Ko-3B-Instruct",
"NousResearch/Nous-Capybara-7B-V1",
"Vijay3548/InterviewMaster-Llama3.1",
"ReviewHub/qwen3-4b-it-2507-sft-2018-2022-rl-step-20",
"Nos-PT/Llama-Carvalho-PT",
"Gille/StrangeMerges_49-7B-dare_ties",
"Kyleyee/CPO_hh-seed2",
"Kyleyee/cDPO_hh-seed3",
"Kyleyee/DrDPO_hh-seed2",
"sthenno-com/miscii-14b-0218",
"mtgv/MobileLLaMA-2.7B-Chat",
"Novaciano/Alice_In_The_Dark_2-Slerp-RP-3.2-1B",
"Himitsui/KuroMitsu-11B",
"owlninjam/nytheria-3b",
"Kyleyee/DrDPO_hh-seed4",
"Kyleyee/DrDPO_hh-seed5",
"shahzebnaveed/NeuralHermes-2.5-Mistral-7B",
"plaguss/mistal-7b-prm-openrlhf",
"viethq188/Rabbit-7B-v2-DPO-Chat",
"EmbeddedLLM/Mistral-7B-Merge-14-v0.3-ft-step-9984",
"dbpedia/nspm-starcoder-1b",
"psh3333/llama-3.2-3b-grpo-merged",
"saarvajanik/facebook-opt-6.7b-qcqa-ub-16-best-for-KV-cache",
"EmbeddedLLM/Mistral-7B-Merge-14-v0.3",
"xformAI/facebook-opt-125m-qcqa-ub-6-best-for-KV-cache",
"Rev124/llama-3-pruned",
"RatanRohith/NeuralPizza-7B-V0.3",
"mncai/DPO_BC_partial_epoch6",
"zeemen2723/museai-lyrics-gen",
"automerger/OgnoExperiment27-7B",
"sohamb37lexsi/qwen25-3b-legal-correction",
"swift/Meta-Llama-3-8B",
"m-a-p/MuPT-v0-8192-190M",
"Kquant03/Samlagast-7B-laser-bf16",
"VTSNLP/Llama3-ViettelSolutions-8B",
"vihangd/dopeyshearedplats-1.3b-v1",
"HCY123902/qwen25_7b_base_hc_tsss_n32_r1_dpo",
"coder3101/gemma-3-1b-it-heretic",
"Hemkant04/qwen05-resume-job-match-evaluator",
"yekon9/Qwen3-4B-Instruct-2507-heretic",
"uukuguy/Orca-2-13b-f16",
"Kquant03/NeuralTrix-7B-dpo-relaser",
"sambanovasystems/SambaLingo-Russian-Base",
"bineric/NorskGPT-Mistral-7b",
"ReviewHub/qwen3-4b-it-2507-sft-2018-2022-rl-step-10",
"beyoru/EvolLLM",
"driaforall/Dria-Agent-a-3B",
"tlphams/zoyllm-7b-slimorca",
"QuixiAI/WizardLM-33B-V1.0-Uncensored",
"bilalRahib/TinyLLama-NSFW-Chatbot",
"Ahatsham/Llama-3-8B-Instruct_Planning_Feedback_oldaug_v2",
"unsloth/Qwen2.5-Math-1.5B",
"wang7776/Llama-2-7b-chat-hf-30-sparsity",
"hector-gr/RLCR-v4-ks-uniqueness-buf5k-hotpot",
"m-a-p/neo_7b_instruct_v0.1",
"p208p2002/llama-traditional-chinese-120M",
"tartuNLP/Llammas-base",
"riotu-lab/ArabianGPT-01B",
"openaccess-ai-collective/DPOpenHermes-7B",
"Enxin/MovieChat-vicuna",
"Skywork/Skywork-OR1-Math-7B",
"Lugha-Llama/Lugha-Llama-8B-wura_edu",
"laion/allenai-sera-unified-316__Qwen3-8B",
"T1anyu/DeepInnovator",
"mideind/icelandic-gpt-sw3-6.7b-gec",
"Rayeeennnnnnnn/legalmind-chatbot",
"Wanfq/FuseLLM-7B",
"mrvinph/Qwen2.5-0.5B-Instruct-Gensyn-Swarm-placid_wily_woodpecker",
"shivanikerai/Llama-2-7b-chat-hf-title-ner-and-title-suggestions-v2.0",
"Invalid-Null/PeiYangMe-0.7",
"open-unlearning/unlearn_tofu_Llama-3.2-1B-Instruct_forget10_GradDiff_lr1e-05_alpha5_epoch5",
"Tesslate/Tessa-T1-3B",
"LorenaYannnnn/unsafe_compliance-Qwen3-0.6B-OURS_self-seed_1",
"HiTZ/latxa-7b-v1",
"huggyllama/llama-7b",
"FlyPig23/Llama3.2-3B_Paper_Impact_media_SFT_1ep",
"hongzhouyu/FineMedLM-o1",
"shisa-ai/shisa-v1-llama3-8b.lr-5e6",
"senseable/Westlake-7B",
"simplescaling/s1.1-3B",
"Borjan/finki-gpt-140M",
"TinyLlama/TinyLlama_v1.1_chinese",
"Manirajan/interview_tiny",
"ajibawa-2023/Young-Children-Storyteller-Mistral-7B",
"TinyLlama/TinyLlama_v1.1_math_code",
"manotham/Thai-dialogue-transalate_sft_80K",
"nassimjp/Maral-7B-alpha-1",
"MSL7/INEX16-7b",
"Rayeeennnnnnnn/mizan-legal-tunisian",
"maheshrawat18/Qwen3-4B-2507-sft1",
"prithivMLmods/Theta-Crucis-0.6B-Turbo1",
"mlabonne/llama-2-7b-miniguanaco",
"FreekCoolAI/privacy-gemma-qlora",
"lex-hue/Delexa-V0.1-7b",
"goldfish-models/tur_latn_100mb",
"shisa-ai/ablation-18-rafbestseq-shisa-v2-llama-3.1-8b-lr8e6",
"yash-lulla/Legal_AI_Assistant",
"prithivMLmods/Deepthink-Llama-3-8B-Preview",
"prithivMLmods/QwQ-R1-Distill-7B-CoT",
"sstoica12/acquisition_metamath_llama_instruct-3_1-8b-math_format_500_combined_openr1math",
"goldfish-models/rus_cyrl_1000mb",
"goldfish-models/ukr_cyrl_1000mb",
"eren23/dpo-binarized-NeutrixOmnibe-7B",
"RAANA-IA/Gheya-med",
"mesolitica/malaysian-tinyllama-1.1b-16k-instructions-v2",
"bue0912/ToolOmni-Qwen3-4B",
"BRlkl/distill-sft-qwen3-4b-full",
"prithivMLmods/PocketThinker-QwQ-3B-Instruct",
"prithivMLmods/Megatron-Bots-1.7B-Reasoning",
"kumarprince070107/geobot",
"ClaudioSavelli/FAME_GA_llama32-1b-instruct-qa",
"kairawal/Qwen3-0.6B-EL-SynthDolly-1A-E8",
"prithivMLmods/Poseidon-Reasoning-1.7B",
"PKU-Alignment/ProgressGym-HistLlama3-8B-C014-instruct-v0.2",
"unsloth/Qwen2-7B",
"prithivMLmods/Open-Xi-Math-Preview",
"MiniLLM/teacher-gpt2-1.5B",
"Rakancorle1/qwen2.5-7b_Instruct_policy_traj_30k_full",
"prithivMLmods/Lang-Exster-0.5B-Instruct",
"prithivMLmods/Nenque-MoT-0.6B-Elite14",
"posicube/Llama2-chat-AYT-13B",
"lomahony/pythia-70m-helpful-sft",
"kyubeen/code-grpo-checkpoint-950",
"nicholasKluge/TeenyTinyLlama-160m",
"allenai/Llama-3.1-Tulu-3-8B",
"BarraHome/Mistroll-7B-v2.2",
"posicube/Llama-chat-AY-13B",
"hongli-zhan/MINT-empathy-Qwen3-4B",
"jhhj25/qwen3-moe-neuron_structure_drop-p50-s1k-128samples-sft",
"Ikonz-Studios/seva-sarathi-intent-qwen3-1.7b",
"NECOUDBFM/Jellyfish-8B",
"gradients-io-tournaments/augmented-1db17e1d682d23fd",
"Locutusque/LocutusqueXFelladrin-TinyMistral248M-Instruct",
"ChuGyouk/R16",
"oveja1122/toolcalling-merged-demo",
"kmseong/llama3_2_3b-instruct-math-safedelta-scale0.8",
"EleutherAI/SmolLM2-1.7B-magpie-ultra-v1.0-math-431k-s",
"paulml/NeuralOmniBeagleMBX-v3-7B",
"skemessage/Qwen2.5-7B-Instruct-neuron",
BIREN_MODELS = [
"zipaltrivedi/dotnet-coder-14b",
]
CAMBRICON_MODELS = [
]
METAX_MODELS = [
"zipaltrivedi/dotnet-coder-14b",
]
HYGON_MODELS = [
"zipaltrivedi/dotnet-coder-14b",
"cds-jb/qwen3-14b-butterfly-subliminal-fullft",
"lllqaq/Qwen2.5-Coder-14B-Instruct-num11-v1-v2-v3-pairs-v3-triples-post-r2egym",
"deepmako/Mako-32B-Conductor",
]
KUNLUNXIN_MODELS = [
]
PPU_MODELS = [
"fpadovani/eng-latn-100mb-after-ppt-Dp-10mb-ckpt500_seed10",
"fpadovani/ita-latn-10mb-after-ppt-Dp-100mb-ckpt500_seed3407",
"fpadovani/ita-latn-10mb-after-ppt-Dp-10mb-ckpt500_seed3407",
"richardr1126/spider-skeleton-wizard-coder-merged",
"fpadovani/dan-latn-10mb-after-ppt-shuff-dyck-10mb-ckpt500_seed3407",
"fpadovani/ita-latn-10mb-after-ppt-shuff-dyck-100mb-ckpt500_seed3407",
"omerkaragulmez/XbyK-0.1",
"fpadovani/eng-latn-10mb-after-ppt-Dp-10mb-ckpt500_seed10",
"fpadovani/eng-latn-10mb-100mb_seed10",
"flax-community/gpt2-medium-indonesian",
"RedHatAI/QwQ-32B-Preview-quantized.w8a8",
"fractalego/fact-checking",
"KoboldAI/GPT-J-6B-Adventure",
"EasierAI/Falcon-3-1B",
"theprint/mistral-7b-cthulhu",
"iwalton3/phoenix",
"renzhenzhen/internLM2-for-triples",
"u2mithrandir/epsi_tmall",
]
# 本轮提交ppu_zw_810e(18) / hygon_k100-ai(4) / MetaX_c-500(1) / Biren_166m(1)共24个。
#
# 候选池是 api_verify_model_download_status_a.txt 里那 24711 个【已下载】的模型,
# 正好满足机制A「模型必须已下载到平台存储」的前提v1.0.37 那次157个失败就是因为没下载
#
# 本轮严格口径与放宽口径别的卡「已验证」vs「已验证或验证中」结果完全相同
# 这批已下载模型里 24007 个有验证记录的24006 个都已至少一张卡「已验证」,
# 放宽只多捞出 1 个;真正的瓶颈是各卡「无记录」的模型太少——
# Kunlunxin_p-800 / Cambricon_mlu-370-x8 / Iluvatar_bi-150 均为 0故不列入 GPU_JOBS。
GPU_JOBS: List[Tuple[str, List[str]]] = [
("ppu_zw_810e", PPU_MODELS),
("hygon_k100-ai", HYGON_MODELS),
("MetaX_c-500", METAX_MODELS),
("Biren_166m", BIREN_MODELS),
]
TOTAL_MODELS = sum(len(models) for _, models in GPU_JOBS)
# ══════════════════════════════════════════════════════════
# 全局状态(供 /status 展示)
# ══════════════════════════════════════════════════════════
_state = {
"strategy_id": STRATEGY_ID,
"phase": "starting", # starting | submitting | done | error
"total": len(ALL_MODEL_IDS),
"phase": "starting", # starting | submitting | waiting_retry | done | error
"total": TOTAL_MODELS,
"submitted": 0,
"failed": 0,
"per_gpu": {gpu: 0 for gpu, _ in GPU_JOBS},
"started_at": None,
"finished_at": None,
"round": 0, # 当前是第几轮提交
"quota_blocked_remaining": 0, # 因额度上限暂未提交成功、等待下一轮重试的模型数
"next_retry_at": None, # 下一轮重试的预计时间(额度耗尽等待期间)
}
_shutdown = threading.Event()
@@ -311,14 +156,124 @@ def _run_http():
print("[http] 已关闭", flush=True)
# ══════════════════════════════════════════════════════════
# 业务逻辑
# 各 GPU 的 config_content 模板
# ══════════════════════════════════════════════════════════
def _submit_task(token: str, model_id: str) -> Tuple[bool, str]:
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {token}",
}
config_content = f"""gpu_type: ppu_zw_810e
def build_config_content(gpu_type: str, model_id: str) -> str:
if gpu_type == "Biren_166m":
max_model_len = 4096
return f"""docker_image: git.modelhub.org.cn:9443/enginex/xc-llm-biren166m:26.01
nv_docker_image: harbor.4pd.io/dooke/vllm/vllm/vllm-openai:v0.11.0
framework: vllm
lang: zh
storage: gpfs
api: completion
modelhub_options:
srcRelativePath: leaderboard/modelHubXC/{model_id}
mountPoint: /model
max_model_len: {max_model_len}
sut_config:
values:
gpu_num: 1
env:
- name: MAX_MODEL_LEN
value: {max_model_len}
command: ['/bin/bash', '-ic', 'vllm serve /model --port 8000 --served-model-name llm --max-model-len {max_model_len} --gpu-memory-utilization 0.9 --enforce-eager --trust-remote-code -tp 1 --host 0.0.0.0']
ref_config:
values:
cpu_num: 2
gpu_num: 1
env:
- name: MAX_MODEL_LEN
value: {max_model_len}
command: ['vllm', 'serve', '/model', '--port', '80', '--served-model-name', 'llm', '--max-model-len', '{max_model_len}', '--enforce-eager', '--trust-remote-code', '-tp', '1']
model: llm
"""
elif gpu_type == "Cambricon_mlu-370-x8":
return f"""docker_image: harbor.4pd.io/hardcore-tech/cambricon-mlu370-pytorch:v25.01-torch2.5.0-torchmlu1.24.1-ubuntu22.04-py310
nv_docker_image: harbor.4pd.io/dooke/vllm/vllm/vllm-openai:v0.11.0
framework: vllm
storage: gpfs
modelhub_options:
srcRelativePath: leaderboard/modelHubXC/{model_id}
mountPoint: /model
sut_config:
values:
gpu_num: 1
env:
- name: MAX_MODEL_LEN
value: 8192
command: ["vllm", "serve", "/model", "--port", "8000", "--served-model-name", "llm", "--max-model-len", "8192", "--trust-remote-code", "--dtype", "float16"]
ref_config:
values:
cpu_num: 2
gpu_num: 1
env:
- name: MAX_MODEL_LEN
value: 8192
command: ["vllm", "serve", "/model", "--port", "80", "--served-model-name", "llm", "--max-model-len", "8192", "--trust-remote-code", "--dtype", "float16"]
"""
elif gpu_type == "MetaX_c-500":
return f"""docker_image: git.modelhub.org.cn:9443/enginex-metax/vllm:0.9.1
nv_docker_image: harbor.4pd.io/dooke/vllm/vllm/vllm-openai:v0.11.0
framework: vllm
lang: en
storage: gpfs
api: chat
modelhub_options:
srcRelativePath: leaderboard/modelHubXC/{model_id}
mountPoint: /model
max_model_len: 2048
sut_config:
gpu_num: 1
values:
command: ['/opt/conda/bin/vllm', 'serve', '/model', '--port', '20644', '--served-model-name', 'llm', '--max-model-len', '2048', '--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', '2048', '--enforce-eager', '--trust-remote-code', '-tp', '1']
"""
elif gpu_type == "Kunlunxin_p-800":
return 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']
"""
elif gpu_type == "hygon_k100-ai":
return f"""
docker_image: harbor.4pd.io/modelhubxc/enginex-hygon/vllm:0.9.2-patch-tokenizer
nv_docker_image: harbor.4pd.io/modelhubxc/enginex-nvidia/vllm:0.11.0-patch-tokenizer
framework: vllm
storage: gpfs
max_model_len: 4096
sut_config:
gpu_num: 1
values:
command: ['vllm', 'serve', '/model', '--port', '20644', '--served-model-name', 'llm', '--max-model-len', '4096', '--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']
"""
elif gpu_type == "ppu_zw_810e":
return f"""gpu_type: ppu_zw_810e
framework: vllm
docker_image: harbor.4pd.io/hardcore-tech/asllm:1.10.1-pytorch2.10.0-ubuntu24.04-sail2.1.0-cuda13.0-sglang0.5.10-vllm0.19.0-py312
nv_docker_image: harbor-contest.4pd.io/sunruoxi/vllm-openai-fix-tokenizer:v0.11.0
@@ -334,14 +289,14 @@ sut_config:
command:
- bash
- /opt/t-head/entrypoint.sh
- python3
- -m
- asllm.entrypoints.api_server
- --model
- /model
- --port
- python3
- -m
- asllm.entrypoints.api_server
- --model
- /model
- --port
- '30000'
- --host
- --host
- 0.0.0.0
- --served-model-name
- llm
@@ -368,21 +323,67 @@ ref_config:
- -tp
- '1'
"""
elif gpu_type == "Iluvatar_bi-150":
return f"""docker_image: harbor-contest.4pd.io/luopingyi/enginex-iluvatar-bi150/vllm:0.8.3
nv_docker_image: harbor.4pd.io/dooke/vllm/vllm/vllm-openai:v0.11.0
framework: vllm
api: completion
temperature: 0.7
repetition_penalty: 1.2
top_p: 0.9
max_model_len: 4096
max_tokens: 1024
sut_config:
gpu_num: 1
values:
command: ['vllm', 'serve', '/model', '--port', '80', '--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']
"""
else:
raise ValueError(f"未知的 GPU_TYPE: {gpu_type}")
# ══════════════════════════════════════════════════════════
# 业务逻辑
# ══════════════════════════════════════════════════════════
# 账号"等待中/运行中"任务数已达上限时平台返回的业务错误信息(子串匹配);
# 命中这个的模型不算永久失败,会在额度腾出空位后自动重试,不会被记作 failed
QUOTA_FULL_MSG = "当前等待中或运行中的异步模型验证任务数量已达上限"
# 额度耗尽后,隔多久自动重试一次剩余(因额度问题未提交成功)的模型
RETRY_INTERVAL_SECONDS = 30 * 60 # 30 分钟
def _submit_task(token: str, gpu_type: str, model_id: str) -> Tuple[bool, str, str]:
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {token}",
}
config_content = build_config_content(gpu_type, model_id)
payload = {
"contestApiToken": CONTEST_API_TOKEN,
"contributors": CONTRIBUTORS,
"gpuTypes": [GPU_TYPE],
"gpuTypes": [gpu_type],
"taskType": TASK_TYPE,
"modelId": model_id,
"framework": "vllm",
"strategyId": STRATEGY_ID, # 平台要求
"submissionConfig": [{
"config": config_content,
"gpuType": GPU_TYPE,
"gpuType": gpu_type,
"taskType": TASK_TYPE,
}],
}
print(f"[payload] {json.dumps(payload, indent=2, ensure_ascii=False)}", flush=True)
print(f"[payload] gpu={gpu_type} model={model_id}", flush=True)
try:
resp = requests.post(
BASE_URL + SUBMIT_ENDPOINT,
@@ -393,46 +394,88 @@ ref_config:
result = resp.json()
if result.get("code") == 0:
task_id = result.get("data", {}).get("id", "")
print(f"[worker] OK {model_id} task_id={task_id}", flush=True)
return True, task_id
print(f"[worker] OK {model_id} (GPU={gpu_type}) task_id={task_id}", flush=True)
return True, task_id, ""
else:
print(f"[worker] FAIL {model_id}: {result.get('message')}", flush=True)
return False, ""
message = result.get("message") or ""
print(f"[worker] FAIL {model_id} (GPU={gpu_type}): {message}", flush=True)
return False, "", message
except Exception as e:
print(f"[worker] ERROR {model_id}: {e}", flush=True)
return False, ""
print(f"[worker] ERROR {model_id} (GPU={gpu_type}): {e}", flush=True)
return False, "", str(e)
def _run_worker():
_state["started_at"] = datetime.utcnow().isoformat()
_state["phase"] = "submitting"
successful: List[Tuple[str, str]] = []
successful: List[Tuple[str, str, str]] = []
token = AUTH_TOKEN
print("[worker] 使用预设 Token跳过登录", flush=True)
for model_id in ALL_MODEL_IDS:
if _shutdown.is_set():
break
ok, task_id = _submit_task(token, model_id)
if ok:
_state["submitted"] += 1
successful.append((task_id, model_id))
else:
_state["failed"] += 1
# 待提交队列:保持 GPU_JOBS 里原有的 (gpu_type, model_id) 顺序
pending: List[Tuple[str, str]] = [
(gpu_type, model_id)
for gpu_type, model_list in GPU_JOBS
for model_id in model_list
]
# 写入结果文件
try:
with open("submitted_validation_tasks.txt", "w", encoding="utf-8") as f:
for tid, mid in successful:
f.write(f"{tid}\t{mid}\n")
except Exception:
pass
round_num = 0
while pending and not _shutdown.is_set():
round_num += 1
_state["round"] = round_num
_state["phase"] = "submitting"
_state["next_retry_at"] = None
print(
f"\n{'='*60}\n🚀 第 {round_num} 轮,待提交 {len(pending)} 个模型\n{'='*60}",
flush=True,
)
quota_blocked: List[Tuple[str, str]] = []
for gpu_type, model_id in pending:
if _shutdown.is_set():
break
ok, task_id, message = _submit_task(token, gpu_type, model_id)
if ok:
_state["submitted"] += 1
_state["per_gpu"][gpu_type] += 1
successful.append((task_id, gpu_type, model_id))
elif QUOTA_FULL_MSG in message:
# 账号额度暂时满了,不算永久失败,留到下一轮重试
quota_blocked.append((gpu_type, model_id))
else:
# 非额度原因失败(如重复提交等),不再重试
_state["failed"] += 1
pending = quota_blocked
_state["quota_blocked_remaining"] = len(pending)
# 每轮结束都把已成功的结果落盘一次,避免中途重启丢失记录
try:
with open("submitted_validation_tasks.txt", "w", encoding="utf-8") as f:
for tid, gpu, mid in successful:
f.write(f"{tid}\t{gpu}\t{mid}\n")
except Exception:
pass
if pending and not _shutdown.is_set():
next_retry = datetime.utcnow().timestamp() + RETRY_INTERVAL_SECONDS
_state["next_retry_at"] = datetime.utcfromtimestamp(next_retry).isoformat()
_state["phase"] = "waiting_retry"
print(
f"[worker] 第 {round_num} 轮结束:{len(pending)} 个模型因账号额度上限暂未提交,"
f"{RETRY_INTERVAL_SECONDS // 60} 分钟后自动重试(不部署新策略,本进程内循环)...",
flush=True,
)
_shutdown.wait(RETRY_INTERVAL_SECONDS)
_state["finished_at"] = datetime.utcnow().isoformat()
_state["phase"] = "done"
_state["quota_blocked_remaining"] = len(pending)
print(
f"[worker] 完成 submitted={_state['submitted']} failed={_state['failed']}",
f"[worker] 完成 submitted={_state['submitted']} failed={_state['failed']} "
f"total={_state['total']} per_gpu={_state['per_gpu']} "
f"仍因额度未提交(如遇shutdown中断)={len(pending)}",
flush=True,
)
# 提交完成后继续保持进程存活,等待平台停止
@@ -465,4 +508,4 @@ def main():
if __name__ == "__main__":
main()
main()