JMaxCool commited on
Commit
0e7aed9
·
verified ·
1 Parent(s): 5defc93

add dpo/checkpoint-8

Browse files
Files changed (36) hide show
  1. .gitattributes +1 -0
  2. dpo/checkpoint-8/README.md +209 -0
  3. dpo/checkpoint-8/adapter_config.json +52 -0
  4. dpo/checkpoint-8/adapter_model.safetensors +3 -0
  5. dpo/checkpoint-8/chat_template.jinja +154 -0
  6. dpo/checkpoint-8/global_step8/bf16_zero_pp_rank_0_mp_rank_00_optim_states.pt +3 -0
  7. dpo/checkpoint-8/global_step8/bf16_zero_pp_rank_1_mp_rank_00_optim_states.pt +3 -0
  8. dpo/checkpoint-8/global_step8/bf16_zero_pp_rank_2_mp_rank_00_optim_states.pt +3 -0
  9. dpo/checkpoint-8/global_step8/bf16_zero_pp_rank_3_mp_rank_00_optim_states.pt +3 -0
  10. dpo/checkpoint-8/global_step8/bf16_zero_pp_rank_4_mp_rank_00_optim_states.pt +3 -0
  11. dpo/checkpoint-8/global_step8/bf16_zero_pp_rank_5_mp_rank_00_optim_states.pt +3 -0
  12. dpo/checkpoint-8/global_step8/bf16_zero_pp_rank_6_mp_rank_00_optim_states.pt +3 -0
  13. dpo/checkpoint-8/global_step8/bf16_zero_pp_rank_7_mp_rank_00_optim_states.pt +3 -0
  14. dpo/checkpoint-8/global_step8/zero_pp_rank_0_mp_rank_00_model_states.pt +3 -0
  15. dpo/checkpoint-8/global_step8/zero_pp_rank_1_mp_rank_00_model_states.pt +3 -0
  16. dpo/checkpoint-8/global_step8/zero_pp_rank_2_mp_rank_00_model_states.pt +3 -0
  17. dpo/checkpoint-8/global_step8/zero_pp_rank_3_mp_rank_00_model_states.pt +3 -0
  18. dpo/checkpoint-8/global_step8/zero_pp_rank_4_mp_rank_00_model_states.pt +3 -0
  19. dpo/checkpoint-8/global_step8/zero_pp_rank_5_mp_rank_00_model_states.pt +3 -0
  20. dpo/checkpoint-8/global_step8/zero_pp_rank_6_mp_rank_00_model_states.pt +3 -0
  21. dpo/checkpoint-8/global_step8/zero_pp_rank_7_mp_rank_00_model_states.pt +3 -0
  22. dpo/checkpoint-8/latest +1 -0
  23. dpo/checkpoint-8/rng_state_0.pth +3 -0
  24. dpo/checkpoint-8/rng_state_1.pth +3 -0
  25. dpo/checkpoint-8/rng_state_2.pth +3 -0
  26. dpo/checkpoint-8/rng_state_3.pth +3 -0
  27. dpo/checkpoint-8/rng_state_4.pth +3 -0
  28. dpo/checkpoint-8/rng_state_5.pth +3 -0
  29. dpo/checkpoint-8/rng_state_6.pth +3 -0
  30. dpo/checkpoint-8/rng_state_7.pth +3 -0
  31. dpo/checkpoint-8/scheduler.pt +3 -0
  32. dpo/checkpoint-8/tokenizer.json +3 -0
  33. dpo/checkpoint-8/tokenizer_config.json +32 -0
  34. dpo/checkpoint-8/trainer_state.json +33 -0
  35. dpo/checkpoint-8/training_args.bin +3 -0
  36. dpo/checkpoint-8/zero_to_fp32.py +790 -0
.gitattributes CHANGED
@@ -33,3 +33,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ dpo/checkpoint-8/tokenizer.json filter=lfs diff=lfs merge=lfs -text
dpo/checkpoint-8/README.md ADDED
@@ -0,0 +1,209 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ base_model: local_king/king_cxxiv
3
+ library_name: peft
4
+ pipeline_tag: text-generation
5
+ tags:
6
+ - base_model:adapter:local_king/king_cxxiv
7
+ - dpo
8
+ - lora
9
+ - transformers
10
+ - trl
11
+ ---
12
+
13
+ # Model Card for Model ID
14
+
15
+ <!-- Provide a quick summary of what the model is/does. -->
16
+
17
+
18
+
19
+ ## Model Details
20
+
21
+ ### Model Description
22
+
23
+ <!-- Provide a longer summary of what this model is. -->
24
+
25
+
26
+
27
+ - **Developed by:** [More Information Needed]
28
+ - **Funded by [optional]:** [More Information Needed]
29
+ - **Shared by [optional]:** [More Information Needed]
30
+ - **Model type:** [More Information Needed]
31
+ - **Language(s) (NLP):** [More Information Needed]
32
+ - **License:** [More Information Needed]
33
+ - **Finetuned from model [optional]:** [More Information Needed]
34
+
35
+ ### Model Sources [optional]
36
+
37
+ <!-- Provide the basic links for the model. -->
38
+
39
+ - **Repository:** [More Information Needed]
40
+ - **Paper [optional]:** [More Information Needed]
41
+ - **Demo [optional]:** [More Information Needed]
42
+
43
+ ## Uses
44
+
45
+ <!-- Address questions around how the model is intended to be used, including the foreseeable users of the model and those affected by the model. -->
46
+
47
+ ### Direct Use
48
+
49
+ <!-- This section is for the model use without fine-tuning or plugging into a larger ecosystem/app. -->
50
+
51
+ [More Information Needed]
52
+
53
+ ### Downstream Use [optional]
54
+
55
+ <!-- This section is for the model use when fine-tuned for a task, or when plugged into a larger ecosystem/app -->
56
+
57
+ [More Information Needed]
58
+
59
+ ### Out-of-Scope Use
60
+
61
+ <!-- This section addresses misuse, malicious use, and uses that the model will not work well for. -->
62
+
63
+ [More Information Needed]
64
+
65
+ ## Bias, Risks, and Limitations
66
+
67
+ <!-- This section is meant to convey both technical and sociotechnical limitations. -->
68
+
69
+ [More Information Needed]
70
+
71
+ ### Recommendations
72
+
73
+ <!-- This section is meant to convey recommendations with respect to the bias, risk, and technical limitations. -->
74
+
75
+ Users (both direct and downstream) should be made aware of the risks, biases and limitations of the model. More information needed for further recommendations.
76
+
77
+ ## How to Get Started with the Model
78
+
79
+ Use the code below to get started with the model.
80
+
81
+ [More Information Needed]
82
+
83
+ ## Training Details
84
+
85
+ ### Training Data
86
+
87
+ <!-- This should link to a Dataset Card, perhaps with a short stub of information on what the training data is all about as well as documentation related to data pre-processing or additional filtering. -->
88
+
89
+ [More Information Needed]
90
+
91
+ ### Training Procedure
92
+
93
+ <!-- This relates heavily to the Technical Specifications. Content here should link to that section when it is relevant to the training procedure. -->
94
+
95
+ #### Preprocessing [optional]
96
+
97
+ [More Information Needed]
98
+
99
+
100
+ #### Training Hyperparameters
101
+
102
+ - **Training regime:** [More Information Needed] <!--fp32, fp16 mixed precision, bf16 mixed precision, bf16 non-mixed precision, fp16 non-mixed precision, fp8 mixed precision -->
103
+
104
+ #### Speeds, Sizes, Times [optional]
105
+
106
+ <!-- This section provides information about throughput, start/end time, checkpoint size if relevant, etc. -->
107
+
108
+ [More Information Needed]
109
+
110
+ ## Evaluation
111
+
112
+ <!-- This section describes the evaluation protocols and provides the results. -->
113
+
114
+ ### Testing Data, Factors & Metrics
115
+
116
+ #### Testing Data
117
+
118
+ <!-- This should link to a Dataset Card if possible. -->
119
+
120
+ [More Information Needed]
121
+
122
+ #### Factors
123
+
124
+ <!-- These are the things the evaluation is disaggregating by, e.g., subpopulations or domains. -->
125
+
126
+ [More Information Needed]
127
+
128
+ #### Metrics
129
+
130
+ <!-- These are the evaluation metrics being used, ideally with a description of why. -->
131
+
132
+ [More Information Needed]
133
+
134
+ ### Results
135
+
136
+ [More Information Needed]
137
+
138
+ #### Summary
139
+
140
+
141
+
142
+ ## Model Examination [optional]
143
+
144
+ <!-- Relevant interpretability work for the model goes here -->
145
+
146
+ [More Information Needed]
147
+
148
+ ## Environmental Impact
149
+
150
+ <!-- Total emissions (in grams of CO2eq) and additional considerations, such as electricity usage, go here. Edit the suggested text below accordingly -->
151
+
152
+ Carbon emissions can be estimated using the [Machine Learning Impact calculator](https://mlco2.github.io/impact#compute) presented in [Lacoste et al. (2019)](https://arxiv.org/abs/1910.09700).
153
+
154
+ - **Hardware Type:** [More Information Needed]
155
+ - **Hours used:** [More Information Needed]
156
+ - **Cloud Provider:** [More Information Needed]
157
+ - **Compute Region:** [More Information Needed]
158
+ - **Carbon Emitted:** [More Information Needed]
159
+
160
+ ## Technical Specifications [optional]
161
+
162
+ ### Model Architecture and Objective
163
+
164
+ [More Information Needed]
165
+
166
+ ### Compute Infrastructure
167
+
168
+ [More Information Needed]
169
+
170
+ #### Hardware
171
+
172
+ [More Information Needed]
173
+
174
+ #### Software
175
+
176
+ [More Information Needed]
177
+
178
+ ## Citation [optional]
179
+
180
+ <!-- If there is a paper or blog post introducing the model, the APA and Bibtex information for that should go in this section. -->
181
+
182
+ **BibTeX:**
183
+
184
+ [More Information Needed]
185
+
186
+ **APA:**
187
+
188
+ [More Information Needed]
189
+
190
+ ## Glossary [optional]
191
+
192
+ <!-- If relevant, include terms and calculations in this section that can help readers understand the model or model card. -->
193
+
194
+ [More Information Needed]
195
+
196
+ ## More Information [optional]
197
+
198
+ [More Information Needed]
199
+
200
+ ## Model Card Authors [optional]
201
+
202
+ [More Information Needed]
203
+
204
+ ## Model Card Contact
205
+
206
+ [More Information Needed]
207
+ ### Framework versions
208
+
209
+ - PEFT 0.20.0
dpo/checkpoint-8/adapter_config.json ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "alora_invocation_tokens": null,
3
+ "alpha_pattern": {},
4
+ "arrow_config": null,
5
+ "auto_mapping": null,
6
+ "base_model_name_or_path": "local_king/king_cxxiv",
7
+ "bias": "none",
8
+ "corda_config": null,
9
+ "ensure_weight_tying": false,
10
+ "eva_config": null,
11
+ "exclude_modules": null,
12
+ "fan_in_fan_out": false,
13
+ "inference_mode": true,
14
+ "init_lora_weights": true,
15
+ "layer_replication": null,
16
+ "layers_pattern": null,
17
+ "layers_to_transform": null,
18
+ "loftq_config": {},
19
+ "lora_alpha": 32,
20
+ "lora_bias": false,
21
+ "lora_dropout": 0.05,
22
+ "lora_ga_config": null,
23
+ "megatron_config": null,
24
+ "megatron_core": "megatron.core",
25
+ "modules_to_save": null,
26
+ "monteclora_config": null,
27
+ "peft_type": "LORA",
28
+ "peft_version": "0.20.0",
29
+ "qalora_group_size": 16,
30
+ "r": 16,
31
+ "rank_pattern": {},
32
+ "revision": null,
33
+ "target_modules": [
34
+ "gate_proj",
35
+ "in_proj_qkv",
36
+ "out_proj",
37
+ "v_proj",
38
+ "k_proj",
39
+ "q_proj",
40
+ "up_proj",
41
+ "o_proj",
42
+ "down_proj"
43
+ ],
44
+ "target_parameters": null,
45
+ "task_type": "CAUSAL_LM",
46
+ "trainable_token_indices": null,
47
+ "use_bdlora": null,
48
+ "use_dora": false,
49
+ "use_qalora": false,
50
+ "use_rslora": false,
51
+ "velora_config": null
52
+ }
dpo/checkpoint-8/adapter_model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:416719d1087e7ec3abc2706578f4601b45292cd72f62aa741e976c040a219fe4
3
+ size 32502800
dpo/checkpoint-8/chat_template.jinja ADDED
@@ -0,0 +1,154 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {%- set image_count = namespace(value=0) %}
2
+ {%- set video_count = namespace(value=0) %}
3
+ {%- macro render_content(content, do_vision_count, is_system_content=false) %}
4
+ {%- if content is string %}
5
+ {{- content }}
6
+ {%- elif content is iterable and content is not mapping %}
7
+ {%- for item in content %}
8
+ {%- if 'image' in item or 'image_url' in item or item.type == 'image' %}
9
+ {%- if is_system_content %}
10
+ {{- raise_exception('System message cannot contain images.') }}
11
+ {%- endif %}
12
+ {%- if do_vision_count %}
13
+ {%- set image_count.value = image_count.value + 1 %}
14
+ {%- endif %}
15
+ {%- if add_vision_id %}
16
+ {{- 'Picture ' ~ image_count.value ~ ': ' }}
17
+ {%- endif %}
18
+ {{- '<|vision_start|><|image_pad|><|vision_end|>' }}
19
+ {%- elif 'video' in item or item.type == 'video' %}
20
+ {%- if is_system_content %}
21
+ {{- raise_exception('System message cannot contain videos.') }}
22
+ {%- endif %}
23
+ {%- if do_vision_count %}
24
+ {%- set video_count.value = video_count.value + 1 %}
25
+ {%- endif %}
26
+ {%- if add_vision_id %}
27
+ {{- 'Video ' ~ video_count.value ~ ': ' }}
28
+ {%- endif %}
29
+ {{- '<|vision_start|><|video_pad|><|vision_end|>' }}
30
+ {%- elif 'text' in item %}
31
+ {{- item.text }}
32
+ {%- else %}
33
+ {{- raise_exception('Unexpected item type in content.') }}
34
+ {%- endif %}
35
+ {%- endfor %}
36
+ {%- elif content is none or content is undefined %}
37
+ {{- '' }}
38
+ {%- else %}
39
+ {{- raise_exception('Unexpected content type.') }}
40
+ {%- endif %}
41
+ {%- endmacro %}
42
+ {%- if not messages %}
43
+ {{- raise_exception('No messages provided.') }}
44
+ {%- endif %}
45
+ {%- if tools and tools is iterable and tools is not mapping %}
46
+ {{- '<|im_start|>system\n' }}
47
+ {{- "# Tools\n\nYou have access to the following functions:\n\n<tools>" }}
48
+ {%- for tool in tools %}
49
+ {{- "\n" }}
50
+ {{- tool | tojson }}
51
+ {%- endfor %}
52
+ {{- "\n</tools>" }}
53
+ {{- '\n\nIf you choose to call a function ONLY reply in the following format with NO suffix:\n\n<tool_call>\n<function=example_function_name>\n<parameter=example_parameter_1>\nvalue_1\n</parameter>\n<parameter=example_parameter_2>\nThis is the value for the second parameter\nthat can span\nmultiple lines\n</parameter>\n</function>\n</tool_call>\n\n<IMPORTANT>\nReminder:\n- Function calls MUST follow the specified format: an inner <function=...></function> block must be nested within <tool_call></tool_call> XML tags\n- Required parameters MUST be specified\n- You may provide optional reasoning for your function call in natural language BEFORE the function call, but NOT after\n- If there is no function call available, answer the question like normal with your current knowledge and do not tell the user about function calls\n</IMPORTANT>' }}
54
+ {%- if messages[0].role == 'system' %}
55
+ {%- set content = render_content(messages[0].content, false, true)|trim %}
56
+ {%- if content %}
57
+ {{- '\n\n' + content }}
58
+ {%- endif %}
59
+ {%- endif %}
60
+ {{- '<|im_end|>\n' }}
61
+ {%- else %}
62
+ {%- if messages[0].role == 'system' %}
63
+ {%- set content = render_content(messages[0].content, false, true)|trim %}
64
+ {{- '<|im_start|>system\n' + content + '<|im_end|>\n' }}
65
+ {%- endif %}
66
+ {%- endif %}
67
+ {%- set ns = namespace(multi_step_tool=true, last_query_index=messages|length - 1) %}
68
+ {%- for message in messages[::-1] %}
69
+ {%- set index = (messages|length - 1) - loop.index0 %}
70
+ {%- if ns.multi_step_tool and message.role == "user" %}
71
+ {%- set content = render_content(message.content, false)|trim %}
72
+ {%- if not(content.startswith('<tool_response>') and content.endswith('</tool_response>')) %}
73
+ {%- set ns.multi_step_tool = false %}
74
+ {%- set ns.last_query_index = index %}
75
+ {%- endif %}
76
+ {%- endif %}
77
+ {%- endfor %}
78
+ {%- if ns.multi_step_tool %}
79
+ {{- raise_exception('No user query found in messages.') }}
80
+ {%- endif %}
81
+ {%- for message in messages %}
82
+ {%- set content = render_content(message.content, true)|trim %}
83
+ {%- if message.role == "system" %}
84
+ {%- if not loop.first %}
85
+ {{- raise_exception('System message must be at the beginning.') }}
86
+ {%- endif %}
87
+ {%- elif message.role == "user" %}
88
+ {{- '<|im_start|>' + message.role + '\n' + content + '<|im_end|>' + '\n' }}
89
+ {%- elif message.role == "assistant" %}
90
+ {%- set reasoning_content = '' %}
91
+ {%- if message.reasoning_content is string %}
92
+ {%- set reasoning_content = message.reasoning_content %}
93
+ {%- else %}
94
+ {%- if '</think>' in content %}
95
+ {%- set reasoning_content = content.split('</think>')[0].rstrip('\n').split('<think>')[-1].lstrip('\n') %}
96
+ {%- set content = content.split('</think>')[-1].lstrip('\n') %}
97
+ {%- endif %}
98
+ {%- endif %}
99
+ {%- set reasoning_content = reasoning_content|trim %}
100
+ {%- if (preserve_thinking is defined and preserve_thinking is true) or (loop.index0 > ns.last_query_index) %}
101
+ {{- '<|im_start|>' + message.role + '\n<think>\n' + reasoning_content + '\n</think>\n\n' + content }}
102
+ {%- else %}
103
+ {{- '<|im_start|>' + message.role + '\n' + content }}
104
+ {%- endif %}
105
+ {%- if message.tool_calls and message.tool_calls is iterable and message.tool_calls is not mapping %}
106
+ {%- for tool_call in message.tool_calls %}
107
+ {%- if tool_call.function is defined %}
108
+ {%- set tool_call = tool_call.function %}
109
+ {%- endif %}
110
+ {%- if loop.first %}
111
+ {%- if content|trim %}
112
+ {{- '\n\n<tool_call>\n<function=' + tool_call.name + '>\n' }}
113
+ {%- else %}
114
+ {{- '<tool_call>\n<function=' + tool_call.name + '>\n' }}
115
+ {%- endif %}
116
+ {%- else %}
117
+ {{- '\n<tool_call>\n<function=' + tool_call.name + '>\n' }}
118
+ {%- endif %}
119
+ {%- if tool_call.arguments is defined %}
120
+ {%- for args_name, args_value in tool_call.arguments|items %}
121
+ {{- '<parameter=' + args_name + '>\n' }}
122
+ {%- set args_value = args_value | string if args_value is string else args_value | tojson | safe %}
123
+ {{- args_value }}
124
+ {{- '\n</parameter>\n' }}
125
+ {%- endfor %}
126
+ {%- endif %}
127
+ {{- '</function>\n</tool_call>' }}
128
+ {%- endfor %}
129
+ {%- endif %}
130
+ {{- '<|im_end|>\n' }}
131
+ {%- elif message.role == "tool" %}
132
+ {%- if loop.previtem and loop.previtem.role != "tool" %}
133
+ {{- '<|im_start|>user' }}
134
+ {%- endif %}
135
+ {{- '\n<tool_response>\n' }}
136
+ {{- content }}
137
+ {{- '\n</tool_response>' }}
138
+ {%- if not loop.last and loop.nextitem.role != "tool" %}
139
+ {{- '<|im_end|>\n' }}
140
+ {%- elif loop.last %}
141
+ {{- '<|im_end|>\n' }}
142
+ {%- endif %}
143
+ {%- else %}
144
+ {{- raise_exception('Unexpected message role.') }}
145
+ {%- endif %}
146
+ {%- endfor %}
147
+ {%- if add_generation_prompt %}
148
+ {{- '<|im_start|>assistant\n' }}
149
+ {%- if enable_thinking is defined and enable_thinking is false %}
150
+ {{- '<think>\n\n</think>\n\n' }}
151
+ {%- else %}
152
+ {{- '<think>\n' }}
153
+ {%- endif %}
154
+ {%- endif %}
dpo/checkpoint-8/global_step8/bf16_zero_pp_rank_0_mp_rank_00_optim_states.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:c33ee54818e887619d99454179b0a0968b14bd970282163572484e5ef668f31f
3
+ size 24334469
dpo/checkpoint-8/global_step8/bf16_zero_pp_rank_1_mp_rank_00_optim_states.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:b51a45630b51b019a497a78ec40bca270e41795829a661850eba3a739d49955d
3
+ size 24334469
dpo/checkpoint-8/global_step8/bf16_zero_pp_rank_2_mp_rank_00_optim_states.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:f15d914224eb1641b137087b6cc60985ad7890c252013126ed39c9a49cf2f645
3
+ size 24334469
dpo/checkpoint-8/global_step8/bf16_zero_pp_rank_3_mp_rank_00_optim_states.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:4e8d57bdb6caf5f080d34b1833690d1e492611889a91b718765f8287e6e0ef83
3
+ size 24334469
dpo/checkpoint-8/global_step8/bf16_zero_pp_rank_4_mp_rank_00_optim_states.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:282feee5b7b7d8561bc6f5af4acf575789e7eae8328223c813631348e2f43e8f
3
+ size 24334469
dpo/checkpoint-8/global_step8/bf16_zero_pp_rank_5_mp_rank_00_optim_states.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:71275bbe9f563bf05c6cf58151c2518b9e4ce4992d3a685ad8cf718085c75f0b
3
+ size 24334469
dpo/checkpoint-8/global_step8/bf16_zero_pp_rank_6_mp_rank_00_optim_states.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:f3eb137c20baf6a45c5e4b4299fd19c8556f8d7a399bfd6214eac50a77ebd55e
3
+ size 24334469
dpo/checkpoint-8/global_step8/bf16_zero_pp_rank_7_mp_rank_00_optim_states.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:ec17f667a06443383b5456c9723042710e01677defb6f9b83256b65eb4328eea
3
+ size 24334469
dpo/checkpoint-8/global_step8/zero_pp_rank_0_mp_rank_00_model_states.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:5fd129a359dbb5a8028176366e718d48a082b3fbbb0a71a112a814d93434c540
3
+ size 498513
dpo/checkpoint-8/global_step8/zero_pp_rank_1_mp_rank_00_model_states.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:ebc9082dbb2433e3a40647765abc4657d32e9159d92f6699b936476df2ff9790
3
+ size 498513
dpo/checkpoint-8/global_step8/zero_pp_rank_2_mp_rank_00_model_states.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:abb694fbae57e2379ba31e7a41d6f2eedbd1912d5f8f825aa5b0c4f5898a75b7
3
+ size 498513
dpo/checkpoint-8/global_step8/zero_pp_rank_3_mp_rank_00_model_states.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:481127f4e095ea7cc2326e2cf13aa76538e6709819e976f44070365cdfe350ae
3
+ size 498513
dpo/checkpoint-8/global_step8/zero_pp_rank_4_mp_rank_00_model_states.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:0f2ab53a7e0e85b323b29e24f9e982a0b68b5e70ead8b04cab228084ca8a7909
3
+ size 498513
dpo/checkpoint-8/global_step8/zero_pp_rank_5_mp_rank_00_model_states.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:96b7c113c783765df35191a2219edabd2cf214ecd7150a7fd474569041e08545
3
+ size 498513
dpo/checkpoint-8/global_step8/zero_pp_rank_6_mp_rank_00_model_states.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:ba9bf8eb6a9641f5aeaab0c06ad02da2233f132a4498900eef90ef02c2bd5018
3
+ size 498513
dpo/checkpoint-8/global_step8/zero_pp_rank_7_mp_rank_00_model_states.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:60fb14b3d70f0c39abe0330febf3b0b848cbfa95f6a3732ef7033af88dffad62
3
+ size 498513
dpo/checkpoint-8/latest ADDED
@@ -0,0 +1 @@
 
 
1
+ global_step8
dpo/checkpoint-8/rng_state_0.pth ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:f8f92cf63e0989759370d24108b469c492c12202403f036015307ce49f12cedc
3
+ size 16389
dpo/checkpoint-8/rng_state_1.pth ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:9ed40a0a4e9f365d2c6cc004d97e6705894eba46c8be4c160c1455bc3062dee1
3
+ size 16389
dpo/checkpoint-8/rng_state_2.pth ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:d688b304d19c260b5cfa471535ed51d7e1d60b3a0d0159dfd1a04b87904a9f42
3
+ size 16389
dpo/checkpoint-8/rng_state_3.pth ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:9967425ebcaee80d9b518fa0244d52f739b1b983d87cda71d5fede0c073e9d3b
3
+ size 16389
dpo/checkpoint-8/rng_state_4.pth ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:469900fd39c667ffbd49c3c407c0ba317a1e9f5f9339a99b5d38423b7d0ce6d4
3
+ size 16389
dpo/checkpoint-8/rng_state_5.pth ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:124688471ff2a6e80f2fcefedbf741fb18d08dd539d5bd07a52e81be545142a5
3
+ size 16389
dpo/checkpoint-8/rng_state_6.pth ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:1e69f1ced9f992a72c948698e5eb06088610788988cdb2fdbdd624e064319d60
3
+ size 16389
dpo/checkpoint-8/rng_state_7.pth ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:a376268a55d6ee10c371c06aa952334c4c6a1af9ea2d71b1951a57367a0c6722
3
+ size 16389
dpo/checkpoint-8/scheduler.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:2af0c5be47d4fccfa80b297971c3af5ca519ae495d71df47ff2cbe0d72b5c1b8
3
+ size 1401
dpo/checkpoint-8/tokenizer.json ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:06b9509352d2af50381ab2247e083b80d32d5c0aba91c272ca9ff729b6a0e523
3
+ size 19989325
dpo/checkpoint-8/tokenizer_config.json ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "add_prefix_space": false,
3
+ "audio_bos_token": "<|audio_start|>",
4
+ "audio_eos_token": "<|audio_end|>",
5
+ "audio_token": "<|audio_pad|>",
6
+ "backend": "tokenizers",
7
+ "bos_token": null,
8
+ "clean_up_tokenization_spaces": false,
9
+ "eos_token": "<|im_end|>",
10
+ "errors": "replace",
11
+ "image_token": "<|image_pad|>",
12
+ "is_local": true,
13
+ "local_files_only": false,
14
+ "model_max_length": 262144,
15
+ "model_specific_special_tokens": {
16
+ "audio_bos_token": "<|audio_start|>",
17
+ "audio_eos_token": "<|audio_end|>",
18
+ "audio_token": "<|audio_pad|>",
19
+ "image_token": "<|image_pad|>",
20
+ "video_token": "<|video_pad|>",
21
+ "vision_bos_token": "<|vision_start|>",
22
+ "vision_eos_token": "<|vision_end|>"
23
+ },
24
+ "pad_token": "<|endoftext|>",
25
+ "pretokenize_regex": "(?i:'s|'t|'re|'ve|'m|'ll|'d)|[^\\r\\n\\p{L}\\p{N}]?[\\p{L}\\p{M}]+|\\p{N}| ?[^\\s\\p{L}\\p{M}\\p{N}]+[\\r\\n]*|\\s*[\\r\\n]+|\\s+(?!\\S)|\\s+",
26
+ "split_special_tokens": false,
27
+ "tokenizer_class": "Qwen2Tokenizer",
28
+ "unk_token": null,
29
+ "video_token": "<|video_pad|>",
30
+ "vision_bos_token": "<|vision_start|>",
31
+ "vision_eos_token": "<|vision_end|>"
32
+ }
dpo/checkpoint-8/trainer_state.json ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "best_global_step": null,
3
+ "best_metric": null,
4
+ "best_model_checkpoint": null,
5
+ "epoch": 0.5161290322580645,
6
+ "eval_steps": 500,
7
+ "global_step": 8,
8
+ "is_hyper_param_search": false,
9
+ "is_local_process_zero": true,
10
+ "is_world_process_zero": true,
11
+ "log_history": [],
12
+ "logging_steps": 10,
13
+ "max_steps": 16,
14
+ "num_input_tokens_seen": 0,
15
+ "num_train_epochs": 1,
16
+ "save_steps": 8,
17
+ "stateful_callbacks": {
18
+ "TrainerControl": {
19
+ "args": {
20
+ "should_epoch_stop": false,
21
+ "should_evaluate": false,
22
+ "should_log": false,
23
+ "should_save": true,
24
+ "should_training_stop": false
25
+ },
26
+ "attributes": {}
27
+ }
28
+ },
29
+ "total_flos": 29896864694272.0,
30
+ "train_batch_size": 1,
31
+ "trial_name": null,
32
+ "trial_params": null
33
+ }
dpo/checkpoint-8/training_args.bin ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:77907494c2d80ceb7969ce8d47cf5d93a8e4f875d5f4d85b71f6d4c00742e448
3
+ size 7505
dpo/checkpoint-8/zero_to_fp32.py ADDED
@@ -0,0 +1,790 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python
2
+
3
+ # Copyright (c) Microsoft Corporation.
4
+ # SPDX-License-Identifier: Apache-2.0
5
+
6
+ # DeepSpeed Team
7
+
8
+ # This script extracts fp32 consolidated weights from a zero 1, 2 and 3 DeepSpeed checkpoints. It gets
9
+ # copied into the top level checkpoint dir, so the user can easily do the conversion at any point in
10
+ # the future. Once extracted, the weights don't require DeepSpeed and can be used in any
11
+ # application.
12
+ #
13
+ # example:
14
+ # python zero_to_fp32.py . output_dir/
15
+ # or
16
+ # python zero_to_fp32.py . output_dir/ --safe_serialization
17
+
18
+ import argparse
19
+ import torch
20
+ import glob
21
+ import math
22
+ import os
23
+ import re
24
+ import gc
25
+ import json
26
+ import numpy as np
27
+ from tqdm import tqdm
28
+ from collections import OrderedDict
29
+ from dataclasses import dataclass
30
+
31
+ # while this script doesn't use deepspeed to recover data, since the checkpoints are pickled with
32
+ # DeepSpeed data structures it has to be available in the current python environment.
33
+ from deepspeed.utils import logger
34
+ from deepspeed.checkpoint.constants import (DS_VERSION, OPTIMIZER_STATE_DICT, SINGLE_PARTITION_OF_FP32_GROUPS,
35
+ FP32_FLAT_GROUPS, ZERO_STAGE, PARTITION_COUNT, PARAM_SHAPES, BUFFER_NAMES,
36
+ FROZEN_PARAM_SHAPES, FROZEN_PARAM_FRAGMENTS, AUTOEP_LAYERS_KEY,
37
+ AUTOEP_LAYERS_KEY_LEGACY, AUTOEP_ZERO3_EXPERT_STATE_FORMAT_KEY,
38
+ AUTOEP_ZERO3_PARTITIONED_EXPERT_STATE_FORMAT)
39
+
40
+
41
+ @dataclass
42
+ class zero_model_state:
43
+ buffers: dict()
44
+ param_shapes: dict()
45
+ shared_params: list
46
+ ds_version: int
47
+ frozen_param_shapes: dict()
48
+ frozen_param_fragments: dict()
49
+
50
+
51
+ debug = 0
52
+
53
+ # load to cpu
54
+ device = torch.device('cpu')
55
+
56
+
57
+ def atoi(text):
58
+ return int(text) if text.isdigit() else text
59
+
60
+
61
+ def natural_keys(text):
62
+ '''
63
+ alist.sort(key=natural_keys) sorts in human order
64
+ http://nedbatchelder.com/blog/200712/human_sorting.html
65
+ (See Toothy's implementation in the comments)
66
+ '''
67
+ return [atoi(c) for c in re.split(r'(\d+)', text)]
68
+
69
+
70
+ def get_model_state_file(checkpoint_dir, zero_stage):
71
+ if not os.path.isdir(checkpoint_dir):
72
+ raise FileNotFoundError(f"Directory '{checkpoint_dir}' doesn't exist")
73
+
74
+ # there should be only one file
75
+ if zero_stage <= 2:
76
+ file = os.path.join(checkpoint_dir, "mp_rank_00_model_states.pt")
77
+ elif zero_stage == 3:
78
+ file = os.path.join(checkpoint_dir, "zero_pp_rank_0_mp_rank_00_model_states.pt")
79
+
80
+ if not os.path.exists(file):
81
+ raise FileNotFoundError(f"can't find model states file at '{file}'")
82
+
83
+ return file
84
+
85
+
86
+ def get_checkpoint_files(checkpoint_dir, glob_pattern):
87
+ # XXX: need to test that this simple glob rule works for multi-node setup too
88
+ ckpt_files = sorted(glob.glob(os.path.join(checkpoint_dir, glob_pattern)), key=natural_keys)
89
+
90
+ if len(ckpt_files) == 0:
91
+ raise FileNotFoundError(f"can't find {glob_pattern} files in directory '{checkpoint_dir}'")
92
+
93
+ return ckpt_files
94
+
95
+
96
+ def get_optim_files(checkpoint_dir):
97
+ return get_checkpoint_files(checkpoint_dir, "*_optim_states.pt")
98
+
99
+
100
+ def get_model_state_files(checkpoint_dir):
101
+ return get_checkpoint_files(checkpoint_dir, "*_model_states.pt")
102
+
103
+
104
+ def _has_autoep_zero3_partitioned_metadata(state_dict):
105
+ autoep_layers = state_dict.get(AUTOEP_LAYERS_KEY)
106
+ if autoep_layers is None:
107
+ autoep_layers = state_dict.get(AUTOEP_LAYERS_KEY_LEGACY)
108
+ if not isinstance(autoep_layers, list):
109
+ return False
110
+ return any(
111
+ isinstance(entry, dict)
112
+ and entry.get(AUTOEP_ZERO3_EXPERT_STATE_FORMAT_KEY) == AUTOEP_ZERO3_PARTITIONED_EXPERT_STATE_FORMAT
113
+ for entry in autoep_layers)
114
+
115
+
116
+ def _raise_if_autoep_zero3_partitioned_state(state_dict):
117
+ if _has_autoep_zero3_partitioned_metadata(state_dict):
118
+ raise NotImplementedError("zero_to_fp32 does not support AutoEP ZeRO-3 partition-native checkpoints. "
119
+ "AutoEP expert parameters are partitioned over expert replica groups, so "
120
+ "global data-parallel consolidation would produce incomplete expert tensors. "
121
+ "Use ds_to_universal.py for expert-aware conversion.")
122
+
123
+
124
+ def _raise_if_autoep_zero3_partitioned_checkpoint(model_files):
125
+ for file in model_files:
126
+ state_dict = torch.load(file, map_location=device, weights_only=False)
127
+ _raise_if_autoep_zero3_partitioned_state(state_dict)
128
+
129
+
130
+ def parse_model_states(files):
131
+ zero_model_states = []
132
+ for file in files:
133
+ state_dict = torch.load(file, map_location=device, weights_only=False)
134
+ _raise_if_autoep_zero3_partitioned_state(state_dict)
135
+
136
+ if BUFFER_NAMES not in state_dict:
137
+ raise ValueError(f"{file} is not a model state checkpoint")
138
+ buffer_names = state_dict[BUFFER_NAMES]
139
+ if debug:
140
+ print("Found buffers:", buffer_names)
141
+
142
+ # recover just the buffers while restoring them to fp32 if they were saved in fp16
143
+ buffers = {k: v.float() for k, v in state_dict["module"].items() if k in buffer_names}
144
+ param_shapes = state_dict[PARAM_SHAPES]
145
+
146
+ # collect parameters that are included in param_shapes
147
+ param_names = []
148
+ for s in param_shapes:
149
+ for name in s.keys():
150
+ param_names.append(name)
151
+
152
+ # update with frozen parameters
153
+ frozen_param_shapes = state_dict.get(FROZEN_PARAM_SHAPES, None)
154
+ if frozen_param_shapes is not None:
155
+ if debug:
156
+ print(f"Found frozen_param_shapes: {frozen_param_shapes}")
157
+ param_names += list(frozen_param_shapes.keys())
158
+
159
+ # handle shared params
160
+ shared_params = [[k, v] for k, v in state_dict["shared_params"].items()]
161
+
162
+ ds_version = state_dict.get(DS_VERSION, None)
163
+
164
+ frozen_param_fragments = state_dict.get(FROZEN_PARAM_FRAGMENTS, None)
165
+
166
+ z_model_state = zero_model_state(buffers=buffers,
167
+ param_shapes=param_shapes,
168
+ shared_params=shared_params,
169
+ ds_version=ds_version,
170
+ frozen_param_shapes=frozen_param_shapes,
171
+ frozen_param_fragments=frozen_param_fragments)
172
+ zero_model_states.append(z_model_state)
173
+
174
+ return zero_model_states
175
+
176
+
177
+ def parse_optim_states(files, ds_checkpoint_dir):
178
+ total_files = len(files)
179
+ state_dicts = []
180
+ for f in tqdm(files, desc='Loading checkpoint shards'):
181
+ state_dict = torch.load(f, map_location=device, mmap=True, weights_only=False)
182
+ # immediately discard the potentially huge 2 optimizer states as we only care for fp32 master weights
183
+ # and also handle the case where it was already removed by another helper script
184
+ state_dict["optimizer_state_dict"].pop("optimizer_state_dict", None)
185
+ state_dicts.append(state_dict)
186
+
187
+ if ZERO_STAGE not in state_dicts[0][OPTIMIZER_STATE_DICT]:
188
+ raise ValueError(f"{files[0]} is not a zero checkpoint")
189
+ zero_stage = state_dicts[0][OPTIMIZER_STATE_DICT][ZERO_STAGE]
190
+ world_size = state_dicts[0][OPTIMIZER_STATE_DICT][PARTITION_COUNT]
191
+
192
+ # For ZeRO-2 each param group can have different partition_count as data parallelism for expert
193
+ # parameters can be different from data parallelism for non-expert parameters. So we can just
194
+ # use the max of the partition_count to get the dp world_size.
195
+
196
+ if type(world_size) is list:
197
+ world_size = max(world_size)
198
+
199
+ if world_size != total_files:
200
+ raise ValueError(
201
+ f"Expected {world_size} of '*_optim_states.pt' under '{ds_checkpoint_dir}' but found {total_files} files. "
202
+ "Possibly due to an overwrite of an old checkpoint, or a checkpoint didn't get saved by one or more processes."
203
+ )
204
+
205
+ # the groups are named differently in each stage
206
+ if zero_stage <= 2:
207
+ fp32_groups_key = SINGLE_PARTITION_OF_FP32_GROUPS
208
+ elif zero_stage == 3:
209
+ fp32_groups_key = FP32_FLAT_GROUPS
210
+ else:
211
+ raise ValueError(f"unknown zero stage {zero_stage}")
212
+
213
+ fp32_flat_groups = [state_dicts[i][OPTIMIZER_STATE_DICT][fp32_groups_key] for i in range(len(state_dicts))]
214
+ return zero_stage, world_size, fp32_flat_groups
215
+
216
+
217
+ def _get_fp32_state_dict_from_zero_checkpoint(ds_checkpoint_dir, exclude_frozen_parameters):
218
+ """
219
+ Returns fp32 state_dict reconstructed from ds checkpoint
220
+
221
+ Args:
222
+ - ``ds_checkpoint_dir``: path to the deepspeed checkpoint folder (where the optimizer files are)
223
+
224
+ """
225
+ print(f"Processing zero checkpoint '{ds_checkpoint_dir}'")
226
+
227
+ # parse_model_states rejects AutoEP ZeRO-3 partition-native checkpoints
228
+ # before the expensive optimizer-shard load below.
229
+ model_files = get_model_state_files(ds_checkpoint_dir)
230
+ zero_model_states = parse_model_states(model_files)
231
+ print(f'Parsing checkpoint created by deepspeed=={zero_model_states[0].ds_version}')
232
+
233
+ optim_files = get_optim_files(ds_checkpoint_dir)
234
+ zero_stage, world_size, fp32_flat_groups = parse_optim_states(optim_files, ds_checkpoint_dir)
235
+ print(f"Detected checkpoint of type zero stage {zero_stage}, world_size: {world_size}")
236
+
237
+ if zero_stage <= 2:
238
+ return _get_fp32_state_dict_from_zero2_checkpoint(world_size, fp32_flat_groups, zero_model_states,
239
+ exclude_frozen_parameters)
240
+ elif zero_stage == 3:
241
+ return _get_fp32_state_dict_from_zero3_checkpoint(world_size, fp32_flat_groups, zero_model_states,
242
+ exclude_frozen_parameters)
243
+
244
+
245
+ def _zero2_merge_frozen_params(state_dict, zero_model_states):
246
+ if zero_model_states[0].frozen_param_shapes is None or len(zero_model_states[0].frozen_param_shapes) == 0:
247
+ return
248
+
249
+ frozen_param_shapes = zero_model_states[0].frozen_param_shapes
250
+ frozen_param_fragments = zero_model_states[0].frozen_param_fragments
251
+
252
+ if debug:
253
+ num_elem = sum(s.numel() for s in frozen_param_shapes.values())
254
+ print(f'rank 0: {FROZEN_PARAM_SHAPES}.numel = {num_elem}')
255
+
256
+ wanted_params = len(frozen_param_shapes)
257
+ wanted_numel = sum(s.numel() for s in frozen_param_shapes.values())
258
+ avail_numel = sum([p.numel() for p in frozen_param_fragments.values()])
259
+ print(f'Frozen params: Have {avail_numel} numels to process.')
260
+ print(f'Frozen params: Need {wanted_numel} numels in {wanted_params} params')
261
+
262
+ total_params = 0
263
+ total_numel = 0
264
+ for name, shape in frozen_param_shapes.items():
265
+ total_params += 1
266
+ unpartitioned_numel = shape.numel()
267
+ total_numel += unpartitioned_numel
268
+
269
+ state_dict[name] = frozen_param_fragments[name]
270
+
271
+ if debug:
272
+ print(f"{name} full shape: {shape} unpartitioned numel {unpartitioned_numel} ")
273
+
274
+ print(f"Reconstructed Frozen fp32 state dict with {total_params} params {total_numel} elements")
275
+
276
+
277
+ def _has_callable(obj, fn):
278
+ attr = getattr(obj, fn, None)
279
+ return callable(attr)
280
+
281
+
282
+ def _zero2_merge_trainable_params(state_dict, world_size, fp32_flat_groups, zero_model_states):
283
+ param_shapes = zero_model_states[0].param_shapes
284
+
285
+ # Reconstruction protocol:
286
+ #
287
+ # XXX: document this
288
+
289
+ if debug:
290
+ for i in range(world_size):
291
+ for j in range(len(fp32_flat_groups[0])):
292
+ print(f"{FP32_FLAT_GROUPS}[{i}][{j}].shape={fp32_flat_groups[i][j].shape}")
293
+
294
+ # XXX: memory usage doubles here (zero2)
295
+ num_param_groups = len(fp32_flat_groups[0])
296
+ merged_single_partition_of_fp32_groups = []
297
+ for i in range(num_param_groups):
298
+ merged_partitions = [sd[i] for sd in fp32_flat_groups]
299
+ full_single_fp32_vector = torch.cat(merged_partitions, 0)
300
+ merged_single_partition_of_fp32_groups.append(full_single_fp32_vector)
301
+ avail_numel = sum(
302
+ [full_single_fp32_vector.numel() for full_single_fp32_vector in merged_single_partition_of_fp32_groups])
303
+
304
+ if debug:
305
+ wanted_params = sum([len(shapes) for shapes in param_shapes])
306
+ wanted_numel = sum([sum(shape.numel() for shape in shapes.values()) for shapes in param_shapes])
307
+ # not asserting if there is a mismatch due to possible padding
308
+ print(f"Have {avail_numel} numels to process.")
309
+ print(f"Need {wanted_numel} numels in {wanted_params} params.")
310
+
311
+ # params
312
+ # XXX: for huge models that can't fit into the host's RAM we will have to recode this to support
313
+ # out-of-core computing solution
314
+ total_numel = 0
315
+ total_params = 0
316
+ for shapes, full_single_fp32_vector in zip(param_shapes, merged_single_partition_of_fp32_groups):
317
+ offset = 0
318
+ avail_numel = full_single_fp32_vector.numel()
319
+ for name, shape in shapes.items():
320
+
321
+ unpartitioned_numel = shape.numel() if _has_callable(shape, 'numel') else math.prod(shape)
322
+ total_numel += unpartitioned_numel
323
+ total_params += 1
324
+
325
+ if debug:
326
+ print(f"{name} full shape: {shape} unpartitioned numel {unpartitioned_numel} ")
327
+ state_dict[name] = full_single_fp32_vector.narrow(0, offset, unpartitioned_numel).view(shape)
328
+ offset += unpartitioned_numel
329
+
330
+ # Z2 started to align to 2*world_size to improve nccl performance. Therefore both offset and
331
+ # avail_numel can differ by anywhere between 0..2*world_size. Due to two unrelated complex
332
+ # paddings performed in the code it's almost impossible to predict the exact numbers w/o the
333
+ # live optimizer object, so we are checking that the numbers are within the right range
334
+ align_to = 2 * world_size
335
+
336
+ def zero2_align(x):
337
+ return align_to * math.ceil(x / align_to)
338
+
339
+ if debug:
340
+ print(f"original offset={offset}, avail_numel={avail_numel}")
341
+
342
+ offset = zero2_align(offset)
343
+ avail_numel = zero2_align(avail_numel)
344
+
345
+ if debug:
346
+ print(f"aligned offset={offset}, avail_numel={avail_numel}")
347
+
348
+ # Sanity check
349
+ if offset != avail_numel:
350
+ raise ValueError(f"consumed {offset} numels out of {avail_numel} - something is wrong")
351
+
352
+ print(f"Reconstructed fp32 state dict with {total_params} params {total_numel} elements")
353
+
354
+
355
+ def _get_fp32_state_dict_from_zero2_checkpoint(world_size, fp32_flat_groups, zero_model_states,
356
+ exclude_frozen_parameters):
357
+ state_dict = OrderedDict()
358
+
359
+ # buffers
360
+ buffers = zero_model_states[0].buffers
361
+ state_dict.update(buffers)
362
+ if debug:
363
+ print(f"added {len(buffers)} buffers")
364
+
365
+ if not exclude_frozen_parameters:
366
+ _zero2_merge_frozen_params(state_dict, zero_model_states)
367
+
368
+ _zero2_merge_trainable_params(state_dict, world_size, fp32_flat_groups, zero_model_states)
369
+
370
+ # recover shared parameters
371
+ for pair in zero_model_states[0].shared_params:
372
+ if pair[1] in state_dict:
373
+ state_dict[pair[0]] = state_dict[pair[1]]
374
+
375
+ return state_dict
376
+
377
+
378
+ def zero3_partitioned_param_info(unpartitioned_numel, world_size):
379
+ remainder = unpartitioned_numel % world_size
380
+ padding_numel = (world_size - remainder) if remainder else 0
381
+ partitioned_numel = math.ceil(unpartitioned_numel / world_size)
382
+ return partitioned_numel, padding_numel
383
+
384
+
385
+ def _zero3_merge_frozen_params(state_dict, world_size, zero_model_states):
386
+ if zero_model_states[0].frozen_param_shapes is None or len(zero_model_states[0].frozen_param_shapes) == 0:
387
+ return
388
+
389
+ if debug:
390
+ for i in range(world_size):
391
+ num_elem = sum(s.numel() for s in zero_model_states[i].frozen_param_fragments.values())
392
+ print(f'rank {i}: {FROZEN_PARAM_SHAPES}.numel = {num_elem}')
393
+
394
+ frozen_param_shapes = zero_model_states[0].frozen_param_shapes
395
+ wanted_params = len(frozen_param_shapes)
396
+ wanted_numel = sum(s.numel() for s in frozen_param_shapes.values())
397
+ avail_numel = sum([p.numel() for p in zero_model_states[0].frozen_param_fragments.values()]) * world_size
398
+ print(f'Frozen params: Have {avail_numel} numels to process.')
399
+ print(f'Frozen params: Need {wanted_numel} numels in {wanted_params} params')
400
+
401
+ total_params = 0
402
+ total_numel = 0
403
+ for name, shape in zero_model_states[0].frozen_param_shapes.items():
404
+ total_params += 1
405
+ unpartitioned_numel = shape.numel()
406
+ total_numel += unpartitioned_numel
407
+
408
+ param_frags = tuple(model_state.frozen_param_fragments[name] for model_state in zero_model_states)
409
+ state_dict[name] = torch.cat(param_frags, 0).narrow(0, 0, unpartitioned_numel).view(shape)
410
+
411
+ partitioned_numel, partitioned_padding_numel = zero3_partitioned_param_info(unpartitioned_numel, world_size)
412
+
413
+ if debug:
414
+ print(
415
+ f"Frozen params: {total_params} {name} full shape: {shape} partition0 numel={partitioned_numel} partitioned_padding_numel={partitioned_padding_numel}"
416
+ )
417
+
418
+ print(f"Reconstructed Frozen fp32 state dict with {total_params} params {total_numel} elements")
419
+
420
+
421
+ class GatheredTensor:
422
+ """
423
+ A pseudo tensor that collects partitioned weights.
424
+ It is more memory efficient when there are multiple groups.
425
+ """
426
+
427
+ def __init__(self, flat_groups, flat_groups_offset, offset, partitioned_numel, shape):
428
+ self.flat_groups = flat_groups
429
+ self.flat_groups_offset = flat_groups_offset
430
+ self.offset = offset
431
+ self.partitioned_numel = partitioned_numel
432
+ self.shape = shape
433
+ self.dtype = self.flat_groups[0][0].dtype
434
+
435
+ def contiguous(self):
436
+ """
437
+ Merge partitioned weights from flat_groups into a single tensor.
438
+ """
439
+ end_idx = self.offset + self.partitioned_numel
440
+ world_size = len(self.flat_groups)
441
+ pad_flat_param_chunks = []
442
+
443
+ for rank_i in range(world_size):
444
+ # for each rank, we need to collect weights from related group/groups
445
+ flat_groups_at_rank_i = self.flat_groups[rank_i]
446
+ start_group_id = None
447
+ end_group_id = None
448
+ for group_id in range(len(self.flat_groups_offset)):
449
+ if self.flat_groups_offset[group_id] <= self.offset < self.flat_groups_offset[group_id + 1]:
450
+ start_group_id = group_id
451
+ if self.flat_groups_offset[group_id] < end_idx <= self.flat_groups_offset[group_id + 1]:
452
+ end_group_id = group_id
453
+ break
454
+ # collect weights from related group/groups
455
+ for group_id in range(start_group_id, end_group_id + 1):
456
+ flat_tensor = flat_groups_at_rank_i[group_id]
457
+ start_offset = self.offset - self.flat_groups_offset[group_id]
458
+ end_offset = min(end_idx, self.flat_groups_offset[group_id + 1]) - self.flat_groups_offset[group_id]
459
+ pad_flat_param_chunks.append(flat_tensor[start_offset:end_offset])
460
+
461
+ # collect weights from all ranks
462
+ pad_flat_param = torch.cat(pad_flat_param_chunks, dim=0)
463
+ param = pad_flat_param[:self.shape.numel()].view(self.shape).contiguous()
464
+ return param
465
+
466
+
467
+ def _zero3_merge_trainable_params(state_dict, world_size, fp32_flat_groups, zero_model_states):
468
+ param_shapes = zero_model_states[0].param_shapes
469
+ avail_numel = sum([flat_group.numel() for flat_group in fp32_flat_groups[0]]) * world_size
470
+
471
+ # Reconstruction protocol: For zero3 we need to zip the partitions together at boundary of each
472
+ # param, re-consolidating each param, while dealing with padding if any
473
+
474
+ # merge list of dicts, preserving order
475
+ param_shapes = {k: v for d in param_shapes for k, v in d.items()}
476
+
477
+ if debug:
478
+ for i in range(world_size):
479
+ print(f"{FP32_FLAT_GROUPS}[{i}].shape={fp32_flat_groups[i].shape}")
480
+
481
+ wanted_params = len(param_shapes)
482
+ wanted_numel = sum(shape.numel() for shape in param_shapes.values())
483
+ # not asserting if there is a mismatch due to possible padding
484
+ avail_numel = fp32_flat_groups[0].numel() * world_size
485
+ print(f"Trainable params: Have {avail_numel} numels to process.")
486
+ print(f"Trainable params: Need {wanted_numel} numels in {wanted_params} params.")
487
+
488
+ # params
489
+ # XXX: for huge models that can't fit into the host's RAM we will have to recode this to support
490
+ # out-of-core computing solution
491
+ offset = 0
492
+ total_numel = 0
493
+ total_params = 0
494
+ flat_groups_offset = [0] + list(np.cumsum([flat_tensor.numel() for flat_tensor in fp32_flat_groups[0]]))
495
+ for name, shape in tqdm(param_shapes.items(), desc='Gathering sharded weights'):
496
+ unpartitioned_numel = shape.numel()
497
+ total_numel += unpartitioned_numel
498
+ total_params += 1
499
+ partitioned_numel, partitioned_padding_numel = zero3_partitioned_param_info(unpartitioned_numel, world_size)
500
+
501
+ if debug:
502
+ print(
503
+ f"Trainable params: {total_params} {name} full shape: {shape} partition0 numel={partitioned_numel} partitioned_padding_numel={partitioned_padding_numel}"
504
+ )
505
+
506
+ # memory efficient tensor
507
+ tensor = GatheredTensor(fp32_flat_groups, flat_groups_offset, offset, partitioned_numel, shape)
508
+ state_dict[name] = tensor
509
+ offset += partitioned_numel
510
+
511
+ offset *= world_size
512
+
513
+ # Sanity check
514
+ if offset != avail_numel:
515
+ raise ValueError(f"consumed {offset} numels out of {avail_numel} - something is wrong")
516
+
517
+ print(f"Reconstructed Trainable fp32 state dict with {total_params} params {total_numel} elements")
518
+
519
+
520
+ def _get_fp32_state_dict_from_zero3_checkpoint(world_size, fp32_flat_groups, zero_model_states,
521
+ exclude_frozen_parameters):
522
+ state_dict = OrderedDict()
523
+
524
+ # buffers
525
+ buffers = zero_model_states[0].buffers
526
+ state_dict.update(buffers)
527
+ if debug:
528
+ print(f"added {len(buffers)} buffers")
529
+
530
+ if not exclude_frozen_parameters:
531
+ _zero3_merge_frozen_params(state_dict, world_size, zero_model_states)
532
+
533
+ _zero3_merge_trainable_params(state_dict, world_size, fp32_flat_groups, zero_model_states)
534
+
535
+ # recover shared parameters
536
+ for pair in zero_model_states[0].shared_params:
537
+ if pair[1] in state_dict:
538
+ state_dict[pair[0]] = state_dict[pair[1]]
539
+
540
+ return state_dict
541
+
542
+
543
+ def to_torch_tensor(state_dict, return_empty_tensor=False):
544
+ """
545
+ Convert state_dict of GatheredTensor to torch tensor
546
+ """
547
+ torch_state_dict = {}
548
+ converted_tensors = {}
549
+ for name, tensor in state_dict.items():
550
+ tensor_id = id(tensor)
551
+ if tensor_id in converted_tensors: # shared tensors
552
+ shared_tensor = torch_state_dict[converted_tensors[tensor_id]]
553
+ torch_state_dict[name] = shared_tensor
554
+ else:
555
+ converted_tensors[tensor_id] = name
556
+ if return_empty_tensor:
557
+ torch_state_dict[name] = torch.empty(tensor.shape, dtype=tensor.dtype)
558
+ else:
559
+ torch_state_dict[name] = tensor.contiguous()
560
+ return torch_state_dict
561
+
562
+
563
+ def get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir,
564
+ tag=None,
565
+ exclude_frozen_parameters=False,
566
+ lazy_mode=False):
567
+ """
568
+ Convert ZeRO 2 or 3 checkpoint into a single fp32 consolidated state_dict that can be loaded with
569
+ ``load_state_dict()`` and used for training without DeepSpeed or shared with others, for example
570
+ via a model hub.
571
+
572
+ Args:
573
+ - ``checkpoint_dir``: path to the desired checkpoint folder
574
+ - ``tag``: checkpoint tag used as a unique identifier for checkpoint. If not provided will attempt to load tag in 'latest' file. e.g., ``global_step14``
575
+ - ``exclude_frozen_parameters``: exclude frozen parameters
576
+ - ``lazy_mode``: get state_dict in lazy mode. It returns a dict of pesduo tensor instead of torch tensor, which is more memory efficient.
577
+ Convert the pesduo tensor to torch tensor by ``.contiguous()``
578
+
579
+ Returns:
580
+ - pytorch ``state_dict``
581
+
582
+ A typical usage might be ::
583
+
584
+ from deepspeed.utils.zero_to_fp32 import get_fp32_state_dict_from_zero_checkpoint
585
+ # do the training and checkpoint saving
586
+ state_dict = get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir) # already on cpu
587
+ model = model.cpu() # move to cpu
588
+ model.load_state_dict(state_dict)
589
+ # submit to model hub or save the model to share with others
590
+
591
+ In this example the ``model`` will no longer be usable in the deepspeed context of the same
592
+ application. i.e. you will need to re-initialize the deepspeed engine, since
593
+ ``model.load_state_dict(state_dict)`` will remove all the deepspeed magic from it.
594
+
595
+ If you want it all done for you, use ``load_state_dict_from_zero_checkpoint`` instead.
596
+
597
+ Note: the above usage may not work if your application doesn't have sufficient free CPU memory.
598
+ You may need to use the offline approach using the ``zero_to_fp32.py`` script that is saved with
599
+ the checkpoint. Or you can load state_dict in lazy mode ::
600
+
601
+ from deepspeed.utils.zero_to_fp32 import get_fp32_state_dict_from_zero_checkpoint
602
+ state_dict = get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir, lazy_mode=True) # not on cpu
603
+ for name, lazy_tensor in state_dict.item():
604
+ tensor = lazy_tensor.contiguous() # to cpu
605
+ print(name, tensor)
606
+ # del tensor to release memory if it no longer in use
607
+ """
608
+ if tag is None:
609
+ latest_path = os.path.join(checkpoint_dir, 'latest')
610
+ if os.path.isfile(latest_path):
611
+ with open(latest_path, 'r') as fd:
612
+ tag = fd.read().strip()
613
+ else:
614
+ raise ValueError(f"Unable to find 'latest' file at {latest_path}")
615
+
616
+ ds_checkpoint_dir = os.path.join(checkpoint_dir, tag)
617
+
618
+ if not os.path.isdir(ds_checkpoint_dir):
619
+ raise FileNotFoundError(f"Directory '{ds_checkpoint_dir}' doesn't exist")
620
+
621
+ state_dict = _get_fp32_state_dict_from_zero_checkpoint(ds_checkpoint_dir, exclude_frozen_parameters)
622
+ if lazy_mode:
623
+ return state_dict
624
+ else:
625
+ return to_torch_tensor(state_dict)
626
+
627
+
628
+ def convert_zero_checkpoint_to_fp32_state_dict(checkpoint_dir,
629
+ output_dir,
630
+ max_shard_size="5GB",
631
+ safe_serialization=False,
632
+ tag=None,
633
+ exclude_frozen_parameters=False):
634
+ """
635
+ Convert ZeRO 2 or 3 checkpoint into a single fp32 consolidated ``state_dict`` file that can be
636
+ loaded with ``torch.load(file)`` + ``load_state_dict()`` and used for training without DeepSpeed.
637
+
638
+ Args:
639
+ - ``checkpoint_dir``: path to the desired checkpoint folder. (one that contains the tag-folder, like ``global_step14``)
640
+ - ``output_dir``: directory to the pytorch fp32 state_dict output files
641
+ - ``max_shard_size``: the maximum size for a checkpoint before being sharded, default value is 5GB
642
+ - ``safe_serialization``: whether to save the model using `safetensors` or the traditional PyTorch way (that uses `pickle`).
643
+ - ``tag``: checkpoint tag used as a unique identifier for checkpoint. If not provided will attempt to load tag in the file named ``latest`` in the checkpoint folder, e.g., ``global_step14``
644
+ - ``exclude_frozen_parameters``: exclude frozen parameters
645
+ """
646
+
647
+ # Dependency pre-check
648
+ if safe_serialization:
649
+ try:
650
+ from safetensors.torch import save_file
651
+ except ImportError:
652
+ print('If you want to use `safe_serialization`, please `pip install safetensors`')
653
+ raise
654
+ if max_shard_size is not None:
655
+ try:
656
+ from huggingface_hub import split_torch_state_dict_into_shards
657
+ except ImportError:
658
+ print('If you want to use `max_shard_size`, please `pip install huggingface_hub`')
659
+ raise
660
+
661
+ # Convert zero checkpoint to state_dict
662
+ state_dict = get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir,
663
+ tag,
664
+ exclude_frozen_parameters,
665
+ lazy_mode=True)
666
+
667
+ # Shard the model if it is too big.
668
+ weights_name = "model.safetensors" if safe_serialization else "pytorch_model.bin"
669
+ if max_shard_size is not None:
670
+ filename_pattern = weights_name.replace(".bin", "{suffix}.bin").replace(".safetensors", "{suffix}.safetensors")
671
+ # an memory-efficient approach for sharding
672
+ empty_state_dict = to_torch_tensor(state_dict, return_empty_tensor=True)
673
+ state_dict_split = split_torch_state_dict_into_shards(empty_state_dict,
674
+ filename_pattern=filename_pattern,
675
+ max_shard_size=max_shard_size)
676
+ else:
677
+ from collections import namedtuple
678
+ StateDictSplit = namedtuple("StateDictSplit", ["is_sharded", "filename_to_tensors"])
679
+ state_dict_split = StateDictSplit(is_sharded=False,
680
+ filename_to_tensors={weights_name: list(state_dict.keys())})
681
+
682
+ # Save the model by shard
683
+ os.makedirs(output_dir, exist_ok=True)
684
+ filename_to_tensors = state_dict_split.filename_to_tensors.items()
685
+ for shard_file, tensors in tqdm(filename_to_tensors, desc="Saving checkpoint shards"):
686
+ shard_state_dict = {tensor_name: state_dict[tensor_name] for tensor_name in tensors}
687
+ shard_state_dict = to_torch_tensor(shard_state_dict)
688
+ output_path = os.path.join(output_dir, shard_file)
689
+ if safe_serialization:
690
+ save_file(shard_state_dict, output_path, metadata={"format": "pt"})
691
+ else:
692
+ torch.save(shard_state_dict, output_path)
693
+ # release the memory of current shard
694
+ for tensor_name in list(shard_state_dict.keys()):
695
+ del state_dict[tensor_name]
696
+ del shard_state_dict[tensor_name]
697
+ del shard_state_dict
698
+ gc.collect()
699
+
700
+ # Save index if sharded
701
+ if state_dict_split.is_sharded:
702
+ index = {
703
+ "metadata": state_dict_split.metadata,
704
+ "weight_map": state_dict_split.tensor_to_filename,
705
+ }
706
+ save_index_file = "model.safetensors.index.json" if safe_serialization else "pytorch_model.bin.index.json"
707
+ save_index_file = os.path.join(output_dir, save_index_file)
708
+ with open(save_index_file, "w", encoding="utf-8") as f:
709
+ content = json.dumps(index, indent=2, sort_keys=True) + "\n"
710
+ f.write(content)
711
+
712
+
713
+ def load_state_dict_from_zero_checkpoint(model, checkpoint_dir, tag=None):
714
+ """
715
+ 1. Put the provided model to cpu
716
+ 2. Convert ZeRO 2 or 3 checkpoint into a single fp32 consolidated ``state_dict``
717
+ 3. Load it into the provided model
718
+
719
+ Args:
720
+ - ``model``: the model object to update
721
+ - ``checkpoint_dir``: path to the desired checkpoint folder. (one that contains the tag-folder, like ``global_step14``)
722
+ - ``tag``: checkpoint tag used as a unique identifier for checkpoint. If not provided will attempt to load tag in the file named ``latest`` in the checkpoint folder, e.g., ``global_step14``
723
+
724
+ Returns:
725
+ - ``model`: modified model
726
+
727
+ Make sure you have plenty of CPU memory available before you call this function. If you don't
728
+ have enough use the ``zero_to_fp32.py`` utility to do the conversion. You will find it
729
+ conveniently placed for you in the checkpoint folder.
730
+
731
+ A typical usage might be ::
732
+
733
+ from deepspeed.utils.zero_to_fp32 import load_state_dict_from_zero_checkpoint
734
+ model = load_state_dict_from_zero_checkpoint(trainer.model, checkpoint_dir)
735
+ # submit to model hub or save the model to share with others
736
+
737
+ Note, that once this was run, the ``model`` will no longer be usable in the deepspeed context
738
+ of the same application. i.e. you will need to re-initialize the deepspeed engine, since
739
+ ``model.load_state_dict(state_dict)`` will remove all the deepspeed magic from it.
740
+
741
+ """
742
+ logger.info("Extracting fp32 weights")
743
+ state_dict = get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir, tag)
744
+
745
+ logger.info("Overwriting model with fp32 weights")
746
+ model = model.cpu()
747
+ model.load_state_dict(state_dict, strict=False)
748
+
749
+ return model
750
+
751
+
752
+ if __name__ == "__main__":
753
+ parser = argparse.ArgumentParser()
754
+ parser.add_argument("checkpoint_dir",
755
+ type=str,
756
+ help="path to the desired checkpoint folder, e.g., path/checkpoint-12")
757
+ parser.add_argument("output_dir",
758
+ type=str,
759
+ help="directory to the pytorch fp32 state_dict output files"
760
+ "(e.g. path/checkpoint-12-output/)")
761
+ parser.add_argument(
762
+ "--max_shard_size",
763
+ type=str,
764
+ default="5GB",
765
+ help="The maximum size for a checkpoint before being sharded. Checkpoints shard will then be each of size"
766
+ "lower than this size. If expressed as a string, needs to be digits followed by a unit (like `5MB`"
767
+ "We default it to 5GB in order for models to be able to run easily on free-tier google colab instances"
768
+ "without CPU OOM issues.")
769
+ parser.add_argument(
770
+ "--safe_serialization",
771
+ default=False,
772
+ action='store_true',
773
+ help="Whether to save the model using `safetensors` or the traditional PyTorch way (that uses `pickle`).")
774
+ parser.add_argument("-t",
775
+ "--tag",
776
+ type=str,
777
+ default=None,
778
+ help="checkpoint tag used as a unique identifier for checkpoint. e.g., global_step1")
779
+ parser.add_argument("--exclude_frozen_parameters", action='store_true', help="exclude frozen parameters")
780
+ parser.add_argument("-d", "--debug", action='store_true', help="enable debug")
781
+ args = parser.parse_args()
782
+
783
+ debug = args.debug
784
+
785
+ convert_zero_checkpoint_to_fp32_state_dict(args.checkpoint_dir,
786
+ args.output_dir,
787
+ max_shard_size=args.max_shard_size,
788
+ safe_serialization=args.safe_serialization,
789
+ tag=args.tag,
790
+ exclude_frozen_parameters=args.exclude_frozen_parameters)