|
1 | 1 | # Copyright (c) 2026, NVIDIA CORPORATION. All rights reserved. |
2 | 2 | """K3 recipe integration without checkpoint downloads or model allocations.""" |
3 | 3 |
|
| 4 | +from dataclasses import replace |
4 | 5 | from unittest.mock import MagicMock |
5 | 6 |
|
6 | 7 | import pytest |
|
9 | 10 | from megatron.bridge.models.kimi.kimi_k3_provider import KimiK3ModelProvider |
10 | 11 | from megatron.bridge.recipes.kimi import kimi_k3 |
11 | 12 | from megatron.bridge.recipes.kimi.kimi_k3_runtime import configure_kimi_k3_kernels |
| 13 | +from megatron.bridge.training.tokenizers.config import TokenizerConfig |
| 14 | +from megatron.bridge.training.utils.omegaconf_utils import process_config_with_overrides |
12 | 15 |
|
13 | 16 |
|
14 | 17 | @pytest.fixture |
@@ -64,3 +67,48 @@ def test_local_snapshot_and_short_run_keep_optimizer_contract(offline_bridge, mo |
64 | 67 | assert cfg.model.recompute_num_layers == 1 |
65 | 68 | assert cfg.dataset.seq_length == cfg.model.seq_length == 8192 |
66 | 69 | assert "early, perf not optimized" in kimi_k3.kimi_k3_pretrain_config.__doc__ |
| 70 | + |
| 71 | + |
| 72 | +def test_runner_overrides_preserve_k3_tokenizer_and_hook(offline_bridge): |
| 73 | + cfg = kimi_k3.kimi_k3_pretrain_config() |
| 74 | + cfg = process_config_with_overrides( |
| 75 | + cfg, |
| 76 | + cli_overrides=[ |
| 77 | + "train.train_iters=10", |
| 78 | + "dataset.seq_length=8192", |
| 79 | + "dataset.split='100,0,0'", |
| 80 | + "checkpoint.save=null", |
| 81 | + ], |
| 82 | + ) |
| 83 | + # ConfigContainer.validate reruns initialization for subconfigs without finalize. |
| 84 | + cfg.tokenizer.__post_init__() |
| 85 | + assert cfg.tokenizer.trust_remote_code is True |
| 86 | + assert cfg.tokenizer.vocab_file.endswith("tiktoken.model") |
| 87 | + assert configure_kimi_k3_kernels in cfg.model._pre_wrap_hooks |
| 88 | + assert cfg.scheduler.lr_decay_iters == 10000 |
| 89 | + |
| 90 | + |
| 91 | +@pytest.mark.parametrize("legacy_kwargs", [{}, None]) |
| 92 | +def test_direct_tokenizer_options_survive_reconstruction(legacy_kwargs): |
| 93 | + cfg = TokenizerConfig( |
| 94 | + trust_remote_code=True, |
| 95 | + tokenizer_hf_no_use_fast=True, |
| 96 | + tokenizer_hf_no_include_special_tokens=True, |
| 97 | + hf_tokenizer_kwargs=legacy_kwargs, |
| 98 | + ) |
| 99 | + copied = replace(cfg, tokenizer_model="local-snapshot") |
| 100 | + assert copied.trust_remote_code is True |
| 101 | + assert copied.tokenizer_hf_no_use_fast is True |
| 102 | + assert copied.tokenizer_hf_no_include_special_tokens is True |
| 103 | + |
| 104 | + |
| 105 | +def test_explicit_legacy_tokenizer_options_keep_precedence(): |
| 106 | + cfg = TokenizerConfig( |
| 107 | + trust_remote_code=True, |
| 108 | + tokenizer_hf_no_use_fast=True, |
| 109 | + tokenizer_hf_no_include_special_tokens=True, |
| 110 | + hf_tokenizer_kwargs={"trust_remote_code": False, "use_fast": True, "include_special_tokens": True}, |
| 111 | + ) |
| 112 | + assert cfg.trust_remote_code is False |
| 113 | + assert cfg.tokenizer_hf_no_use_fast is False |
| 114 | + assert cfg.tokenizer_hf_no_include_special_tokens is False |
0 commit comments