1import json
2from pathlib import Path
3
4import accelerate
5import torch
6from huggingface_hub import file_exists, hf_hub_download
7from transformers import (
8 AutoConfig,
9 AutoModelForCausalLM,
10 AutoProcessor,
11 AutoTokenizer,
12 GenerationConfig,
13 set_seed,
14)
15
16source_model_id = "moonshotai/Kimi-K2-Instruct"
17save_folder = "/tmp/tiny-random/kimi-k2"
18
19Path(save_folder).mkdir(parents=True, exist_ok=True)
20with open(hf_hub_download(source_model_id, filename='tokenizer_config.json', repo_type='model'), 'r', encoding='utf-8') as f:
21 tokenizer_config_json = json.load(f)
22tokenizer_config_json['auto_map']['AutoTokenizer'][0] = f'{source_model_id}--' + \
23 tokenizer_config_json["auto_map"]["AutoTokenizer"][0]
24with open(f"{save_folder}/tokenizer_config.json", "w", encoding='utf-8') as f:
25 json.dump(tokenizer_config_json, f, indent=2)
26hf_hub_download(source_model_id, filename='tiktoken.model', repo_type='model',
27 local_dir=save_folder, local_dir_use_symlinks=True, cache_dir='/tmp/')
28
29with open(hf_hub_download(source_model_id, filename='config.json', repo_type='model'), 'r', encoding='utf-8') as f:
30 config_json = json.load(f)
31for k, v in config_json['auto_map'].items():
32 config_json['auto_map'][k] = f'{source_model_id}--{v}'
33config_json.update({
34 'first_k_dense_replace': 1,
35 'num_hidden_layers': 2,
36 'hidden_size': 32,
37 'intermediate_size': 64,
38 'kv_lora_rank': 384,
39 'moe_intermediate_size': 64,
40 'n_routed_experts': 32,
41 'n_shared_experts': 1,
42 'num_attention_heads': 1,
43 'num_experts_per_tok': 8,
44 'num_key_value_heads': 1,
45 'q_lora_rank': 32,
46 'qk_nope_head_dim': 64,
47 'qk_rope_head_dim': 192, # vllm mla kernel supports 576 only, FA supports head dim <= 256
48 'v_head_dim': 64,
49 'tie_word_embeddings': False,
50})
51config_json['rope_scaling']['rope_type'] = 'yarn'
52del config_json['quantization_config']
53with open(f"{save_folder}/config.json", "w", encoding='utf-8') as f:
54 json.dump(config_json, f, indent=2)
55
56config = AutoConfig.from_pretrained(
57 save_folder,
58 trust_remote_code=True,
59)
60print(config)
61torch.set_default_dtype(torch.bfloat16)
62model = AutoModelForCausalLM.from_config(config, trust_remote_code=True)
63torch.set_default_dtype(torch.float32)
64if file_exists(filename="generation_config.json", repo_id=source_model_id, repo_type='model'):
65 model.generation_config = GenerationConfig.from_pretrained(
66 source_model_id, trust_remote_code=True,
67 )
68set_seed(42)
69model = model.cpu() # cpu is more stable for random initialization across machines
70with torch.no_grad():
71 for name, p in sorted(model.named_parameters()):
72 torch.nn.init.normal_(p, 0, 0.2)
73 print(name, p.shape)
74model.save_pretrained(save_folder)
75# print(model)
76with open(f"{save_folder}/config.json", "r", encoding='utf-8') as f:
77 config_json = json.load(f)
78 config_json['auto_map'] = {k: v.split('--')[-1] for k, v in config_json['auto_map'].items()}
79with open(f"{save_folder}/config.json", "w", encoding='utf-8') as f:
80 json.dump(config_json, f, indent=2)
81# for python_file in Path(save_folder).glob('*.py'):
82# python_file.unlink()
83with open(f'{save_folder}/modeling_deepseek.py', 'r', encoding='utf-8') as f:
84 codes = f.read()
85codes = codes.replace(
86 "past_length = past_key_values.seen_tokens",
87 "past_length = past_key_values.seen_tokens if hasattr(past_key_values, 'seen_tokens') else past_key_values.get_seq_length() # fix cache api deprecation"
88)
89codes = codes.replace(
90 "max_cache_length = past_key_values.get_max_length()",
91 "max_cache_length = past_key_values.get_max_length() if hasattr(past_key_values, 'get_max_length') else past_key_values.get_max_cache_shape() # fix cache api deprecation"
92)
93with open(f'{save_folder}/modeling_deepseek.py', 'w', encoding='utf-8') as f:
94 f.write(codes)