{"record":{"id":"c58cca823f0b5e5c","repo":"hiyouga/LlamaFactory","slug":"recompute-granularity-must-be-full-or-selecti","errorCode":null,"errorMessage":"`recompute_granularity` must be 'full' or 'selective'.","messagePattern":"`recompute_granularity` must be 'full' or 'selective'\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/llamafactory/hparams/megatron_bridge_args.py","lineNumber":166,"sourceCode":"            )\n        },\n    )\n\n    def __post_init__(self) -> None:\n        if self.tensor_model_parallel_size < 1:\n            raise ValueError(\"`tensor_model_parallel_size` must be >= 1.\")\n        if self.pipeline_model_parallel_size < 1:\n            raise ValueError(\"`pipeline_model_parallel_size` must be >= 1.\")\n        if self.expert_model_parallel_size < 1:\n            raise ValueError(\"`expert_model_parallel_size` must be >= 1.\")\n        if self.context_parallel_size < 1:\n            raise ValueError(\"`context_parallel_size` must be >= 1.\")\n        if self.virtual_pipeline_model_parallel_size is not None and self.virtual_pipeline_model_parallel_size < 1:\n            raise ValueError(\"`virtual_pipeline_model_parallel_size` must be >= 1 when set.\")\n        if self.sequence_parallel and self.tensor_model_parallel_size <= 1:\n            raise ValueError(\"`sequence_parallel` requires `tensor_model_parallel_size` > 1.\")\n        if self.recompute_granularity is not None and self.recompute_granularity not in (\"full\", \"selective\"):\n            raise ValueError(\"`recompute_granularity` must be 'full' or 'selective'.\")\n        if self.recompute_method is not None and self.recompute_method not in (\"uniform\", \"block\"):\n            raise ValueError(\"`recompute_method` must be 'uniform' or 'block'.\")\n        if self.recompute_num_layers is not None and self.recompute_num_layers < 1:\n            raise ValueError(\"`recompute_num_layers` must be >= 1 when set.\")\n        if self.moe_token_dispatcher_type is not None and self.moe_token_dispatcher_type not in (\n            \"allgather\",\n            \"alltoall\",\n            \"flex\",\n        ):\n            raise ValueError(\"`moe_token_dispatcher_type` must be 'allgather', 'alltoall', or 'flex'.\")\n\n        if isinstance(self.extra_config, str):\n            config_str = self.extra_config.strip()\n            if config_str.startswith(\"{\"):\n                self.extra_config = _convert_str_dict(json.loads(config_str))\n            else:\n                self.extra_config = config_str\n","sourceCodeStart":148,"sourceCodeEnd":184,"githubUrl":"https://github.com/hiyouga/LlamaFactory/blob/f28afaf6355af515454dfb16c97d728307c93897/src/llamafactory/hparams/megatron_bridge_args.py#L148-L184","documentation":"Raised in MegatronBridgeArguments.__post_init__ (megatron_bridge_args.py:166) when recompute_granularity is set to a string other than 'full' or 'selective'. These are the only two activation-recompute granularities Megatron-core supports: 'full' recomputes every layer, 'selective' recomputes only attention/MLP cores. The validation is an exact, case-sensitive string match.","triggerScenarios":"Passing recompute_granularity: Full (capitalized), 'FULL', 'layer', or a typo such as 'selectiev'; passing a value accepted by a different Megatron fork but not this whitelist.","commonSituations":"Copy-pasting from Megatron-LM docs or NVIDIA scripts that use different casing; hand-typing the value; configs migrated between LlamaFactory versions where accepted vocabularies drifted.","solutions":["Use exactly 'full' or 'selective' (lowercase) for recompute_granularity","If you meant per-layer counting, keep recompute_granularity plus recompute_method/recompute_num_layers with valid values","Remove the key to accept the default behavior"],"exampleFix":"# before\nrecompute_granularity: Full\n\n# after\nrecompute_granularity: full","handlingStrategy":"validation","validationCode":"if cfg.get('recompute_granularity') not in (None, 'full', 'selective'):\n    raise SystemExit(f\"bad recompute_granularity: {cfg['recompute_granularity']!r}\")","typeGuard":"def is_valid_granularity(v: str | None) -> bool:\n    return v in (None, 'full', 'selective')","tryCatchPattern":"try:\n    args = MegatronBridgeArguments(**cfg)\nexcept ValueError as e:\n    if 'recompute_granularity' in str(e):\n        cfg['recompute_granularity'] = 'selective'  # or 'full'\n        args = MegatronBridgeArguments(**cfg)\n    else:\n        raise","preventionTips":["Copy enum-like values from this repo's source/tests, not from upstream Megatron docs","Keep recompute_* keys lowercase and grouped together"],"tags":["megatron","activation-checkpointing","config-validation"],"backgroundTag":null,"analyzedSha":"f28afaf6355af515454dfb16c97d728307c93897","analyzedAt":"2026-08-14T21:57:28.298Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}