Skip to content

Commit 2d5410d

Browse files
committed
Merge branch 'main' of https://github.com/NVIDIA-NeMo/Megatron-Bridge into rghadia/nt3-ultra-gtp-cg
Signed-off-by: rghadia <rghadia@nvidia.com>
2 parents cbd1d28 + b1bb0a9 commit 2d5410d

88 files changed

Lines changed: 1331 additions & 577 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.main.commit‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
e0c5e18673bf4d4fd89cf87c4f1afbe521fe297f
1+
e30d863a6d82a3c45f2d71355dc73fbf5610967b

‎docs/_static/model-verification/catalog-v1.json‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5393,21 +5393,21 @@
53935393
"command_topologies": [
53945394
{
53955395
"gpus_per_node": "8",
5396-
"nodes": "24",
5397-
"recipe": "nemotron_3_ultra_sft_192gpu_h100_bf16_openmathinstruct2_packed_config",
5398-
"total_gpus": 192
5396+
"nodes": "48",
5397+
"recipe": "nemotron_3_ultra_sft_384gpu_h100_bf16_openmathinstruct2_packed_config",
5398+
"total_gpus": 384
53995399
}
54005400
],
54015401
"commands": [
5402-
"./scripts/training/train.sh --nodes 24 --gpus-per-node 8 --recipe nemotron_3_ultra_sft_192gpu_h100_bf16_openmathinstruct2_packed_config --mode sft --wait --pretrained_checkpoint work/model-verification/nemotron-3-ultra-550b-a55b/imported-megatron/iter_0000000 --max_steps 100 --warmup_iters 10 scheduler.lr_decay_iters=100 'dataset.hf_dataset.split=\"train_1M[:10%]\"' 'dataset.hf_dataset.load_kwargs={revision:\"469216e3f46f4dacf476b382e192485ea51a143e\"}' dataset.hf_output_root=work/data/openmathinstruct2-ultra-4096-v1 dataset.seed=1234 dataset.offline_packing_specs.pad_seq_to_mult=2 validation.eval_iters=0 validation.eval_interval=0 --save_dir work/model-verification/nemotron-3-ultra-550b-a55b/sft-checkpoints --save_interval 100 ddp.check_for_nan_in_grad=true ddp.check_for_large_grads=true rerun_state_machine.check_for_nan_in_loss=true logger.log_interval=1 logger.log_throughput=true logger.save_config_filepath=work/model-verification/nemotron-3-ultra-550b-a55b/sft-resolved.yaml logger.tensorboard_dir=null"
5402+
"./scripts/training/train.sh --nodes 48 --gpus-per-node 8 --recipe nemotron_3_ultra_sft_384gpu_h100_bf16_openmathinstruct2_packed_config --mode sft --wait --pretrained_checkpoint work/model-verification/nemotron-3-ultra-550b-a55b/imported-megatron/iter_0000000 --max_steps 100 --warmup_iters 10 scheduler.lr_decay_iters=100 'dataset.hf_dataset.split=\"train_1M[:10%]\"' 'dataset.hf_dataset.load_kwargs={revision:\"469216e3f46f4dacf476b382e192485ea51a143e\"}' dataset.hf_output_root=work/data/openmathinstruct2-ultra-4096-v1 dataset.seed=1234 dataset.offline_packing_specs.pad_seq_to_mult=2 validation.eval_iters=0 validation.eval_interval=0 --save_dir work/model-verification/nemotron-3-ultra-550b-a55b/sft-checkpoints --save_interval 100 ddp.check_for_nan_in_grad=true ddp.check_for_large_grads=true rerun_state_machine.check_for_nan_in_loss=true logger.log_interval=1 logger.log_throughput=true logger.save_config_filepath=work/model-verification/nemotron-3-ultra-550b-a55b/sft-resolved.yaml logger.tensorboard_dir=null"
54035403
],
54045404
"dimensions": {},
54055405
"enabled_features": {
54065406
"moe_dispatcher": "hybridep",
54075407
"sequence_packing": "offline"
54085408
},
54095409
"entry_id": "nemotron-3-ultra-550b-a55b-sft-h100",
5410-
"expected_result": "The public 192-H100 packed OpenMathInstruct-2 full-SFT recipe must use the pinned dataset revision and bounded train_1M first-ten-percent selection, complete 100 optimizer steps at sequence length 4096 and GBS/MBS 128/1, and preserve pad_seq_to_mult 2. This published Ultra contract is support verification rather than the 8K/GBS8 qwen3_30b_a3b_convergence_v2 cohort. Loss must remain finite with no skipped or NaN iterations, all five metrics, a persisted post-setup configuration, audited supervised-token counts, and a complete reloadable final checkpoint.\n",
5410+
"expected_result": "The public 384-H100 packed OpenMathInstruct-2 full-SFT recipe must use the pinned dataset revision and bounded train_1M first-ten-percent selection, complete 100 optimizer steps at sequence length 4096 and GBS/MBS 128/1, and preserve pad_seq_to_mult 2. This published Ultra contract is support verification rather than the 8K/GBS8 qwen3_30b_a3b_convergence_v2 cohort. Loss must remain finite with no skipped or NaN iterations, all five metrics, a persisted post-setup configuration, audited supervised-token counts, and a complete reloadable final checkpoint.\n",
54115411
"hardware": "H100",
54125412
"last_verified": null,
54135413
"metrics": {

‎docs/bridge-guide.md‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,12 @@ family's Megatron Core `ModelBuilder`, such as `GPTModelBuilder` or
115115
while other model families migrate. Calling the legacy provider API for a
116116
builder-backed family emits a deprecation warning.
117117

118+
The builder path is opt-in per family: a bridge opts in by setting
119+
`MODEL_CONFIG_CLASS`, which defaults to `None`. For a family that has not
120+
migrated, `get_model_config()` raises `ModelConfigNotSupportedError` and
121+
`to_megatron_provider()` remains the supported path, without a deprecation
122+
warning.
123+
118124
```python
119125
from megatron.bridge import AutoBridge
120126

‎docs/fern/versions/nightly/pages/models/nemotron/nemotron3-ultra.mdx‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -408,12 +408,12 @@ Choose a workflow, precision, and exact recorded combination. The command and ex
408408
<span>Command</span>
409409
<button type="button" class="verification-copy-command">Copy</button>
410410
</div>
411-
<pre><code class="language-bash">./scripts/training/train.sh --nodes 24 --gpus-per-node 8 --recipe nemotron_3_ultra_sft_192gpu_h100_bf16_openmathinstruct2_packed_config --mode sft --wait --pretrained_checkpoint work/model-verification/nemotron-3-ultra-550b-a55b/imported-megatron/iter_0000000 --max_steps 100 --warmup_iters 10 scheduler.lr_decay_iters=100 &#x27;dataset.hf_dataset.split=&quot;train_1M[:10%]&quot;&#x27; &#x27;dataset.hf_dataset.load_kwargs=&#123;revision:&quot;469216e3f46f4dacf476b382e192485ea51a143e&quot;&#125;&#x27; dataset.hf_output_root=work/data/openmathinstruct2-ultra-4096-v1 dataset.seed=1234 dataset.offline_packing_specs.pad_seq_to_mult=2 validation.eval_iters=0 validation.eval_interval=0 --save_dir work/model-verification/nemotron-3-ultra-550b-a55b/sft-checkpoints --save_interval 100 ddp.check_for_nan_in_grad=true ddp.check_for_large_grads=true rerun_state_machine.check_for_nan_in_loss=true logger.log_interval=1 logger.log_throughput=true logger.save_config_filepath=work/model-verification/nemotron-3-ultra-550b-a55b/sft-resolved.yaml logger.tensorboard_dir=null</code></pre>
411+
<pre><code class="language-bash">./scripts/training/train.sh --nodes 48 --gpus-per-node 8 --recipe nemotron_3_ultra_sft_384gpu_h100_bf16_openmathinstruct2_packed_config --mode sft --wait --pretrained_checkpoint work/model-verification/nemotron-3-ultra-550b-a55b/imported-megatron/iter_0000000 --max_steps 100 --warmup_iters 10 scheduler.lr_decay_iters=100 &#x27;dataset.hf_dataset.split=&quot;train_1M[:10%]&quot;&#x27; &#x27;dataset.hf_dataset.load_kwargs=&#123;revision:&quot;469216e3f46f4dacf476b382e192485ea51a143e&quot;&#125;&#x27; dataset.hf_output_root=work/data/openmathinstruct2-ultra-4096-v1 dataset.seed=1234 dataset.offline_packing_specs.pad_seq_to_mult=2 validation.eval_iters=0 validation.eval_interval=0 --save_dir work/model-verification/nemotron-3-ultra-550b-a55b/sft-checkpoints --save_interval 100 ddp.check_for_nan_in_grad=true ddp.check_for_large_grads=true rerun_state_machine.check_for_nan_in_loss=true logger.log_interval=1 logger.log_throughput=true logger.save_config_filepath=work/model-verification/nemotron-3-ultra-550b-a55b/sft-resolved.yaml logger.tensorboard_dir=null</code></pre>
412412
</div>
413413
</section>
414414
<section class="verification-expected-result">
415415
<h5>Expected result</h5>
416-
<p>The public 192-H100 packed OpenMathInstruct-2 full-SFT recipe must use the pinned dataset revision and bounded train_1M first-ten-percent selection, complete 100 optimizer steps at sequence length 4096 and GBS/MBS 128/1, and preserve pad_seq_to_mult 2. This published Ultra contract is support verification rather than the 8K/GBS8 qwen3_30b_a3b_convergence_v2 cohort. Loss must remain finite with no skipped or NaN iterations, all five metrics, a persisted post-setup configuration, audited supervised-token counts, and a complete reloadable final checkpoint.</p>
416+
<p>The public 384-H100 packed OpenMathInstruct-2 full-SFT recipe must use the pinned dataset revision and bounded train_1M first-ten-percent selection, complete 100 optimizer steps at sequence length 4096 and GBS/MBS 128/1, and preserve pad_seq_to_mult 2. This published Ultra contract is support verification rather than the 8K/GBS8 qwen3_30b_a3b_convergence_v2 cohort. Loss must remain finite with no skipped or NaN iterations, all five metrics, a persisted post-setup configuration, audited supervised-token counts, and a complete reloadable final checkpoint.</p>
417417
</section>
418418
</article>
419419
<article id="nemotron-3-ultra-550b-a55b-sft-gb200" class="verification-model-detail" data-entry-detail="nemotron-3-ultra-550b-a55b-sft-gb200" tabindex="-1">

‎docs/models/nemotron/nemotron3-ultra.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -414,12 +414,12 @@ Choose a workflow, precision, and exact recorded combination. The command and ex
414414
<span>Command</span>
415415
<button type="button" class="verification-copy-command">Copy</button>
416416
</div>
417-
<pre><code class="language-bash">./scripts/training/train.sh --nodes 24 --gpus-per-node 8 --recipe nemotron_3_ultra_sft_192gpu_h100_bf16_openmathinstruct2_packed_config --mode sft --wait --pretrained_checkpoint work/model-verification/nemotron-3-ultra-550b-a55b/imported-megatron/iter_0000000 --max_steps 100 --warmup_iters 10 scheduler.lr_decay_iters=100 &#x27;dataset.hf_dataset.split=&quot;train_1M[:10%]&quot;&#x27; &#x27;dataset.hf_dataset.load_kwargs={revision:&quot;469216e3f46f4dacf476b382e192485ea51a143e&quot;}&#x27; dataset.hf_output_root=work/data/openmathinstruct2-ultra-4096-v1 dataset.seed=1234 dataset.offline_packing_specs.pad_seq_to_mult=2 validation.eval_iters=0 validation.eval_interval=0 --save_dir work/model-verification/nemotron-3-ultra-550b-a55b/sft-checkpoints --save_interval 100 ddp.check_for_nan_in_grad=true ddp.check_for_large_grads=true rerun_state_machine.check_for_nan_in_loss=true logger.log_interval=1 logger.log_throughput=true logger.save_config_filepath=work/model-verification/nemotron-3-ultra-550b-a55b/sft-resolved.yaml logger.tensorboard_dir=null</code></pre>
417+
<pre><code class="language-bash">./scripts/training/train.sh --nodes 48 --gpus-per-node 8 --recipe nemotron_3_ultra_sft_384gpu_h100_bf16_openmathinstruct2_packed_config --mode sft --wait --pretrained_checkpoint work/model-verification/nemotron-3-ultra-550b-a55b/imported-megatron/iter_0000000 --max_steps 100 --warmup_iters 10 scheduler.lr_decay_iters=100 &#x27;dataset.hf_dataset.split=&quot;train_1M[:10%]&quot;&#x27; &#x27;dataset.hf_dataset.load_kwargs={revision:&quot;469216e3f46f4dacf476b382e192485ea51a143e&quot;}&#x27; dataset.hf_output_root=work/data/openmathinstruct2-ultra-4096-v1 dataset.seed=1234 dataset.offline_packing_specs.pad_seq_to_mult=2 validation.eval_iters=0 validation.eval_interval=0 --save_dir work/model-verification/nemotron-3-ultra-550b-a55b/sft-checkpoints --save_interval 100 ddp.check_for_nan_in_grad=true ddp.check_for_large_grads=true rerun_state_machine.check_for_nan_in_loss=true logger.log_interval=1 logger.log_throughput=true logger.save_config_filepath=work/model-verification/nemotron-3-ultra-550b-a55b/sft-resolved.yaml logger.tensorboard_dir=null</code></pre>
418418
</div>
419419
</section>
420420
<section class="verification-expected-result">
421421
<h5>Expected result</h5>
422-
<p>The public 192-H100 packed OpenMathInstruct-2 full-SFT recipe must use the pinned dataset revision and bounded train_1M first-ten-percent selection, complete 100 optimizer steps at sequence length 4096 and GBS/MBS 128/1, and preserve pad_seq_to_mult 2. This published Ultra contract is support verification rather than the 8K/GBS8 qwen3_30b_a3b_convergence_v2 cohort. Loss must remain finite with no skipped or NaN iterations, all five metrics, a persisted post-setup configuration, audited supervised-token counts, and a complete reloadable final checkpoint.
422+
<p>The public 384-H100 packed OpenMathInstruct-2 full-SFT recipe must use the pinned dataset revision and bounded train_1M first-ten-percent selection, complete 100 optimizer steps at sequence length 4096 and GBS/MBS 128/1, and preserve pad_seq_to_mult 2. This published Ultra contract is support verification rather than the 8K/GBS8 qwen3_30b_a3b_convergence_v2 cohort. Loss must remain finite with no skipped or NaN iterations, all five metrics, a persisted post-setup configuration, audited supervised-token counts, and a complete reloadable final checkpoint.
423423
</p>
424424
</section>
425425
</article>

‎examples/model_verification_cards/nemotron-3-ultra-550b-a55b/card.yaml‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -269,8 +269,8 @@ items:
269269
sequence_packing: offline
270270
moe_dispatcher: hybridep
271271
command: >
272-
./scripts/training/train.sh --nodes 24 --gpus-per-node 8
273-
--recipe nemotron_3_ultra_sft_192gpu_h100_bf16_openmathinstruct2_packed_config
272+
./scripts/training/train.sh --nodes 48 --gpus-per-node 8
273+
--recipe nemotron_3_ultra_sft_384gpu_h100_bf16_openmathinstruct2_packed_config
274274
--mode sft --wait
275275
--pretrained_checkpoint work/model-verification/nemotron-3-ultra-550b-a55b/imported-megatron/iter_0000000
276276
--max_steps 100
@@ -296,7 +296,7 @@ items:
296296
last_10_steps_model_tflops_per_gpu_avg: null
297297
last_10_steps_tokens_per_second_per_gpu_avg: null
298298
expected_result: >
299-
The public 192-H100 packed OpenMathInstruct-2 full-SFT recipe must use
299+
The public 384-H100 packed OpenMathInstruct-2 full-SFT recipe must use
300300
the pinned dataset revision and bounded train_1M first-ten-percent
301301
selection, complete 100 optimizer steps at sequence length 4096 and
302302
GBS/MBS 128/1, and preserve pad_seq_to_mult 2. This published Ultra

‎examples/models/nemotron/nemotron_3_ultra/README.md‎

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ environment variables to the GB200 values in this table.
4848
| Checkpoint import | 1 node with `convert.sh --device cpu` | 6 nodes with `convert.sh --device gpu`, `TP=1 PP=6 EP=4` |
4949
| Base inference | 4 nodes, `TP=1 PP=4 EP=8`, `KV_CACHE_BUFFER_SIZE_GB=4` | 3 nodes, `TP=1 PP=3 EP=4` |
5050
| DCLM pretraining | 48 nodes, `TP=4 PP=12 EP=16`, full uniform recompute with `RECOMPUTE_GRANULARITY=full RECOMPUTE_METHOD=uniform RECOMPUTE_NUM_LAYERS=1 RECOMPUTE_MODULES=""` | 24 nodes, `TP=2 PP=3 EP=32`, selective recompute on `moe+layernorm+core_attn+moe_act+mlp+shared_experts` |
51-
| OpenMath SFT | 48 nodes, `TP=2 PP=12 EP=16`, full uniform recompute with `RECOMPUTE_GRANULARITY=full RECOMPUTE_METHOD=uniform RECOMPUTE_NUM_LAYERS=1 RECOMPUTE_MODULES=""` | 48 nodes, `TP=2 PP=3 EP=32`, selective recompute on `moe+layernorm+core_attn+moe_act` |
51+
| OpenMath SFT | 48 nodes, `TP=2 PP=12 EP=16`, the recipe's selective recompute on `moe+core_attn+moe_act` | 48 nodes, `TP=2 PP=3 EP=32`, the recipe's selective recompute on `moe+core_attn+moe_act` |
5252
| OpenMath PEFT | 4 nodes, `TP=2 PP=4 EP=8`, selective recompute on `moe+layernorm+core_attn+moe_act+mlp+shared_experts` | 4 nodes, `TP=2 PP=1 EP=16`, selective recompute on `moe+layernorm+core_attn+moe_act` |
5353

5454
These are bring-up and convergence starting points, not universal optima.
@@ -173,17 +173,22 @@ Current OpenMath starting points are:
173173

174174
- PEFT: 4 nodes, `TP=2 PP=4 EP=8`, selective recompute on
175175
`moe+layernorm+core_attn+moe_act+mlp+shared_experts`.
176-
- Full SFT: 48 nodes, `TP=2 PP=12 EP=16`, full uniform recompute with
177-
`RECOMPUTE_GRANULARITY=full RECOMPUTE_METHOD=uniform
178-
RECOMPUTE_NUM_LAYERS=1 RECOMPUTE_MODULES=""`. This is the current H100
179-
starting point for 4096-token packed OpenMath SFT.
176+
- Full SFT: 48 nodes, `TP=2 PP=12 EP=16`, the recipe's selective recompute on
177+
`moe+core_attn+moe_act`. These are the recipe defaults and the current H100
178+
starting point for 4096-token packed OpenMath SFT. On Transformer Engine 2.18
179+
and later, a TE norm that is a pipeline stage's first backward operation fails
180+
with `invalid device context`, so the recipe does not recompute the pre-MLP
181+
norms and sets `NVTE_NORM_FWD_USE_CUDNN=1` and `NVTE_NORM_BWD_USE_CUDNN=1` to
182+
use cuDNN normalization kernels. The recipe places 5 decoder layers on the
183+
last pipeline stage, which also holds the output layer and MTP, and 9 to 11 on
184+
the others; when changing `PP`, also override `model.hybrid_layer_pattern`.
180185

181186
For 4xGB200 nodes:
182187

183188
- PEFT: 4 nodes, `TP=2 PP=1 EP=16`, selective recompute on
184189
`moe+layernorm+core_attn+moe_act`.
185-
- Full SFT: 48 nodes, `TP=2 PP=3 EP=32`, selective recompute on
186-
`moe+layernorm+core_attn+moe_act`.
190+
- Full SFT: 48 nodes, `TP=2 PP=3 EP=32`, the recipe's selective recompute on
191+
`moe+core_attn+moe_act`.
187192

188193
Advanced VPP, pipeline-layout, and recompute sweeps are intentionally left out
189194
of these starter scripts; add those overrides only for targeted performance

‎examples/models/nemotron/nemotron_3_ultra/slurm_sft.sh‎

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -91,13 +91,14 @@ if [ -z "$PAD_SEQ_TO_MULT" ]; then
9191
fi
9292
fi
9393

94-
RECOMPUTE_GRANULARITY=${RECOMPUTE_GRANULARITY:-full}
95-
RECOMPUTE_METHOD=${RECOMPUTE_METHOD:-uniform}
94+
# Leave these empty to use the recipe's selective recompute; set them to override it.
95+
RECOMPUTE_GRANULARITY=${RECOMPUTE_GRANULARITY:-}
96+
RECOMPUTE_METHOD=${RECOMPUTE_METHOD:-}
9697
if [ -z "${RECOMPUTE_MODULES+x}" ]; then
9798
RECOMPUTE_MODULES=""
9899
fi
99-
RECOMPUTE_NUM_LAYERS=${RECOMPUTE_NUM_LAYERS:-1}
100-
RECOMPUTE_TAG=${RECOMPUTE_TAG:-recompute_full_uniform1}
100+
RECOMPUTE_NUM_LAYERS=${RECOMPUTE_NUM_LAYERS:-}
101+
RECOMPUTE_TAG=${RECOMPUTE_TAG:-recompute_${RECOMPUTE_GRANULARITY:-recipe}}
101102

102103
WANDB_ENTITY=${WANDB_ENTITY:-nvidia-nemo-fw-public}
103104
WANDB_PROJECT=${WANDB_PROJECT:-megatron-bridge-nemotron-ultra}
@@ -171,9 +172,11 @@ CLI_OVERRIDES="\
171172
dataset.seq_length=${SEQ_LENGTH} \
172173
dataset.offline_packing_specs.packed_sequence_size=${SEQ_LENGTH} \
173174
dataset.offline_packing_specs.pad_seq_to_mult=${PAD_SEQ_TO_MULT} \
174-
model.recompute_granularity=${RECOMPUTE_GRANULARITY} \
175175
dist.distributed_timeout_minutes=90"
176176

177+
if [ -n "$RECOMPUTE_GRANULARITY" ]; then
178+
CLI_OVERRIDES="${CLI_OVERRIDES} model.recompute_granularity=${RECOMPUTE_GRANULARITY}"
179+
fi
177180
if [ -n "$RECOMPUTE_METHOD" ]; then
178181
CLI_OVERRIDES="${CLI_OVERRIDES} model.recompute_method=${RECOMPUTE_METHOD}"
179182
fi
@@ -205,7 +208,7 @@ echo "GPUs/node: ${GPUS_PER_NODE}"
205208
echo "Recipe: ${RECIPE_NAME}"
206209
echo "Parallelism: TP=${TP} PP=${PP} EP=${EP} ETP=${ETP} CP=${CP} SP=${SP}"
207210
echo "Packed pad_seq_to_mult: ${PAD_SEQ_TO_MULT}"
208-
echo "Recompute: ${RECOMPUTE_GRANULARITY} ${RECOMPUTE_METHOD:-} ${RECOMPUTE_MODULES}"
211+
echo "Recompute: ${RECOMPUTE_GRANULARITY:-recipe default} ${RECOMPUTE_METHOD:-} ${RECOMPUTE_MODULES}"
209212
echo "Save dir: ${SAVE_DIR}"
210213
echo "W&B: ${WANDB_ENTITY}/${WANDB_PROJECT} (${WANDB_MODE})"
211214
echo "======================================"

‎pyproject.toml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ requires-dist = []
171171
# MCore pin's metadata so a lock-only operation never invokes the build backend.
172172
[[tool.uv.dependency-metadata]]
173173
name = "transformer-engine"
174-
version = "2.20.2+6ea2a74a"
174+
version = "2.20.2+44f31bbe"
175175
requires-dist = [
176176
"pydantic<2.14",
177177
"importlib-metadata>=1.0",

0 commit comments

Comments
 (0)