Skip to content

Commit 1dd6f97

Browse files
JYMiracle305kilinchange
authored andcommitted
feat: Update PR according to comments
1 parent 82b3535 commit 1dd6f97

14 files changed

Lines changed: 193 additions & 117 deletions

File tree

‎CMakeLists.txt‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,6 @@ add_executable(llama3
265265
example/llama3/checkpoint_loader.cc
266266
)
267267
link_infini_train_exe(llama3)
268-
endif()
269268

270269
add_executable(qwen3
271270
example/qwen3/main.cc
@@ -275,6 +274,8 @@ add_executable(qwen3
275274
example/common/tokenizer.cc
276275
)
277276
link_infini_train_exe(qwen3)
277+
endif()
278+
278279
# Tools
279280
if(PROJECT_IS_TOP_LEVEL)
280281
add_subdirectory(tools/infini_run)

‎example/common/tokenizer.h‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ class Module;
1111
class Tokenizer {
1212
public:
1313
enum class Version : uint32_t {
14-
kV1 = 1,
15-
kV2 = 2,
16-
kV3 = 3,
14+
kV1 = 1, // GPT2
15+
kV2 = 2, // LLaMA-3
16+
kV3 = 3, // Qwen-3
1717
};
1818

1919
Tokenizer(const std::string &filepath);

‎example/gpt2/config.h‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ inline nn::TransformerConfig GPT2Config() {
2222
.tie_weights = true,
2323
.ffn_expansion_ratio = 4.0f,
2424
.ffn_dim_multiplier = std::nullopt,
25-
.multiple_of = 1};
25+
.multiple_of = 1,
26+
.rotary_interleaved = true};
2627
}
2728

2829
inline void SanitizeGPT2Config(const nn::TransformerConfig &c) {

‎example/llama3/config.h‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ inline nn::TransformerConfig LLaMA3Config() {
2222
.tie_weights = false,
2323
.ffn_expansion_ratio = 4.0f,
2424
.ffn_dim_multiplier = 1.5f,
25-
.multiple_of = 256};
25+
.multiple_of = 256,
26+
.rotary_interleaved = true};
2627
}
2728

2829
inline void SanitizeLLaMA3Config(const nn::TransformerConfig &c) {

‎example/mixtral/config.h‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ inline nn::TransformerConfig TinyMixtralConfig() {
2828
config.norm_eps = 1e-5f;
2929
config.rope_theta = 1000000.0f;
3030
config.use_scaled_rope = false;
31+
config.rotary_interleaved = true;
3132

3233
nn::MoEConfig moe_config;
3334
moe_config.num_experts = 8;

‎example/qwen3/checkpoint_loader.cc‎

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@
1212

1313
#include "glog/logging.h"
1414

15-
#include "example/common/utils.h"
16-
#include "example/qwen3/config.h"
1715
#include "infini_train/include/nn/modules/normalization.h"
1816
#include "infini_train/include/nn/modules/transformer/causal_self_attention.h"
1917
#include "infini_train/include/nn/modules/transformer/mlp.h"
@@ -22,6 +20,9 @@
2220
#include "infini_train/include/nn/parallel/tensor_parallel.h"
2321
#include "infini_train/include/tensor.h"
2422

23+
#include "example/common/utils.h"
24+
#include "example/qwen3/config.h"
25+
2526
using namespace infini_train;
2627
namespace nn = infini_train::nn;
2728

@@ -107,8 +108,8 @@ std::shared_ptr<nn::TransformerModel> LoadFromLLMC(const std::string &filepath)
107108
qwen3_config.use_scaled_rope = static_cast<bool>(use_scaled_rope);
108109
qwen3_config.norm_eps = norm_eps;
109110
qwen3_config.max_gen_batch_size = max_gen_bs;
110-
qwen3_config.use_qk_norm = true;
111-
qwen3_config.qk_norm_eps = norm_eps;
111+
qwen3_config.qk_layernorm = true;
112+
qwen3::SanitizeQwen3Config(qwen3_config);
112113
auto qwen3 = std::make_shared<nn::TransformerModel>(qwen3_config);
113114

114115
// ========== pp_size: num_stages; vpp_size: num_chunks_per_stage ==========
@@ -178,7 +179,7 @@ std::shared_ptr<nn::TransformerModel> LoadFromLLMC(const std::string &filepath)
178179

179180
// RowParallel (proj)
180181
const int64_t in_pp = static_cast<int64_t>(n_embd) / tp_size;
181-
// nn::MLP: c_fc/c_fc2(shard along row), c_proj(shard along col)
182+
// nn::MLP: packed c_fc [gate | up] (shard each block along row), c_proj (shard along col)
182183
const int64_t fc_out = ffn_hidden;
183184
const int64_t fc_pp = fc_out / tp_size;
184185
const int64_t in_fc_pp = ffn_hidden / tp_size;
@@ -309,13 +310,13 @@ std::shared_ptr<nn::TransformerModel> LoadFromLLMC(const std::string &filepath)
309310
}
310311
}
311312

312-
// gate_proj is loaded into c_fc2 because MLP applies SiLU to its second projection.
313+
// transformer.h.{i}.mlp.c_fc2.weight (gate) -> local packed c_fc rows [0 : fc_pp)
313314
local_layer_index = 0;
314315
for (int i = 0; i < static_cast<int>(n_layer); ++i) {
315316
if (owned_layers[i]) {
316317
auto &tensor = state_dict[std::format("{}.{}.{}.{}.{}.{}", nn::TransformerModel::kTransformerModelName,
317318
nn::TransformerChunk::kHLayerName, std::to_string(local_layer_index),
318-
nn::TransformerLayer::kMlpLayerName, nn::MLP::kCFc2LayerName,
319+
nn::TransformerLayer::kMlpLayerName, nn::MLP::kCFcLayerName,
319320
nn::parallel::ColumnParallelLinear::kParamWeightName)];
320321
ReadMatrixRowShardFloat(ifs, static_cast<float *>(tensor->DataPtr()),
321322
/*rows=*/fc_out, /*cols=*/n_embd,
@@ -327,16 +328,16 @@ std::shared_ptr<nn::TransformerModel> LoadFromLLMC(const std::string &filepath)
327328
}
328329
}
329330

330-
// up_proj is loaded into c_fc, producing SiLU(gate_proj(x)) * up_proj(x).
331+
// transformer.h.{i}.mlp.c_fc.weight (up) -> local packed c_fc rows [fc_pp : 2*fc_pp)
331332
local_layer_index = 0;
332333
for (int i = 0; i < static_cast<int>(n_layer); ++i) {
333334
if (owned_layers[i]) {
334335
auto &tensor = state_dict[std::format("{}.{}.{}.{}.{}.{}", nn::TransformerModel::kTransformerModelName,
335336
nn::TransformerChunk::kHLayerName, std::to_string(local_layer_index),
336337
nn::TransformerLayer::kMlpLayerName, nn::MLP::kCFcLayerName,
337338
nn::parallel::ColumnParallelLinear::kParamWeightName)];
338-
ReadMatrixRowShardFloat(ifs, static_cast<float *>(tensor->DataPtr()),
339-
/*rows=*/fc_out, /*cols=*/n_embd,
339+
float *dst = static_cast<float *>(tensor->DataPtr()) + fc_pp * n_embd;
340+
ReadMatrixRowShardFloat(ifs, dst, /*rows=*/fc_out, /*cols=*/n_embd,
340341
/*row_start=*/tp_rank * fc_pp, /*row_cnt=*/fc_pp);
341342
++local_layer_index;
342343
} else {

‎example/qwen3/config.h‎

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
#pragma once
2+
#include <cmath>
3+
4+
#include "glog/logging.h"
25

36
#include "infini_train/include/nn/modules/transformer/transformer_config.h"
47

@@ -25,7 +28,36 @@ inline nn::TransformerConfig Qwen3Config() {
2528
.use_scaled_rope = false,
2629
.rotary_interleaved = false,
2730
.norm_eps = 1e-6f,
28-
.use_qk_norm = true,
29-
.qk_norm_eps = 1e-6f};
31+
.qk_layernorm = true};
32+
}
33+
34+
inline void SanitizeQwen3Config(const nn::TransformerConfig &c) {
35+
CHECK_GT(c.block_size, 0);
36+
CHECK_GT(c.vocab_size, 0);
37+
CHECK_GE(c.vocab_size, c.original_vocab_size);
38+
CHECK_GT(c.n_layer, 0);
39+
CHECK_GT(c.n_head, 0);
40+
CHECK_GT(c.n_kv_head, 0);
41+
CHECK_LE(c.n_kv_head, c.n_head);
42+
CHECK_EQ(c.n_head % c.n_kv_head, 0) << "n_head must be divisible by n_kv_head for GQA";
43+
CHECK_GT(c.n_embd, 0);
44+
CHECK_EQ(c.n_embd % c.n_head, 0) << "n_embd must be divisible by n_head";
45+
const auto head_dim = c.n_embd / c.n_head;
46+
CHECK_GT(head_dim, 0) << "Qwen3 attention head dimension must be positive";
47+
CHECK_EQ(head_dim % 2, 0) << "Qwen3 RoPE requires an even attention head dimension";
48+
CHECK(c.position_embedding_type == nn::PositionEmbeddingType::kRoPE) << "Qwen3 requires RoPE position embedding";
49+
CHECK(!c.use_scaled_rope) << "Qwen3 scaled RoPE is not implemented";
50+
CHECK(!c.rotary_interleaved) << "Qwen3 requires half-split rotary embedding";
51+
CHECK_GT(c.rope_theta, 0.0f);
52+
CHECK(c.activation_type == nn::MLPType::kSwiGLU) << "Qwen3 requires SwiGLU activation";
53+
CHECK(c.ffn_type == nn::FFNType::kDense) << "Qwen3-8B requires a dense FFN";
54+
CHECK_GT(c.ffn_expansion_ratio, 0.0f);
55+
CHECK(c.norm_type == nn::NormType::kRMSNorm) << "Qwen3 requires RMSNorm";
56+
CHECK_GT(c.norm_eps, 0.0f);
57+
CHECK(!c.add_bias_linear) << "Qwen3 has no bias in linear layers";
58+
CHECK(!c.add_bias_lm_head) << "Qwen3 has no bias in lm_head";
59+
CHECK(!c.tie_weights) << "Qwen3 does not tie embedding and lm_head weights";
60+
CHECK_GT(c.multiple_of, 0);
61+
CHECK(c.qk_layernorm) << "Qwen3 apply laynorm to the query and key embeddings";
3062
}
3163
} // namespace qwen3

0 commit comments

Comments
 (0)