{"record":{"id":"9ccf8d293df99084","repo":"deepseek-ai/DeepSeek-V3","slug":"number-of-experts-must-be-divisible-by-model-paral","errorCode":null,"errorMessage":"Number of experts must be divisible by model parallelism","messagePattern":"Number of experts must be divisible by model parallelism","errorType":"validation","errorClass":"AssertionError","httpStatus":null,"severity":"error","filePath":"inference/convert.py","lineNumber":95,"sourceCode":"\n    os.makedirs(save_path, exist_ok=True)\n\n    for i in trange(mp):\n        save_file(state_dicts[i], os.path.join(save_path, f\"model{i}-mp{mp}.safetensors\"))\n\n    for file_path in glob(os.path.join(hf_ckpt_path, \"*token*\")):\n        new_file_path = os.path.join(save_path, os.path.basename(file_path))\n        shutil.copyfile(file_path, new_file_path)\n\n\nif __name__ == \"__main__\":\n    parser = ArgumentParser()\n    parser.add_argument(\"--hf-ckpt-path\", type=str, required=True)\n    parser.add_argument(\"--save-path\", type=str, required=True)\n    parser.add_argument(\"--n-experts\", type=int, required=True)\n    parser.add_argument(\"--model-parallel\", type=int, required=True)\n    args = parser.parse_args()\n    assert args.n_experts % args.model_parallel == 0, \"Number of experts must be divisible by model parallelism\"\n    main(args.hf_ckpt_path, args.save_path, args.n_experts, args.model_parallel)\n","sourceCodeStart":77,"sourceCodeEnd":97,"githubUrl":"https://github.com/deepseek-ai/DeepSeek-V3/blob/9b4e9788e4a3a731f7567338ed15d3ec549ce03b/inference/convert.py#L77-L97","documentation":"Thrown in convert.py's __main__ (inference/convert.py:95): experts are distributed round-robin into n_experts // model_parallel local experts per shard file, so --n-experts (256 for DeepSeek-V3 R1/V3) must be divisible by --model-parallel. This is a CLI-level precondition checked before main() runs.","triggerScenarios":"Running convert.py with e.g. --n-experts 256 --model-parallel 6 (256 % 6 != 0), or --n-experts values from a different model variant than the mp degree chosen.","commonSituations":"Picking mp equal to available GPUs without considering expert count; mismatching --n-experts with the actual checkpoint (must equal the checkpoint's routed expert count, e.g. 256, not 257/128).","solutions":["Use --model-parallel in {2,4,8,16,32,64} for n-experts 256","Set --n-experts to the checkpoint's true routed expert count (256 for DeepSeek-V3/R1)","Keep this mp identical to the inference world_size used at generate time"],"exampleFix":"# before\npython convert.py --hf-ckpt-path hf/ --save-path out/ --n-experts 256 --model-parallel 6\n\n# after\npython convert.py --hf-ckpt-path hf/ --save-path out/ --n-experts 256 --model-parallel 8","handlingStrategy":"validation","validationCode":"n_experts, mp = 256, 8\nassert n_experts % mp == 0, (\n    f\"n_experts={n_experts} not divisible by model_parallel={mp}; pick 2/4/8/16\"\n)","typeGuard":"def experts_divide(n_experts: int, mp: int) -> bool:\n    return n_experts % mp == 0","tryCatchPattern":null,"preventionTips":["Pass --n-experts exactly matching the checkpoint (256 for DeepSeek-V3/R1)","Select mp from divisors of the expert count and equal to your GPU count","Script the full convert+launch pipeline so the two values cannot drift"],"tags":["checkpoint-conversion","cli","moe","model-parallelism","deepseek"],"backgroundTag":null,"analyzedSha":"9b4e9788e4a3a731f7567338ed15d3ec549ce03b","analyzedAt":"2026-08-14T19:02:32.748Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}