chenbhao commited on
Commit
2c87b68
·
1 Parent(s): 4020c99

rename minimind→omni in model_type, eval/convert scripts, and docs

Browse files
README.md CHANGED
@@ -173,25 +173,37 @@ torchrun --nproc_per_node=4 -m trainers.lm.full_sft --config configs/lm/lm_full_
173
  ### 推理 / 对话
174
 
175
  ```bash
176
- # 加载 SFT 模型对话(mini 版)
177
- python scripts/eval_llm.py --save_dir checkpoint/lm_full_sft_mini \
178
- --weight full_sft --hidden_size 128 --native
179
 
180
- # 加载 pretrain 模型(仅续写,无对话格式)
181
- python scripts/eval_llm.py --save_dir checkpoint/lm_pretrain_mini \
182
- --weight pretrain --hidden_size 128 --native
183
 
184
- # 全量版(hidden_size=512)
185
- python scripts/eval_llm.py --save_dir checkpoint/lm/full_sft \
186
- --weight full_sft --hidden_size 512 --native
187
 
188
- # 多模态视觉 VLM
189
- python scripts/eval_vlm.py --save_dir checkpoint/vlm --weight full_sft
190
 
191
- # 全模态 VAM(文本 + 视觉 + 语音)
 
192
  python scripts/eval_vam.py --save_dir checkpoint/vam --weight full_sft
193
  ```
194
 
 
 
 
 
 
 
 
 
 
 
 
 
195
  ## 配置说明
196
 
197
  `configs/*.yaml` 分为 `model` / `train` / `paths` 三段,由 `utils.training.apply_config`
 
173
  ### 推理 / 对话
174
 
175
  ```bash
176
+ # 原生 torch 格式(.pth)
177
+ python scripts/eval_llm.py --native --save_dir checkpoint/lm_full_sft_mini \
178
+ --weight full_sft --hidden_size 128
179
 
180
+ python scripts/eval_llm.py --native --save_dir checkpoint/lm_pretrain_mini \
181
+ --weight pretrain --hidden_size 128
 
182
 
183
+ # HuggingFace 格式(config.json + model.safetensors)
184
+ python scripts/eval_llm.py --load_from checkpoint/omni \
185
+ --tokenizer_path checkpoint/omni
186
 
187
+ python scripts/eval_llm.py --load_from checkpoint/lm_full_sft_mini/hf \
188
+ --tokenizer_path checkpoint/lm_full_sft_mini/hf
189
 
190
+ # 多模态(VLM / VAM)
191
+ python scripts/eval_vlm.py --save_dir checkpoint/vlm --weight full_sft
192
  python scripts/eval_vam.py --save_dir checkpoint/vam --weight full_sft
193
  ```
194
 
195
+ ### 格式转换
196
+
197
+ ```bash
198
+ # 原生 torch → HuggingFace 格式(omni 原生)
199
+ python scripts/convert_model.py checkpoint/lm_full_sft_mini/full_sft_128.pth \
200
+ checkpoint/lm_full_sft_mini/hf \
201
+ --tokenizer_path checkpoint/tokenizer
202
+
203
+ # 省略 --mode,默认 omni;也可输出 Qwen3 兼容格式
204
+ python scripts/convert_model.py checkpoint/omni/full_sft.pth output/dir --mode qwen
205
+ ```
206
+
207
  ## 配置说明
208
 
209
  `configs/*.yaml` 分为 `model` / `train` / `paths` 三段,由 `utils.training.apply_config`
scripts/convert_model.py CHANGED
@@ -10,7 +10,7 @@ from models.lm.lora import apply_lora, merge_lora
10
 
11
  warnings.filterwarnings('ignore', category=UserWarning)
12
 
13
- def convert_torch2transformers_minimind(torch_path, transformers_path, dtype=torch.float16):
14
  LMConfig.register_for_auto_class()
15
  LMForCausalLM.register_for_auto_class("AutoModelForCausalLM")
16
  lm_model = LMForCausalLM(lm_config)
@@ -21,7 +21,7 @@ def convert_torch2transformers_minimind(torch_path, transformers_path, dtype=tor
21
  model_params = sum(p.numel() for p in lm_model.parameters() if p.requires_grad)
22
  print(f'模型参数: {model_params / 1e6} 百万 = {model_params / 1e9} B (Billion)')
23
  lm_model.save_pretrained(transformers_path, safe_serialization=False)
24
- tokenizer = AutoTokenizer.from_pretrained('../model/')
25
  tokenizer.save_pretrained(transformers_path)
26
  # ======= transformers-5.0的兼容低版本写法 =======
27
  if int(transformers.__version__.split('.')[0]) >= 5:
@@ -30,11 +30,11 @@ def convert_torch2transformers_minimind(torch_path, transformers_path, dtype=tor
30
  config = json.load(open(config_path, 'r', encoding='utf-8'))
31
  config['rope_theta'] = lm_config.rope_theta; config['rope_scaling'] = None; del config['rope_parameters']
32
  json.dump(config, open(config_path, 'w', encoding='utf-8'), indent=2, ensure_ascii=False)
33
- print(f"模型已保存为 Transformers-MiniMind 格式: {transformers_path}")
34
 
35
 
36
  # QwenForCausalLM/LlamaForCausalLM结构兼容生态
37
- def convert_torch2transformers(torch_path, transformers_path, dtype=torch.float16):
38
  device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
39
  state_dict = torch.load(torch_path, map_location=device)
40
  common_config = {
@@ -80,7 +80,7 @@ def convert_torch2transformers(torch_path, transformers_path, dtype=torch.float1
80
  qwen_model.save_pretrained(transformers_path)
81
  model_params = sum(p.numel() for p in qwen_model.parameters() if p.requires_grad)
82
  print(f'模型参数: {model_params / 1e6} 百万 = {model_params / 1e9} B (Billion)')
83
- tokenizer = AutoTokenizer.from_pretrained('../model/')
84
  tokenizer.save_pretrained(transformers_path)
85
 
86
  # ======= transformers-5.0的兼容低版本写法 =======
@@ -123,19 +123,28 @@ def convert_json_to_jinja(json_file_path, output_path):
123
 
124
 
125
  if __name__ == '__main__':
126
- lm_config = LMConfig(hidden_size=768, num_hidden_layers=8, max_seq_len=8192, use_moe=False)
127
-
128
- # convert torch to transformers
129
- torch_path = f"../checkpoint/full_sft_{lm_config.hidden_size}{'_moe' if lm_config.use_moe else ''}.pth"
130
- transformers_path = '../minimind-3'
131
- convert_torch2transformers(torch_path, transformers_path)
132
-
133
- # # merge lora
134
- # base_torch_path = f"../checkpoint/full_sft_{lm_config.hidden_size}{'_moe' if lm_config.use_moe else ''}.pth"
135
- # lora_path = f"../checkpoint/lora_identity_{lm_config.hidden_size}{'_moe' if lm_config.use_moe else ''}.pth"
136
- # merged_torch_path = f"../checkpoint/merge_identity_{lm_config.hidden_size}{'_moe' if lm_config.use_moe else ''}.pth"
137
- # convert_merge_base_lora(base_torch_path, lora_path, merged_torch_path)
138
-
139
- # convert_transformers2torch(transformers_path, torch_path)
140
- # convert_json_to_jinja('../model/tokenizer_config.json', '../model/chat_template.jinja')
141
- # convert_jinja_to_json('../model/chat_template.jinja')
 
 
 
 
 
 
 
 
 
 
10
 
11
  warnings.filterwarnings('ignore', category=UserWarning)
12
 
13
+ def convert_torch2transformers_omni(torch_path, transformers_path, dtype=torch.float16, tokenizer_path='checkpoint/tokenizer'):
14
  LMConfig.register_for_auto_class()
15
  LMForCausalLM.register_for_auto_class("AutoModelForCausalLM")
16
  lm_model = LMForCausalLM(lm_config)
 
21
  model_params = sum(p.numel() for p in lm_model.parameters() if p.requires_grad)
22
  print(f'模型参数: {model_params / 1e6} 百万 = {model_params / 1e9} B (Billion)')
23
  lm_model.save_pretrained(transformers_path, safe_serialization=False)
24
+ tokenizer = AutoTokenizer.from_pretrained(tokenizer_path)
25
  tokenizer.save_pretrained(transformers_path)
26
  # ======= transformers-5.0的兼容低版本写法 =======
27
  if int(transformers.__version__.split('.')[0]) >= 5:
 
30
  config = json.load(open(config_path, 'r', encoding='utf-8'))
31
  config['rope_theta'] = lm_config.rope_theta; config['rope_scaling'] = None; del config['rope_parameters']
32
  json.dump(config, open(config_path, 'w', encoding='utf-8'), indent=2, ensure_ascii=False)
33
+ print(f"模型已保存为 Transformers-Omni 格式: {transformers_path}")
34
 
35
 
36
  # QwenForCausalLM/LlamaForCausalLM结构兼容生态
37
+ def convert_torch2transformers(torch_path, transformers_path, dtype=torch.float16, tokenizer_path='checkpoint/tokenizer'):
38
  device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
39
  state_dict = torch.load(torch_path, map_location=device)
40
  common_config = {
 
80
  qwen_model.save_pretrained(transformers_path)
81
  model_params = sum(p.numel() for p in qwen_model.parameters() if p.requires_grad)
82
  print(f'模型参数: {model_params / 1e6} 百万 = {model_params / 1e9} B (Billion)')
83
+ tokenizer = AutoTokenizer.from_pretrained(tokenizer_path)
84
  tokenizer.save_pretrained(transformers_path)
85
 
86
  # ======= transformers-5.0的兼容低版本写法 =======
 
123
 
124
 
125
  if __name__ == '__main__':
126
+ import argparse
127
+ parser = argparse.ArgumentParser(description="转换模型格式")
128
+ parser.add_argument('torch_path', type=str, help="输入 .pth 权重路径")
129
+ parser.add_argument('output_dir', type=str, help="输出目录")
130
+ parser.add_argument('--hidden_size', type=int, default=None, help="hidden_size(未指定则从 checkpoint 推断)")
131
+ parser.add_argument('--num_hidden_layers', type=int, default=None, help="层数(未指定则从 checkpoint 推断)")
132
+ parser.add_argument('--use_moe', action='store_true', help="MoE 架构")
133
+ parser.add_argument('--max_seq_len', type=int, default=8192, help="最大序列长度")
134
+ parser.add_argument('--mode', choices=['omni', 'qwen'], default='omni', help="输出格式(omni=原生LM格式, qwen=Qwen3兼容格式)")
135
+ parser.add_argument('--dtype', type=str, default='float16', help="权重精度")
136
+ parser.add_argument('--tokenizer_path', type=str, default='checkpoint/tokenizer', help="tokenizer 路径")
137
+ args = parser.parse_args()
138
+
139
+ state = torch.load(args.torch_path, map_location='cpu')
140
+ hs = args.hidden_size or state['model.embed_tokens.weight'].shape[1]
141
+ nl = args.num_hidden_layers or (max(int(k.split('.')[2]) for k in state if k.startswith('model.layers.')) + 1)
142
+ dtype = getattr(torch, args.dtype)
143
+
144
+ lm_config = LMConfig(hidden_size=hs, num_hidden_layers=nl,
145
+ max_seq_len=args.max_seq_len, use_moe=args.use_moe)
146
+
147
+ if args.mode == 'omni':
148
+ convert_torch2transformers_omni(args.torch_path, args.output_dir, dtype, args.tokenizer_path)
149
+ else:
150
+ convert_torch2transformers(args.torch_path, args.output_dir, dtype, args.tokenizer_path)
scripts/eval_llm.py CHANGED
@@ -3,7 +3,7 @@ import argparse
3
  import random
4
  import warnings
5
  import torch
6
- from transformers import AutoTokenizer, AutoModelForCausalLM, TextStreamer
7
  from models import LMConfig, LMForCausalLM
8
  from models.lm.lora import * # noqa: F401,F403
9
  from utils.training import setup_seed, get_model_params
@@ -27,7 +27,7 @@ def init_model(args):
27
  apply_lora(model)
28
  load_lora(model, f'./{args.save_dir}/{args.lora_weight}_{args.hidden_size}.pth')
29
  else:
30
- model = AutoModelForCausalLM.from_pretrained(args.load_from, trust_remote_code=True)
31
  get_model_params(model, model.config)
32
  return model.half().eval().to(args.device), tokenizer
33
 
 
3
  import random
4
  import warnings
5
  import torch
6
+ from transformers import AutoTokenizer, TextStreamer
7
  from models import LMConfig, LMForCausalLM
8
  from models.lm.lora import * # noqa: F401,F403
9
  from utils.training import setup_seed, get_model_params
 
27
  apply_lora(model)
28
  load_lora(model, f'./{args.save_dir}/{args.lora_weight}_{args.hidden_size}.pth')
29
  else:
30
+ model = LMForCausalLM.from_pretrained(args.load_from)
31
  get_model_params(model, model.config)
32
  return model.half().eval().to(args.device), tokenizer
33
 
scripts/serve_openai_api.py CHANGED
@@ -218,7 +218,7 @@ async def chat_completions(request: ChatRequest):
218
  "id": f"chatcmpl-{int(time.time())}",
219
  "object": "chat.completion",
220
  "created": int(time.time()),
221
- "model": "minimind",
222
  "choices": [
223
  {
224
  "index": 0,
 
218
  "id": f"chatcmpl-{int(time.time())}",
219
  "object": "chat.completion",
220
  "created": int(time.time()),
221
+ "model": "omni",
222
  "choices": [
223
  {
224
  "index": 0,
src/models/lm/config.py CHANGED
@@ -3,7 +3,7 @@ from transformers import PretrainedConfig
3
 
4
 
5
  class LMConfig(PretrainedConfig):
6
- model_type = "minimind"
7
 
8
  def __init__(self, hidden_size=768, num_hidden_layers=8, use_moe=False, **kwargs):
9
  super().__init__(**kwargs)
@@ -17,25 +17,35 @@ class LMConfig(PretrainedConfig):
17
  self.flash_attn = kwargs.get("flash_attn", True)
18
  self.num_attention_heads = kwargs.get("num_attention_heads", 8)
19
  self.num_key_value_heads = kwargs.get("num_key_value_heads", 4)
20
- self.head_dim = kwargs.get("head_dim", self.hidden_size // self.num_attention_heads)
21
- self.hidden_act = kwargs.get("hidden_act", 'silu')
22
- self.intermediate_size = kwargs.get("intermediate_size", math.ceil(hidden_size * math.pi / 64) * 64)
 
 
 
 
23
  self.max_position_embeddings = kwargs.get("max_position_embeddings", 32768)
24
  self.rms_norm_eps = kwargs.get("rms_norm_eps", 1e-6)
25
  self.rope_theta = kwargs.get("rope_theta", 1e6)
26
  self.tie_word_embeddings = kwargs.get("tie_word_embeddings", True)
27
  self.inference_rope_scaling = kwargs.get("inference_rope_scaling", False)
28
- self.rope_scaling = {
29
- "beta_fast": 32,
30
- "beta_slow": 1,
31
- "factor": 16,
32
- "original_max_position_embeddings": 2048,
33
- "attention_factor": 1.0,
34
- "type": "yarn"
35
- } if self.inference_rope_scaling else None
 
 
 
 
36
  # MoE specific configs (ignored if use_moe = False)
37
  self.num_experts = kwargs.get("num_experts", 4)
38
  self.num_experts_per_tok = kwargs.get("num_experts_per_tok", 1)
39
- self.moe_intermediate_size = kwargs.get("moe_intermediate_size", self.intermediate_size)
 
 
40
  self.norm_topk_prob = kwargs.get("norm_topk_prob", True)
41
  self.router_aux_loss_coef = kwargs.get("router_aux_loss_coef", 5e-4)
 
3
 
4
 
5
  class LMConfig(PretrainedConfig):
6
+ model_type = "omni"
7
 
8
  def __init__(self, hidden_size=768, num_hidden_layers=8, use_moe=False, **kwargs):
9
  super().__init__(**kwargs)
 
17
  self.flash_attn = kwargs.get("flash_attn", True)
18
  self.num_attention_heads = kwargs.get("num_attention_heads", 8)
19
  self.num_key_value_heads = kwargs.get("num_key_value_heads", 4)
20
+ self.head_dim = kwargs.get(
21
+ "head_dim", self.hidden_size // self.num_attention_heads
22
+ )
23
+ self.hidden_act = kwargs.get("hidden_act", "silu")
24
+ self.intermediate_size = kwargs.get(
25
+ "intermediate_size", math.ceil(hidden_size * math.pi / 64) * 64
26
+ )
27
  self.max_position_embeddings = kwargs.get("max_position_embeddings", 32768)
28
  self.rms_norm_eps = kwargs.get("rms_norm_eps", 1e-6)
29
  self.rope_theta = kwargs.get("rope_theta", 1e6)
30
  self.tie_word_embeddings = kwargs.get("tie_word_embeddings", True)
31
  self.inference_rope_scaling = kwargs.get("inference_rope_scaling", False)
32
+ self.rope_scaling = (
33
+ {
34
+ "beta_fast": 32,
35
+ "beta_slow": 1,
36
+ "factor": 16,
37
+ "original_max_position_embeddings": 2048,
38
+ "attention_factor": 1.0,
39
+ "type": "yarn",
40
+ }
41
+ if self.inference_rope_scaling
42
+ else None
43
+ )
44
  # MoE specific configs (ignored if use_moe = False)
45
  self.num_experts = kwargs.get("num_experts", 4)
46
  self.num_experts_per_tok = kwargs.get("num_experts_per_tok", 1)
47
+ self.moe_intermediate_size = kwargs.get(
48
+ "moe_intermediate_size", self.intermediate_size
49
+ )
50
  self.norm_topk_prob = kwargs.get("norm_topk_prob", True)
51
  self.router_aux_loss_coef = kwargs.get("router_aux_loss_coef", 5e-4)
src/models/vam/config.py CHANGED
@@ -2,7 +2,7 @@ from models.lm.config import LMConfig
2
 
3
 
4
  class VAMConfig(LMConfig):
5
- model_type = "minimind-o"
6
 
7
  def __init__(self, **kwargs):
8
  super().__init__(**kwargs)
 
2
 
3
 
4
  class VAMConfig(LMConfig):
5
+ model_type = "omni-o"
6
 
7
  def __init__(self, **kwargs):
8
  super().__init__(**kwargs)
src/models/vlm/config.py CHANGED
@@ -2,7 +2,7 @@ from models.lm.config import LMConfig
2
 
3
 
4
  class VLMConfig(LMConfig):
5
- model_type = "minimind-v"
6
 
7
  def __init__(self, image_special_token='<|image_pad|>', image_ids=[12], **kwargs):
8
  self.image_special_token = image_special_token
 
2
 
3
 
4
  class VLMConfig(LMConfig):
5
+ model_type = "omni-v"
6
 
7
  def __init__(self, image_special_token='<|image_pad|>', image_ids=[12], **kwargs):
8
  self.image_special_token = image_special_token
src/trainers/lm/rollout_engine.py CHANGED
@@ -1,7 +1,7 @@
1
  """Rollout engines for RL training.
2
 
3
  To use the SGLang backend, first launch the server (with a transformers-format model):
4
- python -m sglang.launch_server --model-path ./minimind-3 --attention-backend triton --host 0.0.0.0 --port 8998
5
  """
6
  import os
7
  import requests
 
1
  """Rollout engines for RL training.
2
 
3
  To use the SGLang backend, first launch the server (with a transformers-format model):
4
+ python -m sglang.launch_server --model-path ./checkpoint/omni --attention-backend triton --host 0.0.0.0 --port 8998
5
  """
6
  import os
7
  import requests