Add a general composable $import system for YAML configs, and use it to implement composable recipes#1253
Conversation
|
Auto-sync is disabled for draft pull requests in this repository. Workflows must be run manually. Contributors can view more details about this message here. |
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughAdds a composable YAML imports system ( Changes
Sequence Diagram(s)sequenceDiagram
participant U as User
participant L as modelopt.recipe.loader
participant R as _load_raw_config
participant S as _resolve_imports
participant FS as Files / Builtins
U->>L: load_recipe(path)
L->>R: _load_raw_config(path)
R->>FS: read YAML (file or builtin)
FS-->>R: raw documents
R-->>L: parsed raw config (may include imports)
alt imports present
L->>S: _resolve_imports(parsed_config)
S->>R: _load_raw_config(import_path)
R->>FS: read imported snippet
FS-->>R: snippet content
R-->>S: snippet (dict/list/_list_content)
S->>S: merge / splice / detect circular refs
S-->>L: resolved config
end
L-->>U: final resolved recipe
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes 🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Tip 💬 Introducing Slack Agent: The best way for teams to turn conversations into code.Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.
Built for teams:
One agent for your entire SDLC. Right inside Slack. Comment |
|
Commit description:
Introduce an import mechanism that lets recipe YAML files reference reusable
config snippets by name, reducing duplication across recipes.
Syntax:
imports:
fp8: configs/numerics/fp8
base_disable_all: configs/ptq/base_disable_all
quant_cfg:
- base_disable_all # string entry → replaced with imported dict or spliced
list
- quantizer_name: '*weight_quantizer'
cfg: fp8 # string cfg → replaced with imported dict
Features:
- Dict-based imports (keys are names, values are config paths) — no name conflicts
- Three resolution modes: string cfg value, string list entry (dict), string list entry (list
splice)
- Recursive resolution with circular import detection
- Path resolution via load_config (built-in library first, then filesystem)
- Works with both single-file and directory recipe formats
New reusable config snippets (modelopt_recipes/configs/):
- numerics/fp8.yml, nvfp4_dynamic.yml, nvfp4_static.yml
- ptq/base_disable_all.yaml, default_disabled_quantizers.yaml
All 6 built-in PTQ recipes converted to use imports, reducing each by ~30 lines.
Pre-commit hook updated to skip configs/ directory and allow string entries in
quant_cfg. load_config() now accepts YAML lists for list-valued snippets.
Signed-off-by: Shengliang Xu <shengliangx@nvidia.com>
Signed-off-by: Shengliang Xu <shengliangx@nvidia.com>
Signed-off-by: Shengliang Xu <shengliangx@nvidia.com>
Signed-off-by: Shengliang Xu <shengliangx@nvidia.com>
Signed-off-by: Shengliang Xu <shengliangx@nvidia.com>
Signed-off-by: Shengliang Xu <shengliangx@nvidia.com>
Signed-off-by: Shengliang Xu <shengliangx@nvidia.com>
Signed-off-by: Shengliang Xu <shengliangx@nvidia.com>
Signed-off-by: Shengliang Xu <shengliangx@nvidia.com>
Signed-off-by: Shengliang Xu <shengliangx@nvidia.com>
Signed-off-by: Shengliang Xu <shengliangx@nvidia.com>
Signed-off-by: Shengliang Xu <shengliangx@nvidia.com>
Signed-off-by: Shengliang Xu <shengliangx@nvidia.com>
Signed-off-by: Shengliang Xu <shengliangx@nvidia.com>
Signed-off-by: Shengliang Xu <shengliangx@nvidia.com>
ea910ae to
82d5a12
Compare
Signed-off-by: Shengliang Xu <shengliangx@nvidia.com>
Signed-off-by: Shengliang Xu <shengliangx@nvidia.com>
Signed-off-by: Shengliang Xu <shengliangx@nvidia.com>
Signed-off-by: Shengliang Xu <shengliangx@nvidia.com>
Signed-off-by: Shengliang Xu <shengliangx@nvidia.com>
Signed-off-by: Shengliang Xu <shengliangx@nvidia.com>
Signed-off-by: Shengliang Xu <shengliangx@nvidia.com>
Signed-off-by: Shengliang Xu <shengliangx@nvidia.com>
it is not in use, so safe to change Signed-off-by: Shengliang Xu <shengliangx@nvidia.com>
these classes are not in use outside of the codebase so safe to change Signed-off-by: Shengliang Xu <shengliangx@nvidia.com>
Signed-off-by: Shengliang Xu <shengliangx@nvidia.com>
Signed-off-by: Shengliang Xu <shengliangx@nvidia.com>
Signed-off-by: Shengliang Xu <shengliangx@nvidia.com>
Signed-off-by: Shengliang Xu <shengliangx@nvidia.com>
Signed-off-by: Shengliang Xu <shengliangx@nvidia.com>
…e-recipes Signed-off-by: Shengliang Xu <shengliangx@nvidia.com>
Signed-off-by: Shengliang Xu <shengliangx@nvidia.com>
Signed-off-by: Shengliang Xu <shengliangx@nvidia.com>
Signed-off-by: Shengliang Xu <shengliangx@nvidia.com>
What does this PR do?
Type of change: New feature
Adds a general composable YAML config loading layer for ModelOpt configs and recipes. YAML remains the source of truth for configuration data, while Python/Pydantic-compatible types provide schema validation at load time. This PR uses that loader to de-duplicate PTQ recipes, introduce reusable config snippets/presets, and start migrating selected hardcoded quantization presets to YAML.
Problem
modelopt.torch.quantization.configcould not depend onmodelopt.recipewithout creating circular imports.recipe.yamlplus nestedmetadata:in a way that made metadata handling inconsistent.Solution
Shared YAML config loader
modelopt.torch.opt.config_loaderas the low-level loader used by bothmodelopt.recipeandmodelopt.torch.quantization.config.modelopt.recipe.load_config()entry point, while removing the privatemodelopt/recipe/_config_loader.pyshim.ExMyconversion fornum_bits/scale_bits,$importexpansion, and schema validation.modelopt.recipein the dependency graph to avoid circular imports from quantization config code.Composable
$importsystemRecipes and snippets can declare an
importsmapping, then reference entries with{$import: name}.$importsemantics:importsheader plus a list body.Snippet schema validation
importsmust declare a# modelopt-schema: ...preamble.modelopt.package and may be Pydantic models,TypedDictclasses, or explicitly typed container aliases such aslist[QuantizerCfgEntry].Recipe model and directory recipe cleanup
ModelOptRecipeBasenow owns ametadata: RecipeMetadataConfigfield.ModelOptPTQRecipeis the PTQ recipe schema; the overlapping YAML-specific PTQ config class was removed.metadata.yaml/metadata.ymlfor top-level metadata fields, plus section files such asquantize.yaml.load_config()instead of manually using raw config loading.Config snippet and preset library
Adds reusable snippets under
modelopt_recipes/configs/:numerics/:fp8,nvfp4,nvfp4_staticptq/units/:base_disable_all,default_disabled_quantizers,w8a8_fp8_fp8,w4a4_nvfp4_nvfp4,kv_fp8,kv_fp8_cast,kv_nvfp4_castptq/presets/: YAML presets forFP8_DEFAULT_CFGandFP8_KV_CFGFP8_DEFAULT_CFGandFP8_KV_CFGnow load from YAML presets viaload_config().Recipe migration and naming
general/ptq/fp8_default-fp8_kv->general/ptq/fp8_default-kv_fp8general/ptq/fp8_default-fp8_cast_kv->general/ptq/fp8_default-kv_fp8_castgeneral/ptq/nvfp4_default-none_kv_gptq->general/ptq/nvfp4_default-kv_none-gptqgeneral/ptq/nvfp4_default-nvfp4_cast_kv->general/ptq/nvfp4_default-kv_nvfp4_castexamples/llm_ptq/hf_ptq.py --recipehelp text were updated to use the new paths.Pre-commit and documentation
$importentries and handles directory recipes usingmetadata.yaml.modelopt_recipes/configs/because those files are reusable snippets, not full recipes.docs/source/guides/10_recipes.rstnow documents imports, schema modelines, list append/splice semantics, built-in snippets, built-in recipe paths, directory recipes, and the current recipe data model.Backward compatibility
$importcontinue to load.modelopt.recipe.load_config()remains public.Testing
pytest tests/unit/recipe/test_loader.py -q- 90 passedpython tools/precommit/check_modelopt_recipes.py ...for the renamed built-in PTQ recipespre-commit run mypy --files modelopt/onnx/llm_export_utils/quantization_utils.pypython -m py_compile examples/llm_ptq/hf_ptq.pygit diff --checkBefore your PR is "Ready for review"