diff --git a/.gitattributes b/.gitattributes index a6344aac8c09253b3b630fb776ae94478aa0275b..c149555b5474b181cd0ce18afd369315ab44c2ae 100644 --- a/.gitattributes +++ b/.gitattributes @@ -33,3 +33,18 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text *.zip filter=lfs diff=lfs merge=lfs -text *.zst filter=lfs diff=lfs merge=lfs -text *tfevents* filter=lfs diff=lfs merge=lfs -text +qwen3/amid/checkpoint-1256/tokenizer.json filter=lfs diff=lfs merge=lfs -text +qwen3/amid/checkpoint-1570/tokenizer.json filter=lfs diff=lfs merge=lfs -text +qwen3/amid/checkpoint-314/tokenizer.json filter=lfs diff=lfs merge=lfs -text +qwen3/amid/checkpoint-628/tokenizer.json filter=lfs diff=lfs merge=lfs -text +qwen3/amid/checkpoint-942/tokenizer.json filter=lfs diff=lfs merge=lfs -text +qwen3/amid/tokenizer.json filter=lfs diff=lfs merge=lfs -text +qwen3/csd/checkpoint-1256/tokenizer.json filter=lfs diff=lfs merge=lfs -text +qwen3/csd/checkpoint-1570/tokenizer.json filter=lfs diff=lfs merge=lfs -text +qwen3/csd/checkpoint-314/tokenizer.json filter=lfs diff=lfs merge=lfs -text +qwen3/csd/checkpoint-628/tokenizer.json filter=lfs diff=lfs merge=lfs -text +qwen3/csd/checkpoint-942/tokenizer.json filter=lfs diff=lfs merge=lfs -text +qwen3/csd/tokenizer.json filter=lfs diff=lfs merge=lfs -text +qwen3/distillm_adaptive_sfkl/checkpoint-1256/tokenizer.json filter=lfs diff=lfs merge=lfs -text +qwen3/distillm_adaptive_sfkl/checkpoint-1570/tokenizer.json filter=lfs diff=lfs merge=lfs -text +qwen3/distillm_adaptive_sfkl/checkpoint-314/tokenizer.json filter=lfs diff=lfs merge=lfs -text diff --git a/qwen3/amid/README.md b/qwen3/amid/README.md new file mode 100644 index 0000000000000000000000000000000000000000..6b12ad5993fadf3afe3a4cea738a0ca2aed10f6c --- /dev/null +++ b/qwen3/amid/README.md @@ -0,0 +1,79 @@ +--- +library_name: peft +license: other +base_model: Qwen/Qwen3-0.6B +tags: +- base_model:adapter:Qwen/Qwen3-0.6B +- llama-factory +- lora +- transformers +pipeline_tag: text-generation +model-index: +- name: amid + results: [] +--- + + + +# amid + +This model is a fine-tuned version of [Qwen/Qwen3-0.6B](https://huggingface.co/Qwen/Qwen3-0.6B) on the cypher_prepared_train dataset. +It achieves the following results on the evaluation set: +- Loss: 0.0040 +- Selector Count: 1712.0 +- Generator Count: 1712.0 +- Selector Accuracy: 98.6565 +- Generator Exact Match: 96.028 +- Generator Rouge1: 99.8671 +- Generator Rouge2: 99.8011 +- Generator Rougel: 99.6739 + +## Model description + +More information needed + +## Intended uses & limitations + +More information needed + +## Training and evaluation data + +More information needed + +## Training procedure + +### Training hyperparameters + +The following hyperparameters were used during training: +- learning_rate: 0.0001 +- train_batch_size: 2 +- eval_batch_size: 16 +- seed: 42 +- distributed_type: multi-GPU +- num_devices: 2 +- gradient_accumulation_steps: 8 +- total_train_batch_size: 32 +- total_eval_batch_size: 32 +- optimizer: Use OptimizerNames.ADAMW_TORCH with betas=(0.9,0.999) and epsilon=1e-08 and optimizer_args=No additional optimizer arguments +- lr_scheduler_type: cosine_with_min_lr +- num_epochs: 5 + +### Training results + +| Training Loss | Epoch | Step | Validation Loss | Selector Count | Generator Count | Selector Accuracy | Generator Exact Match | Generator Rouge1 | Generator Rouge2 | Generator Rougel | +|:-------------:|:-----:|:----:|:---------------:|:--------------:|:---------------:|:-----------------:|:---------------------:|:----------------:|:----------------:|:----------------:| +| 0.0068 | 1.0 | 314 | 0.0128 | 1712.0 | 1712.0 | 90.1869 | 87.3832 | 99.2069 | 98.8793 | 98.7553 | +| 0.0036 | 2.0 | 628 | 0.0069 | 1712.0 | 1712.0 | 96.9042 | 93.5164 | 99.7294 | 99.5697 | 99.5152 | +| 0.0006 | 3.0 | 942 | 0.0057 | 1712.0 | 1712.0 | 96.5537 | 95.3855 | 99.8982 | 99.8084 | 99.6633 | +| 0.0003 | 4.0 | 1256 | 0.0043 | 1712.0 | 1712.0 | 98.1893 | 95.8528 | 99.9186 | 99.8428 | 99.7108 | +| 0.0004 | 5.0 | 1570 | 0.0040 | 1712.0 | 1712.0 | 98.6565 | 95.736 | 99.9082 | 99.8294 | 99.7068 | + + +### Framework versions + +- PEFT 0.18.1 +- Transformers 5.8.0 +- Pytorch 2.9.1+cu128 +- Datasets 4.0.0 +- Tokenizers 0.22.2 \ No newline at end of file diff --git a/qwen3/amid/adapter_config.json b/qwen3/amid/adapter_config.json new file mode 100644 index 0000000000000000000000000000000000000000..16362f47190537658d6b04519de786417a5f6c2f --- /dev/null +++ b/qwen3/amid/adapter_config.json @@ -0,0 +1,46 @@ +{ + "alora_invocation_tokens": null, + "alpha_pattern": {}, + "arrow_config": null, + "auto_mapping": null, + "base_model_name_or_path": "Qwen/Qwen3-0.6B", + "bias": "none", + "corda_config": null, + "ensure_weight_tying": false, + "eva_config": null, + "exclude_modules": null, + "fan_in_fan_out": false, + "inference_mode": true, + "init_lora_weights": true, + "layer_replication": null, + "layers_pattern": null, + "layers_to_transform": null, + "loftq_config": {}, + "lora_alpha": 64, + "lora_bias": false, + "lora_dropout": 0.1, + "megatron_config": null, + "megatron_core": "megatron.core", + "modules_to_save": null, + "peft_type": "LORA", + "peft_version": "0.18.1", + "qalora_group_size": 16, + "r": 32, + "rank_pattern": {}, + "revision": null, + "target_modules": [ + "v_proj", + "q_proj", + "o_proj", + "gate_proj", + "up_proj", + "k_proj", + "down_proj" + ], + "target_parameters": null, + "task_type": "CAUSAL_LM", + "trainable_token_indices": null, + "use_dora": false, + "use_qalora": false, + "use_rslora": false +} \ No newline at end of file diff --git a/qwen3/amid/adapter_model.safetensors b/qwen3/amid/adapter_model.safetensors new file mode 100644 index 0000000000000000000000000000000000000000..93524c4b229da26352140faae8b8d1bed15559bc --- /dev/null +++ b/qwen3/amid/adapter_model.safetensors @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:db85fbee8a5b8671bb7eea278430126deabd15db5ca476d10a9fd242caf6c334 +size 40422560 diff --git a/qwen3/amid/all_results.json b/qwen3/amid/all_results.json new file mode 100644 index 0000000000000000000000000000000000000000..c884ac87bac73cacf29b75b03b5e83eaceb2b530 --- /dev/null +++ b/qwen3/amid/all_results.json @@ -0,0 +1,19 @@ +{ + "epoch": 5.0, + "eval_generator_count": 1712.0, + "eval_generator_exact_match": 96.028, + "eval_generator_rouge1": 99.8671, + "eval_generator_rouge2": 99.8011, + "eval_generator_rougeL": 99.6739, + "eval_loss": 0.004025007598102093, + "eval_runtime": 579.6459, + "eval_samples_per_second": 5.89, + "eval_selector_accuracy": 98.6565, + "eval_selector_count": 1712.0, + "eval_steps_per_second": 0.185, + "total_flos": 5.871444840310374e+16, + "train_loss": 0.01864182253792336, + "train_runtime": 7621.8556, + "train_samples_per_second": 6.578, + "train_steps_per_second": 0.206 +} \ No newline at end of file diff --git a/qwen3/amid/chat_template.jinja b/qwen3/amid/chat_template.jinja new file mode 100644 index 0000000000000000000000000000000000000000..01be9b307daa2d425f7c168c9fb145a286e0afb4 --- /dev/null +++ b/qwen3/amid/chat_template.jinja @@ -0,0 +1,89 @@ +{%- if tools %} + {{- '<|im_start|>system\n' }} + {%- if messages[0].role == 'system' %} + {{- messages[0].content + '\n\n' }} + {%- endif %} + {{- "# Tools\n\nYou may call one or more functions to assist with the user query.\n\nYou are provided with function signatures within XML tags:\n" }} + {%- for tool in tools %} + {{- "\n" }} + {{- tool | tojson }} + {%- endfor %} + {{- "\n\n\nFor each function call, return a json object with function name and arguments within XML tags:\n\n{\"name\": , \"arguments\": }\n<|im_end|>\n" }} +{%- else %} + {%- if messages[0].role == 'system' %} + {{- '<|im_start|>system\n' + messages[0].content + '<|im_end|>\n' }} + {%- endif %} +{%- endif %} +{%- set ns = namespace(multi_step_tool=true, last_query_index=messages|length - 1) %} +{%- for message in messages[::-1] %} + {%- set index = (messages|length - 1) - loop.index0 %} + {%- if ns.multi_step_tool and message.role == "user" and message.content is string and not(message.content.startswith('') and message.content.endswith('')) %} + {%- set ns.multi_step_tool = false %} + {%- set ns.last_query_index = index %} + {%- endif %} +{%- endfor %} +{%- for message in messages %} + {%- if message.content is string %} + {%- set content = message.content %} + {%- else %} + {%- set content = '' %} + {%- endif %} + {%- if (message.role == "user") or (message.role == "system" and not loop.first) %} + {{- '<|im_start|>' + message.role + '\n' + content + '<|im_end|>' + '\n' }} + {%- elif message.role == "assistant" %} + {%- set reasoning_content = '' %} + {%- if message.reasoning_content is string %} + {%- set reasoning_content = message.reasoning_content %} + {%- else %} + {%- if '' in content %} + {%- set reasoning_content = content.split('')[0].rstrip('\n').split('')[-1].lstrip('\n') %} + {%- set content = content.split('')[-1].lstrip('\n') %} + {%- endif %} + {%- endif %} + {%- if loop.index0 > ns.last_query_index %} + {%- if loop.last or (not loop.last and reasoning_content) %} + {{- '<|im_start|>' + message.role + '\n\n' + reasoning_content.strip('\n') + '\n\n\n' + content.lstrip('\n') }} + {%- else %} + {{- '<|im_start|>' + message.role + '\n' + content }} + {%- endif %} + {%- else %} + {{- '<|im_start|>' + message.role + '\n' + content }} + {%- endif %} + {%- if message.tool_calls %} + {%- for tool_call in message.tool_calls %} + {%- if (loop.first and content) or (not loop.first) %} + {{- '\n' }} + {%- endif %} + {%- if tool_call.function %} + {%- set tool_call = tool_call.function %} + {%- endif %} + {{- '\n{"name": "' }} + {{- tool_call.name }} + {{- '", "arguments": ' }} + {%- if tool_call.arguments is string %} + {{- tool_call.arguments }} + {%- else %} + {{- tool_call.arguments | tojson }} + {%- endif %} + {{- '}\n' }} + {%- endfor %} + {%- endif %} + {{- '<|im_end|>\n' }} + {%- elif message.role == "tool" %} + {%- if loop.first or (messages[loop.index0 - 1].role != "tool") %} + {{- '<|im_start|>user' }} + {%- endif %} + {{- '\n\n' }} + {{- content }} + {{- '\n' }} + {%- if loop.last or (messages[loop.index0 + 1].role != "tool") %} + {{- '<|im_end|>\n' }} + {%- endif %} + {%- endif %} +{%- endfor %} +{%- if add_generation_prompt %} + {{- '<|im_start|>assistant\n' }} + {%- if enable_thinking is defined and enable_thinking is false %} + {{- '\n\n\n\n' }} + {%- endif %} +{%- endif %} \ No newline at end of file diff --git a/qwen3/amid/checkpoint-1256/README.md b/qwen3/amid/checkpoint-1256/README.md new file mode 100644 index 0000000000000000000000000000000000000000..776f98d43659dd923b8c3e5649c5ae66d1f99f3e --- /dev/null +++ b/qwen3/amid/checkpoint-1256/README.md @@ -0,0 +1,208 @@ +--- +base_model: Qwen/Qwen3-0.6B +library_name: peft +pipeline_tag: text-generation +tags: +- base_model:adapter:Qwen/Qwen3-0.6B +- llama-factory +- lora +- transformers +--- + +# Model Card for Model ID + + + + + +## Model Details + +### Model Description + + + + + +- **Developed by:** [More Information Needed] +- **Funded by [optional]:** [More Information Needed] +- **Shared by [optional]:** [More Information Needed] +- **Model type:** [More Information Needed] +- **Language(s) (NLP):** [More Information Needed] +- **License:** [More Information Needed] +- **Finetuned from model [optional]:** [More Information Needed] + +### Model Sources [optional] + + + +- **Repository:** [More Information Needed] +- **Paper [optional]:** [More Information Needed] +- **Demo [optional]:** [More Information Needed] + +## Uses + + + +### Direct Use + + + +[More Information Needed] + +### Downstream Use [optional] + + + +[More Information Needed] + +### Out-of-Scope Use + + + +[More Information Needed] + +## Bias, Risks, and Limitations + + + +[More Information Needed] + +### Recommendations + + + +Users (both direct and downstream) should be made aware of the risks, biases and limitations of the model. More information needed for further recommendations. + +## How to Get Started with the Model + +Use the code below to get started with the model. + +[More Information Needed] + +## Training Details + +### Training Data + + + +[More Information Needed] + +### Training Procedure + + + +#### Preprocessing [optional] + +[More Information Needed] + + +#### Training Hyperparameters + +- **Training regime:** [More Information Needed] + +#### Speeds, Sizes, Times [optional] + + + +[More Information Needed] + +## Evaluation + + + +### Testing Data, Factors & Metrics + +#### Testing Data + + + +[More Information Needed] + +#### Factors + + + +[More Information Needed] + +#### Metrics + + + +[More Information Needed] + +### Results + +[More Information Needed] + +#### Summary + + + +## Model Examination [optional] + + + +[More Information Needed] + +## Environmental Impact + + + +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). + +- **Hardware Type:** [More Information Needed] +- **Hours used:** [More Information Needed] +- **Cloud Provider:** [More Information Needed] +- **Compute Region:** [More Information Needed] +- **Carbon Emitted:** [More Information Needed] + +## Technical Specifications [optional] + +### Model Architecture and Objective + +[More Information Needed] + +### Compute Infrastructure + +[More Information Needed] + +#### Hardware + +[More Information Needed] + +#### Software + +[More Information Needed] + +## Citation [optional] + + + +**BibTeX:** + +[More Information Needed] + +**APA:** + +[More Information Needed] + +## Glossary [optional] + + + +[More Information Needed] + +## More Information [optional] + +[More Information Needed] + +## Model Card Authors [optional] + +[More Information Needed] + +## Model Card Contact + +[More Information Needed] +### Framework versions + +- PEFT 0.18.1 \ No newline at end of file diff --git a/qwen3/amid/checkpoint-1256/adapter_config.json b/qwen3/amid/checkpoint-1256/adapter_config.json new file mode 100644 index 0000000000000000000000000000000000000000..16362f47190537658d6b04519de786417a5f6c2f --- /dev/null +++ b/qwen3/amid/checkpoint-1256/adapter_config.json @@ -0,0 +1,46 @@ +{ + "alora_invocation_tokens": null, + "alpha_pattern": {}, + "arrow_config": null, + "auto_mapping": null, + "base_model_name_or_path": "Qwen/Qwen3-0.6B", + "bias": "none", + "corda_config": null, + "ensure_weight_tying": false, + "eva_config": null, + "exclude_modules": null, + "fan_in_fan_out": false, + "inference_mode": true, + "init_lora_weights": true, + "layer_replication": null, + "layers_pattern": null, + "layers_to_transform": null, + "loftq_config": {}, + "lora_alpha": 64, + "lora_bias": false, + "lora_dropout": 0.1, + "megatron_config": null, + "megatron_core": "megatron.core", + "modules_to_save": null, + "peft_type": "LORA", + "peft_version": "0.18.1", + "qalora_group_size": 16, + "r": 32, + "rank_pattern": {}, + "revision": null, + "target_modules": [ + "v_proj", + "q_proj", + "o_proj", + "gate_proj", + "up_proj", + "k_proj", + "down_proj" + ], + "target_parameters": null, + "task_type": "CAUSAL_LM", + "trainable_token_indices": null, + "use_dora": false, + "use_qalora": false, + "use_rslora": false +} \ No newline at end of file diff --git a/qwen3/amid/checkpoint-1256/adapter_model.safetensors b/qwen3/amid/checkpoint-1256/adapter_model.safetensors new file mode 100644 index 0000000000000000000000000000000000000000..18d33b0d0510c794c3dbe3b609c61fa1166bff4b --- /dev/null +++ b/qwen3/amid/checkpoint-1256/adapter_model.safetensors @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e895f0f483699995b38d2518b8ecce916cfba3f34b558ab5d80a2533af2989f8 +size 40422560 diff --git a/qwen3/amid/checkpoint-1256/chat_template.jinja b/qwen3/amid/checkpoint-1256/chat_template.jinja new file mode 100644 index 0000000000000000000000000000000000000000..01be9b307daa2d425f7c168c9fb145a286e0afb4 --- /dev/null +++ b/qwen3/amid/checkpoint-1256/chat_template.jinja @@ -0,0 +1,89 @@ +{%- if tools %} + {{- '<|im_start|>system\n' }} + {%- if messages[0].role == 'system' %} + {{- messages[0].content + '\n\n' }} + {%- endif %} + {{- "# Tools\n\nYou may call one or more functions to assist with the user query.\n\nYou are provided with function signatures within XML tags:\n" }} + {%- for tool in tools %} + {{- "\n" }} + {{- tool | tojson }} + {%- endfor %} + {{- "\n\n\nFor each function call, return a json object with function name and arguments within XML tags:\n\n{\"name\": , \"arguments\": }\n<|im_end|>\n" }} +{%- else %} + {%- if messages[0].role == 'system' %} + {{- '<|im_start|>system\n' + messages[0].content + '<|im_end|>\n' }} + {%- endif %} +{%- endif %} +{%- set ns = namespace(multi_step_tool=true, last_query_index=messages|length - 1) %} +{%- for message in messages[::-1] %} + {%- set index = (messages|length - 1) - loop.index0 %} + {%- if ns.multi_step_tool and message.role == "user" and message.content is string and not(message.content.startswith('') and message.content.endswith('')) %} + {%- set ns.multi_step_tool = false %} + {%- set ns.last_query_index = index %} + {%- endif %} +{%- endfor %} +{%- for message in messages %} + {%- if message.content is string %} + {%- set content = message.content %} + {%- else %} + {%- set content = '' %} + {%- endif %} + {%- if (message.role == "user") or (message.role == "system" and not loop.first) %} + {{- '<|im_start|>' + message.role + '\n' + content + '<|im_end|>' + '\n' }} + {%- elif message.role == "assistant" %} + {%- set reasoning_content = '' %} + {%- if message.reasoning_content is string %} + {%- set reasoning_content = message.reasoning_content %} + {%- else %} + {%- if '' in content %} + {%- set reasoning_content = content.split('')[0].rstrip('\n').split('')[-1].lstrip('\n') %} + {%- set content = content.split('')[-1].lstrip('\n') %} + {%- endif %} + {%- endif %} + {%- if loop.index0 > ns.last_query_index %} + {%- if loop.last or (not loop.last and reasoning_content) %} + {{- '<|im_start|>' + message.role + '\n\n' + reasoning_content.strip('\n') + '\n\n\n' + content.lstrip('\n') }} + {%- else %} + {{- '<|im_start|>' + message.role + '\n' + content }} + {%- endif %} + {%- else %} + {{- '<|im_start|>' + message.role + '\n' + content }} + {%- endif %} + {%- if message.tool_calls %} + {%- for tool_call in message.tool_calls %} + {%- if (loop.first and content) or (not loop.first) %} + {{- '\n' }} + {%- endif %} + {%- if tool_call.function %} + {%- set tool_call = tool_call.function %} + {%- endif %} + {{- '\n{"name": "' }} + {{- tool_call.name }} + {{- '", "arguments": ' }} + {%- if tool_call.arguments is string %} + {{- tool_call.arguments }} + {%- else %} + {{- tool_call.arguments | tojson }} + {%- endif %} + {{- '}\n' }} + {%- endfor %} + {%- endif %} + {{- '<|im_end|>\n' }} + {%- elif message.role == "tool" %} + {%- if loop.first or (messages[loop.index0 - 1].role != "tool") %} + {{- '<|im_start|>user' }} + {%- endif %} + {{- '\n\n' }} + {{- content }} + {{- '\n' }} + {%- if loop.last or (messages[loop.index0 + 1].role != "tool") %} + {{- '<|im_end|>\n' }} + {%- endif %} + {%- endif %} +{%- endfor %} +{%- if add_generation_prompt %} + {{- '<|im_start|>assistant\n' }} + {%- if enable_thinking is defined and enable_thinking is false %} + {{- '\n\n\n\n' }} + {%- endif %} +{%- endif %} \ No newline at end of file diff --git a/qwen3/amid/checkpoint-1256/global_step1256/bf16_zero_pp_rank_0_mp_rank_00_optim_states.pt b/qwen3/amid/checkpoint-1256/global_step1256/bf16_zero_pp_rank_0_mp_rank_00_optim_states.pt new file mode 100644 index 0000000000000000000000000000000000000000..67dc43ff15fb981ccd75531c19301c37143f964e --- /dev/null +++ b/qwen3/amid/checkpoint-1256/global_step1256/bf16_zero_pp_rank_0_mp_rank_00_optim_states.pt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:daf81cbb6f746277d70839536a20bb3b6caef9b74a015978d16aef31a5c91d3e +size 121135557 diff --git a/qwen3/amid/checkpoint-1256/global_step1256/bf16_zero_pp_rank_1_mp_rank_00_optim_states.pt b/qwen3/amid/checkpoint-1256/global_step1256/bf16_zero_pp_rank_1_mp_rank_00_optim_states.pt new file mode 100644 index 0000000000000000000000000000000000000000..d98497b39bf0def47ebd28a351286ed47a8fa75a --- /dev/null +++ b/qwen3/amid/checkpoint-1256/global_step1256/bf16_zero_pp_rank_1_mp_rank_00_optim_states.pt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:44369c0a57c589843da109a7f8fd845aebfbf5d3a285d0ed07f57adac8935df3 +size 121135749 diff --git a/qwen3/amid/checkpoint-1256/global_step1256/mp_rank_00_model_states.pt b/qwen3/amid/checkpoint-1256/global_step1256/mp_rank_00_model_states.pt new file mode 100644 index 0000000000000000000000000000000000000000..bf82f007d10484089fdfa7d383764f985e0f7d1e --- /dev/null +++ b/qwen3/amid/checkpoint-1256/global_step1256/mp_rank_00_model_states.pt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c7cf6368e603b46a1c1678c78c926cd574cebc8901f75d8b9ce6c471073a294d +size 351841765 diff --git a/qwen3/amid/checkpoint-1256/latest b/qwen3/amid/checkpoint-1256/latest new file mode 100644 index 0000000000000000000000000000000000000000..74abb3d23ea83ebdac59918752db5d1782834ca7 --- /dev/null +++ b/qwen3/amid/checkpoint-1256/latest @@ -0,0 +1 @@ +global_step1256 \ No newline at end of file diff --git a/qwen3/amid/checkpoint-1256/rng_state_0.pth b/qwen3/amid/checkpoint-1256/rng_state_0.pth new file mode 100644 index 0000000000000000000000000000000000000000..2b7f039f457e66dff06dde7241eed0ae7045f59a --- /dev/null +++ b/qwen3/amid/checkpoint-1256/rng_state_0.pth @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7530a82318bfc63bf9efe3909e0cfb53991fac12078349c3cd390c37b6717a9c +size 14917 diff --git a/qwen3/amid/checkpoint-1256/rng_state_1.pth b/qwen3/amid/checkpoint-1256/rng_state_1.pth new file mode 100644 index 0000000000000000000000000000000000000000..069e0c29d1ba8eb599dc83543dbe5bcff209ded7 --- /dev/null +++ b/qwen3/amid/checkpoint-1256/rng_state_1.pth @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:82240e85efab23fc7f6753a25eb53f58033ffdc19e106b8c4ca745f9571b2f29 +size 14917 diff --git a/qwen3/amid/checkpoint-1256/scheduler.pt b/qwen3/amid/checkpoint-1256/scheduler.pt new file mode 100644 index 0000000000000000000000000000000000000000..40e863d07cfed22cd912014eb3ba3fd2b16b173f --- /dev/null +++ b/qwen3/amid/checkpoint-1256/scheduler.pt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1775297f14e75f7463ae51983a66296f81f4b2e2e5d7234f1a6d295abfa4cf23 +size 1465 diff --git a/qwen3/amid/checkpoint-1256/tokenizer.json b/qwen3/amid/checkpoint-1256/tokenizer.json new file mode 100644 index 0000000000000000000000000000000000000000..c7afbed2efcdf019f88ab0572ec29d3bf595dfe2 --- /dev/null +++ b/qwen3/amid/checkpoint-1256/tokenizer.json @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:be75606093db2094d7cd20f3c2f385c212750648bd6ea4fb2bf507a6a4c55506 +size 11422650 diff --git a/qwen3/amid/checkpoint-1256/tokenizer_config.json b/qwen3/amid/checkpoint-1256/tokenizer_config.json new file mode 100644 index 0000000000000000000000000000000000000000..6623da03457d79d2cd4af9557e9f31407cdb835c --- /dev/null +++ b/qwen3/amid/checkpoint-1256/tokenizer_config.json @@ -0,0 +1,31 @@ +{ + "add_prefix_space": false, + "backend": "tokenizers", + "bos_token": null, + "clean_up_tokenization_spaces": false, + "eos_token": "<|im_end|>", + "errors": "replace", + "extra_special_tokens": [ + "<|im_start|>", + "<|im_end|>", + "<|object_ref_start|>", + "<|object_ref_end|>", + "<|box_start|>", + "<|box_end|>", + "<|quad_start|>", + "<|quad_end|>", + "<|vision_start|>", + "<|vision_end|>", + "<|vision_pad|>", + "<|image_pad|>", + "<|video_pad|>" + ], + "is_local": false, + "local_files_only": false, + "model_max_length": 131072, + "pad_token": "<|endoftext|>", + "padding_side": "right", + "split_special_tokens": false, + "tokenizer_class": "Qwen2Tokenizer", + "unk_token": null +} diff --git a/qwen3/amid/checkpoint-1256/trainer_state.json b/qwen3/amid/checkpoint-1256/trainer_state.json new file mode 100644 index 0000000000000000000000000000000000000000..765791289ac887e7428011b543fd937ff1430919 --- /dev/null +++ b/qwen3/amid/checkpoint-1256/trainer_state.json @@ -0,0 +1,528 @@ +{ + "best_global_step": null, + "best_metric": null, + "best_model_checkpoint": null, + "epoch": 4.0, + "eval_steps": 500, + "global_step": 1256, + "is_hyper_param_search": false, + "is_local_process_zero": true, + "is_world_process_zero": true, + "log_history": [ + { + "epoch": 0.06382130035899482, + "grad_norm": 0.38384687900543213, + "learning_rate": 9.996390385474569e-05, + "loss": 0.27438180446624755, + "step": 20 + }, + { + "epoch": 0.12764260071798963, + "grad_norm": 0.38263317942619324, + "learning_rate": 9.984797509888031e-05, + "loss": 0.13717052936553956, + "step": 40 + }, + { + "epoch": 0.19146390107698444, + "grad_norm": 0.08620006591081619, + "learning_rate": 9.965229938050925e-05, + "loss": 0.13135391473770142, + "step": 60 + }, + { + "epoch": 0.25528520143597927, + "grad_norm": 0.15773959457874298, + "learning_rate": 9.937719005663432e-05, + "loss": 0.1076702356338501, + "step": 80 + }, + { + "epoch": 0.3191065017949741, + "grad_norm": 0.22962816059589386, + "learning_rate": 9.902308769000724e-05, + "loss": 0.08698999881744385, + "step": 100 + }, + { + "epoch": 0.3829278021539689, + "grad_norm": 0.12232966721057892, + "learning_rate": 9.859055934360789e-05, + "loss": 0.1128507375717163, + "step": 120 + }, + { + "epoch": 0.4467491025129637, + "grad_norm": 0.15597161650657654, + "learning_rate": 9.808029767254437e-05, + "loss": 0.1277535080909729, + "step": 140 + }, + { + "epoch": 0.5105704028719585, + "grad_norm": 0.7329031825065613, + "learning_rate": 9.749311981482817e-05, + "loss": 0.08885469436645507, + "step": 160 + }, + { + "epoch": 0.5743917032309533, + "grad_norm": 0.45483648777008057, + "learning_rate": 9.682996608280154e-05, + "loss": 0.07881734371185303, + "step": 180 + }, + { + "epoch": 0.6382130035899481, + "grad_norm": 0.16407009959220886, + "learning_rate": 9.609189845731207e-05, + "loss": 0.06113555431365967, + "step": 200 + }, + { + "epoch": 0.702034303948943, + "grad_norm": 0.07238732278347015, + "learning_rate": 9.52800988870462e-05, + "loss": 0.06768973469734192, + "step": 220 + }, + { + "epoch": 0.7658556043079378, + "grad_norm": 0.4741341471672058, + "learning_rate": 9.439586739574513e-05, + "loss": 0.04917148947715759, + "step": 240 + }, + { + "epoch": 0.8296769046669326, + "grad_norm": 0.36410900950431824, + "learning_rate": 9.344062000033414e-05, + "loss": 0.010153122991323472, + "step": 260 + }, + { + "epoch": 0.8934982050259274, + "grad_norm": 0.11222824454307556, + "learning_rate": 9.241588644329919e-05, + "loss": 0.00552816241979599, + "step": 280 + }, + { + "epoch": 0.9573195053849222, + "grad_norm": 0.47910866141319275, + "learning_rate": 9.132330774294252e-05, + "loss": 0.006760746240615845, + "step": 300 + }, + { + "epoch": 1.0, + "eval_generator_count": 1712.0, + "eval_generator_exact_match": 87.3832, + "eval_generator_rouge1": 99.2069, + "eval_generator_rouge2": 98.8793, + "eval_generator_rougeL": 98.7553, + "eval_loss": 0.012839075177907944, + "eval_runtime": 592.0147, + "eval_samples_per_second": 5.767, + "eval_selector_accuracy": 90.1869, + "eval_selector_count": 1712.0, + "eval_steps_per_second": 0.181, + "step": 314 + }, + { + "epoch": 1.0191463901076985, + "grad_norm": 0.27295932173728943, + "learning_rate": 9.01646335654399e-05, + "loss": 0.009849193692207336, + "step": 320 + }, + { + "epoch": 1.0829676904666932, + "grad_norm": 0.060826949775218964, + "learning_rate": 8.894171942290817e-05, + "loss": 0.005673223733901977, + "step": 340 + }, + { + "epoch": 1.146788990825688, + "grad_norm": 0.04862668365240097, + "learning_rate": 8.765652370197003e-05, + "loss": 0.005297792330384255, + "step": 360 + }, + { + "epoch": 1.210610291184683, + "grad_norm": 0.05064748600125313, + "learning_rate": 8.631110452757467e-05, + "loss": 0.0021365636959671972, + "step": 380 + }, + { + "epoch": 1.2744315915436777, + "grad_norm": 0.05359279736876488, + "learning_rate": 8.490761646709642e-05, + "loss": 0.00429258793592453, + "step": 400 + }, + { + "epoch": 1.3382528919026724, + "grad_norm": 0.11369121074676514, + "learning_rate": 8.344830707998953e-05, + "loss": 0.0034508116543292998, + "step": 420 + }, + { + "epoch": 1.4020741922616673, + "grad_norm": 0.01604766771197319, + "learning_rate": 8.193551331852458e-05, + "loss": 0.0028350137174129484, + "step": 440 + }, + { + "epoch": 1.4658954926206622, + "grad_norm": 0.15401995182037354, + "learning_rate": 8.037165778537033e-05, + "loss": 0.005546276643872261, + "step": 460 + }, + { + "epoch": 1.5297167929796571, + "grad_norm": 0.5877118706703186, + "learning_rate": 7.875924485401427e-05, + "loss": 0.0044526983052492145, + "step": 480 + }, + { + "epoch": 1.5935380933386518, + "grad_norm": 0.10250785946846008, + "learning_rate": 7.710085665823444e-05, + "loss": 0.0056363165378570555, + "step": 500 + }, + { + "epoch": 1.6573593936976465, + "grad_norm": 0.043251167982816696, + "learning_rate": 7.539914895704521e-05, + "loss": 0.0032581716775894167, + "step": 520 + }, + { + "epoch": 1.7211806940566414, + "grad_norm": 0.2089434117078781, + "learning_rate": 7.365684688173908e-05, + "loss": 0.004207362234592438, + "step": 540 + }, + { + "epoch": 1.7850019944156363, + "grad_norm": 0.14037534594535828, + "learning_rate": 7.18767405718347e-05, + "loss": 0.0019151581451296805, + "step": 560 + }, + { + "epoch": 1.848823294774631, + "grad_norm": 0.22862067818641663, + "learning_rate": 7.006168070692036e-05, + "loss": 0.004427855834364891, + "step": 580 + }, + { + "epoch": 1.9126445951336257, + "grad_norm": 0.03684071823954582, + "learning_rate": 6.821457394154786e-05, + "loss": 0.0017833203077316285, + "step": 600 + }, + { + "epoch": 1.9764658954926206, + "grad_norm": 0.0672929510474205, + "learning_rate": 6.633837825048768e-05, + "loss": 0.0035866759717464447, + "step": 620 + }, + { + "epoch": 2.0, + "eval_generator_count": 1712.0, + "eval_generator_exact_match": 93.5164, + "eval_generator_rouge1": 99.7294, + "eval_generator_rouge2": 99.5697, + "eval_generator_rougeL": 99.5152, + "eval_loss": 0.006910035386681557, + "eval_runtime": 591.6591, + "eval_samples_per_second": 5.77, + "eval_selector_accuracy": 96.9042, + "eval_selector_count": 1712.0, + "eval_steps_per_second": 0.181, + "step": 628 + }, + { + "epoch": 2.038292780215397, + "grad_norm": 0.029134005308151245, + "learning_rate": 6.443609819179926e-05, + "loss": 0.0020816387608647347, + "step": 640 + }, + { + "epoch": 2.102114080574392, + "grad_norm": 0.17367292940616608, + "learning_rate": 6.251078009530256e-05, + "loss": 0.0019141122698783874, + "step": 660 + }, + { + "epoch": 2.1659353809333863, + "grad_norm": 0.016447540372610092, + "learning_rate": 6.0565507184155677e-05, + "loss": 0.0009251200594007969, + "step": 680 + }, + { + "epoch": 2.2297566812923812, + "grad_norm": 0.015570643357932568, + "learning_rate": 5.860339463735136e-05, + "loss": 0.0017806822434067726, + "step": 700 + }, + { + "epoch": 2.293577981651376, + "grad_norm": 0.010291235521435738, + "learning_rate": 5.662758460103895e-05, + "loss": 0.0010542120784521104, + "step": 720 + }, + { + "epoch": 2.357399282010371, + "grad_norm": 0.012873738072812557, + "learning_rate": 5.464124115666095e-05, + "loss": 0.0009571929462254047, + "step": 740 + }, + { + "epoch": 2.421220582369366, + "grad_norm": 0.009928264655172825, + "learning_rate": 5.264754525396212e-05, + "loss": 0.0007098949514329434, + "step": 760 + }, + { + "epoch": 2.4850418827283605, + "grad_norm": 0.014300181530416012, + "learning_rate": 5.06496896169857e-05, + "loss": 0.0007610605098307133, + "step": 780 + }, + { + "epoch": 2.5488631830873554, + "grad_norm": 0.03284010663628578, + "learning_rate": 4.865087363121384e-05, + "loss": 0.002758556976914406, + "step": 800 + }, + { + "epoch": 2.6126844834463503, + "grad_norm": 0.19087237119674683, + "learning_rate": 4.6654298220040673e-05, + "loss": 0.0011194748803973198, + "step": 820 + }, + { + "epoch": 2.6765057838053448, + "grad_norm": 0.02937050722539425, + "learning_rate": 4.466316071878229e-05, + "loss": 0.0014943076297640801, + "step": 840 + }, + { + "epoch": 2.74032708416434, + "grad_norm": 0.031206471845507622, + "learning_rate": 4.2680649754432913e-05, + "loss": 0.0027773819863796236, + "step": 860 + }, + { + "epoch": 2.8041483845233346, + "grad_norm": 0.019134322181344032, + "learning_rate": 4.070994013936646e-05, + "loss": 0.0018997505307197572, + "step": 880 + }, + { + "epoch": 2.8679696848823295, + "grad_norm": 0.2537505030632019, + "learning_rate": 3.8754187787161155e-05, + "loss": 0.0010082274675369263, + "step": 900 + }, + { + "epoch": 2.9317909852413244, + "grad_norm": 0.0017131563508883119, + "learning_rate": 3.681652465868875e-05, + "loss": 0.0012075364589691161, + "step": 920 + }, + { + "epoch": 2.995612285600319, + "grad_norm": 0.03925931081175804, + "learning_rate": 3.490005374656184e-05, + "loss": 0.000642749946564436, + "step": 940 + }, + { + "epoch": 3.0, + "eval_generator_count": 1712.0, + "eval_generator_exact_match": 95.3855, + "eval_generator_rouge1": 99.8982, + "eval_generator_rouge2": 99.8084, + "eval_generator_rougeL": 99.6633, + "eval_loss": 0.0056763943284749985, + "eval_runtime": 590.3317, + "eval_samples_per_second": 5.783, + "eval_selector_accuracy": 96.5537, + "eval_selector_count": 1712.0, + "eval_steps_per_second": 0.181, + "step": 942 + }, + { + "epoch": 3.057439170323095, + "grad_norm": 0.0036900911945849657, + "learning_rate": 3.3007844105971336e-05, + "loss": 0.0012762822210788728, + "step": 960 + }, + { + "epoch": 3.12126047068209, + "grad_norm": 0.028549807146191597, + "learning_rate": 3.114292593987149e-05, + "loss": 0.0006767791230231524, + "step": 980 + }, + { + "epoch": 3.185081771041085, + "grad_norm": 0.007299487479031086, + "learning_rate": 2.9308285746383408e-05, + "loss": 0.0012082518078386784, + "step": 1000 + }, + { + "epoch": 3.24890307140008, + "grad_norm": 0.03702578693628311, + "learning_rate": 2.7506861536187867e-05, + "loss": 0.0014168912544846534, + "step": 1020 + }, + { + "epoch": 3.3127243717590744, + "grad_norm": 0.21273940801620483, + "learning_rate": 2.5741538127566396e-05, + "loss": 0.0012415657751262189, + "step": 1040 + }, + { + "epoch": 3.3765456721180693, + "grad_norm": 0.0033840558025985956, + "learning_rate": 2.4015142526625115e-05, + "loss": 0.0009985800832509994, + "step": 1060 + }, + { + "epoch": 3.4403669724770642, + "grad_norm": 0.020664699375629425, + "learning_rate": 2.233043940009967e-05, + "loss": 0.0011398554779589176, + "step": 1080 + }, + { + "epoch": 3.504188272836059, + "grad_norm": 0.0015457016415894032, + "learning_rate": 2.0690126647990974e-05, + "loss": 0.0016313906759023666, + "step": 1100 + }, + { + "epoch": 3.568009573195054, + "grad_norm": 0.011757194995880127, + "learning_rate": 1.9096831083121828e-05, + "loss": 0.0010684640146791935, + "step": 1120 + }, + { + "epoch": 3.6318308735540485, + "grad_norm": 0.007703748065978289, + "learning_rate": 1.7553104224533324e-05, + "loss": 0.0006688186898827553, + "step": 1140 + }, + { + "epoch": 3.6956521739130435, + "grad_norm": 0.04895896837115288, + "learning_rate": 1.606141821145735e-05, + "loss": 0.0016563836485147475, + "step": 1160 + }, + { + "epoch": 3.7594734742720384, + "grad_norm": 0.04278242960572243, + "learning_rate": 1.4624161844408763e-05, + "loss": 0.0006196124479174614, + "step": 1180 + }, + { + "epoch": 3.823294774631033, + "grad_norm": 0.004100222606211901, + "learning_rate": 1.324363675973698e-05, + "loss": 0.0009099396876990796, + "step": 1200 + }, + { + "epoch": 3.8871160749900278, + "grad_norm": 0.06636715680360794, + "learning_rate": 1.1922053743763052e-05, + "loss": 0.0012004765681922435, + "step": 1220 + }, + { + "epoch": 3.9509373753490227, + "grad_norm": 0.005992025602608919, + "learning_rate": 1.0661529192404973e-05, + "loss": 0.0003460923908278346, + "step": 1240 + }, + { + "epoch": 4.0, + "eval_generator_count": 1712.0, + "eval_generator_exact_match": 95.8528, + "eval_generator_rouge1": 99.9186, + "eval_generator_rouge2": 99.8428, + "eval_generator_rougeL": 99.7108, + "eval_loss": 0.004311855416744947, + "eval_runtime": 587.5171, + "eval_samples_per_second": 5.811, + "eval_selector_accuracy": 98.1893, + "eval_selector_count": 1712.0, + "eval_steps_per_second": 0.182, + "step": 1256 + } + ], + "logging_steps": 20, + "max_steps": 1570, + "num_input_tokens_seen": 0, + "num_train_epochs": 5, + "save_steps": 500, + "stateful_callbacks": { + "TrainerControl": { + "args": { + "should_epoch_stop": false, + "should_evaluate": false, + "should_log": false, + "should_save": true, + "should_training_stop": false + }, + "attributes": {} + } + }, + "total_flos": 4.697643190059008e+16, + "train_batch_size": 2, + "trial_name": null, + "trial_params": null +} diff --git a/qwen3/amid/checkpoint-1256/training_args.bin b/qwen3/amid/checkpoint-1256/training_args.bin new file mode 100644 index 0000000000000000000000000000000000000000..571568fd8ab61d629f2a731739ee4c9e1309cca4 --- /dev/null +++ b/qwen3/amid/checkpoint-1256/training_args.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e67133ff7a80f6f166c03bd5f62d9c580548b0f6840a1ce3891dee623991e47a +size 7185 diff --git a/qwen3/amid/checkpoint-1256/zero_to_fp32.py b/qwen3/amid/checkpoint-1256/zero_to_fp32.py new file mode 100644 index 0000000000000000000000000000000000000000..f40f1f0acbbff30e8e8d29906b56aae4e8b8a138 --- /dev/null +++ b/qwen3/amid/checkpoint-1256/zero_to_fp32.py @@ -0,0 +1,790 @@ +#!/usr/bin/env python + +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: Apache-2.0 + +# DeepSpeed Team + +# This script extracts fp32 consolidated weights from a zero 1, 2 and 3 DeepSpeed checkpoints. It gets +# copied into the top level checkpoint dir, so the user can easily do the conversion at any point in +# the future. Once extracted, the weights don't require DeepSpeed and can be used in any +# application. +# +# example: +# python zero_to_fp32.py . output_dir/ +# or +# python zero_to_fp32.py . output_dir/ --safe_serialization + +import argparse +import torch +import glob +import math +import os +import re +import gc +import json +import numpy as np +from tqdm import tqdm +from collections import OrderedDict +from dataclasses import dataclass + +# while this script doesn't use deepspeed to recover data, since the checkpoints are pickled with +# DeepSpeed data structures it has to be available in the current python environment. +from deepspeed.utils import logger +from deepspeed.checkpoint.constants import (DS_VERSION, OPTIMIZER_STATE_DICT, SINGLE_PARTITION_OF_FP32_GROUPS, + FP32_FLAT_GROUPS, ZERO_STAGE, PARTITION_COUNT, PARAM_SHAPES, BUFFER_NAMES, + FROZEN_PARAM_SHAPES, FROZEN_PARAM_FRAGMENTS, AUTOEP_LAYERS_KEY, + AUTOEP_LAYERS_KEY_LEGACY, AUTOEP_ZERO3_EXPERT_STATE_FORMAT_KEY, + AUTOEP_ZERO3_PARTITIONED_EXPERT_STATE_FORMAT) + + +@dataclass +class zero_model_state: + buffers: dict() + param_shapes: dict() + shared_params: list + ds_version: int + frozen_param_shapes: dict() + frozen_param_fragments: dict() + + +debug = 0 + +# load to cpu +device = torch.device('cpu') + + +def atoi(text): + return int(text) if text.isdigit() else text + + +def natural_keys(text): + ''' + alist.sort(key=natural_keys) sorts in human order + http://nedbatchelder.com/blog/200712/human_sorting.html + (See Toothy's implementation in the comments) + ''' + return [atoi(c) for c in re.split(r'(\d+)', text)] + + +def get_model_state_file(checkpoint_dir, zero_stage): + if not os.path.isdir(checkpoint_dir): + raise FileNotFoundError(f"Directory '{checkpoint_dir}' doesn't exist") + + # there should be only one file + if zero_stage <= 2: + file = os.path.join(checkpoint_dir, "mp_rank_00_model_states.pt") + elif zero_stage == 3: + file = os.path.join(checkpoint_dir, "zero_pp_rank_0_mp_rank_00_model_states.pt") + + if not os.path.exists(file): + raise FileNotFoundError(f"can't find model states file at '{file}'") + + return file + + +def get_checkpoint_files(checkpoint_dir, glob_pattern): + # XXX: need to test that this simple glob rule works for multi-node setup too + ckpt_files = sorted(glob.glob(os.path.join(checkpoint_dir, glob_pattern)), key=natural_keys) + + if len(ckpt_files) == 0: + raise FileNotFoundError(f"can't find {glob_pattern} files in directory '{checkpoint_dir}'") + + return ckpt_files + + +def get_optim_files(checkpoint_dir): + return get_checkpoint_files(checkpoint_dir, "*_optim_states.pt") + + +def get_model_state_files(checkpoint_dir): + return get_checkpoint_files(checkpoint_dir, "*_model_states.pt") + + +def _has_autoep_zero3_partitioned_metadata(state_dict): + autoep_layers = state_dict.get(AUTOEP_LAYERS_KEY) + if autoep_layers is None: + autoep_layers = state_dict.get(AUTOEP_LAYERS_KEY_LEGACY) + if not isinstance(autoep_layers, list): + return False + return any( + isinstance(entry, dict) + and entry.get(AUTOEP_ZERO3_EXPERT_STATE_FORMAT_KEY) == AUTOEP_ZERO3_PARTITIONED_EXPERT_STATE_FORMAT + for entry in autoep_layers) + + +def _raise_if_autoep_zero3_partitioned_state(state_dict): + if _has_autoep_zero3_partitioned_metadata(state_dict): + raise NotImplementedError("zero_to_fp32 does not support AutoEP ZeRO-3 partition-native checkpoints. " + "AutoEP expert parameters are partitioned over expert replica groups, so " + "global data-parallel consolidation would produce incomplete expert tensors. " + "Use ds_to_universal.py for expert-aware conversion.") + + +def _raise_if_autoep_zero3_partitioned_checkpoint(model_files): + for file in model_files: + state_dict = torch.load(file, map_location=device, weights_only=False) + _raise_if_autoep_zero3_partitioned_state(state_dict) + + +def parse_model_states(files): + zero_model_states = [] + for file in files: + state_dict = torch.load(file, map_location=device, weights_only=False) + _raise_if_autoep_zero3_partitioned_state(state_dict) + + if BUFFER_NAMES not in state_dict: + raise ValueError(f"{file} is not a model state checkpoint") + buffer_names = state_dict[BUFFER_NAMES] + if debug: + print("Found buffers:", buffer_names) + + # recover just the buffers while restoring them to fp32 if they were saved in fp16 + buffers = {k: v.float() for k, v in state_dict["module"].items() if k in buffer_names} + param_shapes = state_dict[PARAM_SHAPES] + + # collect parameters that are included in param_shapes + param_names = [] + for s in param_shapes: + for name in s.keys(): + param_names.append(name) + + # update with frozen parameters + frozen_param_shapes = state_dict.get(FROZEN_PARAM_SHAPES, None) + if frozen_param_shapes is not None: + if debug: + print(f"Found frozen_param_shapes: {frozen_param_shapes}") + param_names += list(frozen_param_shapes.keys()) + + # handle shared params + shared_params = [[k, v] for k, v in state_dict["shared_params"].items()] + + ds_version = state_dict.get(DS_VERSION, None) + + frozen_param_fragments = state_dict.get(FROZEN_PARAM_FRAGMENTS, None) + + z_model_state = zero_model_state(buffers=buffers, + param_shapes=param_shapes, + shared_params=shared_params, + ds_version=ds_version, + frozen_param_shapes=frozen_param_shapes, + frozen_param_fragments=frozen_param_fragments) + zero_model_states.append(z_model_state) + + return zero_model_states + + +def parse_optim_states(files, ds_checkpoint_dir): + total_files = len(files) + state_dicts = [] + for f in tqdm(files, desc='Loading checkpoint shards'): + state_dict = torch.load(f, map_location=device, mmap=True, weights_only=False) + # immediately discard the potentially huge 2 optimizer states as we only care for fp32 master weights + # and also handle the case where it was already removed by another helper script + state_dict["optimizer_state_dict"].pop("optimizer_state_dict", None) + state_dicts.append(state_dict) + + if ZERO_STAGE not in state_dicts[0][OPTIMIZER_STATE_DICT]: + raise ValueError(f"{files[0]} is not a zero checkpoint") + zero_stage = state_dicts[0][OPTIMIZER_STATE_DICT][ZERO_STAGE] + world_size = state_dicts[0][OPTIMIZER_STATE_DICT][PARTITION_COUNT] + + # For ZeRO-2 each param group can have different partition_count as data parallelism for expert + # parameters can be different from data parallelism for non-expert parameters. So we can just + # use the max of the partition_count to get the dp world_size. + + if type(world_size) is list: + world_size = max(world_size) + + if world_size != total_files: + raise ValueError( + f"Expected {world_size} of '*_optim_states.pt' under '{ds_checkpoint_dir}' but found {total_files} files. " + "Possibly due to an overwrite of an old checkpoint, or a checkpoint didn't get saved by one or more processes." + ) + + # the groups are named differently in each stage + if zero_stage <= 2: + fp32_groups_key = SINGLE_PARTITION_OF_FP32_GROUPS + elif zero_stage == 3: + fp32_groups_key = FP32_FLAT_GROUPS + else: + raise ValueError(f"unknown zero stage {zero_stage}") + + fp32_flat_groups = [state_dicts[i][OPTIMIZER_STATE_DICT][fp32_groups_key] for i in range(len(state_dicts))] + return zero_stage, world_size, fp32_flat_groups + + +def _get_fp32_state_dict_from_zero_checkpoint(ds_checkpoint_dir, exclude_frozen_parameters): + """ + Returns fp32 state_dict reconstructed from ds checkpoint + + Args: + - ``ds_checkpoint_dir``: path to the deepspeed checkpoint folder (where the optimizer files are) + + """ + print(f"Processing zero checkpoint '{ds_checkpoint_dir}'") + + # parse_model_states rejects AutoEP ZeRO-3 partition-native checkpoints + # before the expensive optimizer-shard load below. + model_files = get_model_state_files(ds_checkpoint_dir) + zero_model_states = parse_model_states(model_files) + print(f'Parsing checkpoint created by deepspeed=={zero_model_states[0].ds_version}') + + optim_files = get_optim_files(ds_checkpoint_dir) + zero_stage, world_size, fp32_flat_groups = parse_optim_states(optim_files, ds_checkpoint_dir) + print(f"Detected checkpoint of type zero stage {zero_stage}, world_size: {world_size}") + + if zero_stage <= 2: + return _get_fp32_state_dict_from_zero2_checkpoint(world_size, fp32_flat_groups, zero_model_states, + exclude_frozen_parameters) + elif zero_stage == 3: + return _get_fp32_state_dict_from_zero3_checkpoint(world_size, fp32_flat_groups, zero_model_states, + exclude_frozen_parameters) + + +def _zero2_merge_frozen_params(state_dict, zero_model_states): + if zero_model_states[0].frozen_param_shapes is None or len(zero_model_states[0].frozen_param_shapes) == 0: + return + + frozen_param_shapes = zero_model_states[0].frozen_param_shapes + frozen_param_fragments = zero_model_states[0].frozen_param_fragments + + if debug: + num_elem = sum(s.numel() for s in frozen_param_shapes.values()) + print(f'rank 0: {FROZEN_PARAM_SHAPES}.numel = {num_elem}') + + wanted_params = len(frozen_param_shapes) + wanted_numel = sum(s.numel() for s in frozen_param_shapes.values()) + avail_numel = sum([p.numel() for p in frozen_param_fragments.values()]) + print(f'Frozen params: Have {avail_numel} numels to process.') + print(f'Frozen params: Need {wanted_numel} numels in {wanted_params} params') + + total_params = 0 + total_numel = 0 + for name, shape in frozen_param_shapes.items(): + total_params += 1 + unpartitioned_numel = shape.numel() + total_numel += unpartitioned_numel + + state_dict[name] = frozen_param_fragments[name] + + if debug: + print(f"{name} full shape: {shape} unpartitioned numel {unpartitioned_numel} ") + + print(f"Reconstructed Frozen fp32 state dict with {total_params} params {total_numel} elements") + + +def _has_callable(obj, fn): + attr = getattr(obj, fn, None) + return callable(attr) + + +def _zero2_merge_trainable_params(state_dict, world_size, fp32_flat_groups, zero_model_states): + param_shapes = zero_model_states[0].param_shapes + + # Reconstruction protocol: + # + # XXX: document this + + if debug: + for i in range(world_size): + for j in range(len(fp32_flat_groups[0])): + print(f"{FP32_FLAT_GROUPS}[{i}][{j}].shape={fp32_flat_groups[i][j].shape}") + + # XXX: memory usage doubles here (zero2) + num_param_groups = len(fp32_flat_groups[0]) + merged_single_partition_of_fp32_groups = [] + for i in range(num_param_groups): + merged_partitions = [sd[i] for sd in fp32_flat_groups] + full_single_fp32_vector = torch.cat(merged_partitions, 0) + merged_single_partition_of_fp32_groups.append(full_single_fp32_vector) + avail_numel = sum( + [full_single_fp32_vector.numel() for full_single_fp32_vector in merged_single_partition_of_fp32_groups]) + + if debug: + wanted_params = sum([len(shapes) for shapes in param_shapes]) + wanted_numel = sum([sum(shape.numel() for shape in shapes.values()) for shapes in param_shapes]) + # not asserting if there is a mismatch due to possible padding + print(f"Have {avail_numel} numels to process.") + print(f"Need {wanted_numel} numels in {wanted_params} params.") + + # params + # XXX: for huge models that can't fit into the host's RAM we will have to recode this to support + # out-of-core computing solution + total_numel = 0 + total_params = 0 + for shapes, full_single_fp32_vector in zip(param_shapes, merged_single_partition_of_fp32_groups): + offset = 0 + avail_numel = full_single_fp32_vector.numel() + for name, shape in shapes.items(): + + unpartitioned_numel = shape.numel() if _has_callable(shape, 'numel') else math.prod(shape) + total_numel += unpartitioned_numel + total_params += 1 + + if debug: + print(f"{name} full shape: {shape} unpartitioned numel {unpartitioned_numel} ") + state_dict[name] = full_single_fp32_vector.narrow(0, offset, unpartitioned_numel).view(shape) + offset += unpartitioned_numel + + # Z2 started to align to 2*world_size to improve nccl performance. Therefore both offset and + # avail_numel can differ by anywhere between 0..2*world_size. Due to two unrelated complex + # paddings performed in the code it's almost impossible to predict the exact numbers w/o the + # live optimizer object, so we are checking that the numbers are within the right range + align_to = 2 * world_size + + def zero2_align(x): + return align_to * math.ceil(x / align_to) + + if debug: + print(f"original offset={offset}, avail_numel={avail_numel}") + + offset = zero2_align(offset) + avail_numel = zero2_align(avail_numel) + + if debug: + print(f"aligned offset={offset}, avail_numel={avail_numel}") + + # Sanity check + if offset != avail_numel: + raise ValueError(f"consumed {offset} numels out of {avail_numel} - something is wrong") + + print(f"Reconstructed fp32 state dict with {total_params} params {total_numel} elements") + + +def _get_fp32_state_dict_from_zero2_checkpoint(world_size, fp32_flat_groups, zero_model_states, + exclude_frozen_parameters): + state_dict = OrderedDict() + + # buffers + buffers = zero_model_states[0].buffers + state_dict.update(buffers) + if debug: + print(f"added {len(buffers)} buffers") + + if not exclude_frozen_parameters: + _zero2_merge_frozen_params(state_dict, zero_model_states) + + _zero2_merge_trainable_params(state_dict, world_size, fp32_flat_groups, zero_model_states) + + # recover shared parameters + for pair in zero_model_states[0].shared_params: + if pair[1] in state_dict: + state_dict[pair[0]] = state_dict[pair[1]] + + return state_dict + + +def zero3_partitioned_param_info(unpartitioned_numel, world_size): + remainder = unpartitioned_numel % world_size + padding_numel = (world_size - remainder) if remainder else 0 + partitioned_numel = math.ceil(unpartitioned_numel / world_size) + return partitioned_numel, padding_numel + + +def _zero3_merge_frozen_params(state_dict, world_size, zero_model_states): + if zero_model_states[0].frozen_param_shapes is None or len(zero_model_states[0].frozen_param_shapes) == 0: + return + + if debug: + for i in range(world_size): + num_elem = sum(s.numel() for s in zero_model_states[i].frozen_param_fragments.values()) + print(f'rank {i}: {FROZEN_PARAM_SHAPES}.numel = {num_elem}') + + frozen_param_shapes = zero_model_states[0].frozen_param_shapes + wanted_params = len(frozen_param_shapes) + wanted_numel = sum(s.numel() for s in frozen_param_shapes.values()) + avail_numel = sum([p.numel() for p in zero_model_states[0].frozen_param_fragments.values()]) * world_size + print(f'Frozen params: Have {avail_numel} numels to process.') + print(f'Frozen params: Need {wanted_numel} numels in {wanted_params} params') + + total_params = 0 + total_numel = 0 + for name, shape in zero_model_states[0].frozen_param_shapes.items(): + total_params += 1 + unpartitioned_numel = shape.numel() + total_numel += unpartitioned_numel + + param_frags = tuple(model_state.frozen_param_fragments[name] for model_state in zero_model_states) + state_dict[name] = torch.cat(param_frags, 0).narrow(0, 0, unpartitioned_numel).view(shape) + + partitioned_numel, partitioned_padding_numel = zero3_partitioned_param_info(unpartitioned_numel, world_size) + + if debug: + print( + f"Frozen params: {total_params} {name} full shape: {shape} partition0 numel={partitioned_numel} partitioned_padding_numel={partitioned_padding_numel}" + ) + + print(f"Reconstructed Frozen fp32 state dict with {total_params} params {total_numel} elements") + + +class GatheredTensor: + """ + A pseudo tensor that collects partitioned weights. + It is more memory efficient when there are multiple groups. + """ + + def __init__(self, flat_groups, flat_groups_offset, offset, partitioned_numel, shape): + self.flat_groups = flat_groups + self.flat_groups_offset = flat_groups_offset + self.offset = offset + self.partitioned_numel = partitioned_numel + self.shape = shape + self.dtype = self.flat_groups[0][0].dtype + + def contiguous(self): + """ + Merge partitioned weights from flat_groups into a single tensor. + """ + end_idx = self.offset + self.partitioned_numel + world_size = len(self.flat_groups) + pad_flat_param_chunks = [] + + for rank_i in range(world_size): + # for each rank, we need to collect weights from related group/groups + flat_groups_at_rank_i = self.flat_groups[rank_i] + start_group_id = None + end_group_id = None + for group_id in range(len(self.flat_groups_offset)): + if self.flat_groups_offset[group_id] <= self.offset < self.flat_groups_offset[group_id + 1]: + start_group_id = group_id + if self.flat_groups_offset[group_id] < end_idx <= self.flat_groups_offset[group_id + 1]: + end_group_id = group_id + break + # collect weights from related group/groups + for group_id in range(start_group_id, end_group_id + 1): + flat_tensor = flat_groups_at_rank_i[group_id] + start_offset = self.offset - self.flat_groups_offset[group_id] + end_offset = min(end_idx, self.flat_groups_offset[group_id + 1]) - self.flat_groups_offset[group_id] + pad_flat_param_chunks.append(flat_tensor[start_offset:end_offset]) + + # collect weights from all ranks + pad_flat_param = torch.cat(pad_flat_param_chunks, dim=0) + param = pad_flat_param[:self.shape.numel()].view(self.shape).contiguous() + return param + + +def _zero3_merge_trainable_params(state_dict, world_size, fp32_flat_groups, zero_model_states): + param_shapes = zero_model_states[0].param_shapes + avail_numel = sum([flat_group.numel() for flat_group in fp32_flat_groups[0]]) * world_size + + # Reconstruction protocol: For zero3 we need to zip the partitions together at boundary of each + # param, re-consolidating each param, while dealing with padding if any + + # merge list of dicts, preserving order + param_shapes = {k: v for d in param_shapes for k, v in d.items()} + + if debug: + for i in range(world_size): + print(f"{FP32_FLAT_GROUPS}[{i}].shape={fp32_flat_groups[i].shape}") + + wanted_params = len(param_shapes) + wanted_numel = sum(shape.numel() for shape in param_shapes.values()) + # not asserting if there is a mismatch due to possible padding + avail_numel = fp32_flat_groups[0].numel() * world_size + print(f"Trainable params: Have {avail_numel} numels to process.") + print(f"Trainable params: Need {wanted_numel} numels in {wanted_params} params.") + + # params + # XXX: for huge models that can't fit into the host's RAM we will have to recode this to support + # out-of-core computing solution + offset = 0 + total_numel = 0 + total_params = 0 + flat_groups_offset = [0] + list(np.cumsum([flat_tensor.numel() for flat_tensor in fp32_flat_groups[0]])) + for name, shape in tqdm(param_shapes.items(), desc='Gathering sharded weights'): + unpartitioned_numel = shape.numel() + total_numel += unpartitioned_numel + total_params += 1 + partitioned_numel, partitioned_padding_numel = zero3_partitioned_param_info(unpartitioned_numel, world_size) + + if debug: + print( + f"Trainable params: {total_params} {name} full shape: {shape} partition0 numel={partitioned_numel} partitioned_padding_numel={partitioned_padding_numel}" + ) + + # memory efficient tensor + tensor = GatheredTensor(fp32_flat_groups, flat_groups_offset, offset, partitioned_numel, shape) + state_dict[name] = tensor + offset += partitioned_numel + + offset *= world_size + + # Sanity check + if offset != avail_numel: + raise ValueError(f"consumed {offset} numels out of {avail_numel} - something is wrong") + + print(f"Reconstructed Trainable fp32 state dict with {total_params} params {total_numel} elements") + + +def _get_fp32_state_dict_from_zero3_checkpoint(world_size, fp32_flat_groups, zero_model_states, + exclude_frozen_parameters): + state_dict = OrderedDict() + + # buffers + buffers = zero_model_states[0].buffers + state_dict.update(buffers) + if debug: + print(f"added {len(buffers)} buffers") + + if not exclude_frozen_parameters: + _zero3_merge_frozen_params(state_dict, world_size, zero_model_states) + + _zero3_merge_trainable_params(state_dict, world_size, fp32_flat_groups, zero_model_states) + + # recover shared parameters + for pair in zero_model_states[0].shared_params: + if pair[1] in state_dict: + state_dict[pair[0]] = state_dict[pair[1]] + + return state_dict + + +def to_torch_tensor(state_dict, return_empty_tensor=False): + """ + Convert state_dict of GatheredTensor to torch tensor + """ + torch_state_dict = {} + converted_tensors = {} + for name, tensor in state_dict.items(): + tensor_id = id(tensor) + if tensor_id in converted_tensors: # shared tensors + shared_tensor = torch_state_dict[converted_tensors[tensor_id]] + torch_state_dict[name] = shared_tensor + else: + converted_tensors[tensor_id] = name + if return_empty_tensor: + torch_state_dict[name] = torch.empty(tensor.shape, dtype=tensor.dtype) + else: + torch_state_dict[name] = tensor.contiguous() + return torch_state_dict + + +def get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir, + tag=None, + exclude_frozen_parameters=False, + lazy_mode=False): + """ + Convert ZeRO 2 or 3 checkpoint into a single fp32 consolidated state_dict that can be loaded with + ``load_state_dict()`` and used for training without DeepSpeed or shared with others, for example + via a model hub. + + Args: + - ``checkpoint_dir``: path to the desired checkpoint folder + - ``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`` + - ``exclude_frozen_parameters``: exclude frozen parameters + - ``lazy_mode``: get state_dict in lazy mode. It returns a dict of pesduo tensor instead of torch tensor, which is more memory efficient. + Convert the pesduo tensor to torch tensor by ``.contiguous()`` + + Returns: + - pytorch ``state_dict`` + + A typical usage might be :: + + from deepspeed.utils.zero_to_fp32 import get_fp32_state_dict_from_zero_checkpoint + # do the training and checkpoint saving + state_dict = get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir) # already on cpu + model = model.cpu() # move to cpu + model.load_state_dict(state_dict) + # submit to model hub or save the model to share with others + + In this example the ``model`` will no longer be usable in the deepspeed context of the same + application. i.e. you will need to re-initialize the deepspeed engine, since + ``model.load_state_dict(state_dict)`` will remove all the deepspeed magic from it. + + If you want it all done for you, use ``load_state_dict_from_zero_checkpoint`` instead. + + Note: the above usage may not work if your application doesn't have sufficient free CPU memory. + You may need to use the offline approach using the ``zero_to_fp32.py`` script that is saved with + the checkpoint. Or you can load state_dict in lazy mode :: + + from deepspeed.utils.zero_to_fp32 import get_fp32_state_dict_from_zero_checkpoint + state_dict = get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir, lazy_mode=True) # not on cpu + for name, lazy_tensor in state_dict.item(): + tensor = lazy_tensor.contiguous() # to cpu + print(name, tensor) + # del tensor to release memory if it no longer in use + """ + if tag is None: + latest_path = os.path.join(checkpoint_dir, 'latest') + if os.path.isfile(latest_path): + with open(latest_path, 'r') as fd: + tag = fd.read().strip() + else: + raise ValueError(f"Unable to find 'latest' file at {latest_path}") + + ds_checkpoint_dir = os.path.join(checkpoint_dir, tag) + + if not os.path.isdir(ds_checkpoint_dir): + raise FileNotFoundError(f"Directory '{ds_checkpoint_dir}' doesn't exist") + + state_dict = _get_fp32_state_dict_from_zero_checkpoint(ds_checkpoint_dir, exclude_frozen_parameters) + if lazy_mode: + return state_dict + else: + return to_torch_tensor(state_dict) + + +def convert_zero_checkpoint_to_fp32_state_dict(checkpoint_dir, + output_dir, + max_shard_size="5GB", + safe_serialization=False, + tag=None, + exclude_frozen_parameters=False): + """ + Convert ZeRO 2 or 3 checkpoint into a single fp32 consolidated ``state_dict`` file that can be + loaded with ``torch.load(file)`` + ``load_state_dict()`` and used for training without DeepSpeed. + + Args: + - ``checkpoint_dir``: path to the desired checkpoint folder. (one that contains the tag-folder, like ``global_step14``) + - ``output_dir``: directory to the pytorch fp32 state_dict output files + - ``max_shard_size``: the maximum size for a checkpoint before being sharded, default value is 5GB + - ``safe_serialization``: whether to save the model using `safetensors` or the traditional PyTorch way (that uses `pickle`). + - ``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`` + - ``exclude_frozen_parameters``: exclude frozen parameters + """ + + # Dependency pre-check + if safe_serialization: + try: + from safetensors.torch import save_file + except ImportError: + print('If you want to use `safe_serialization`, please `pip install safetensors`') + raise + if max_shard_size is not None: + try: + from huggingface_hub import split_torch_state_dict_into_shards + except ImportError: + print('If you want to use `max_shard_size`, please `pip install huggingface_hub`') + raise + + # Convert zero checkpoint to state_dict + state_dict = get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir, + tag, + exclude_frozen_parameters, + lazy_mode=True) + + # Shard the model if it is too big. + weights_name = "model.safetensors" if safe_serialization else "pytorch_model.bin" + if max_shard_size is not None: + filename_pattern = weights_name.replace(".bin", "{suffix}.bin").replace(".safetensors", "{suffix}.safetensors") + # an memory-efficient approach for sharding + empty_state_dict = to_torch_tensor(state_dict, return_empty_tensor=True) + state_dict_split = split_torch_state_dict_into_shards(empty_state_dict, + filename_pattern=filename_pattern, + max_shard_size=max_shard_size) + else: + from collections import namedtuple + StateDictSplit = namedtuple("StateDictSplit", ["is_sharded", "filename_to_tensors"]) + state_dict_split = StateDictSplit(is_sharded=False, + filename_to_tensors={weights_name: list(state_dict.keys())}) + + # Save the model by shard + os.makedirs(output_dir, exist_ok=True) + filename_to_tensors = state_dict_split.filename_to_tensors.items() + for shard_file, tensors in tqdm(filename_to_tensors, desc="Saving checkpoint shards"): + shard_state_dict = {tensor_name: state_dict[tensor_name] for tensor_name in tensors} + shard_state_dict = to_torch_tensor(shard_state_dict) + output_path = os.path.join(output_dir, shard_file) + if safe_serialization: + save_file(shard_state_dict, output_path, metadata={"format": "pt"}) + else: + torch.save(shard_state_dict, output_path) + # release the memory of current shard + for tensor_name in list(shard_state_dict.keys()): + del state_dict[tensor_name] + del shard_state_dict[tensor_name] + del shard_state_dict + gc.collect() + + # Save index if sharded + if state_dict_split.is_sharded: + index = { + "metadata": state_dict_split.metadata, + "weight_map": state_dict_split.tensor_to_filename, + } + save_index_file = "model.safetensors.index.json" if safe_serialization else "pytorch_model.bin.index.json" + save_index_file = os.path.join(output_dir, save_index_file) + with open(save_index_file, "w", encoding="utf-8") as f: + content = json.dumps(index, indent=2, sort_keys=True) + "\n" + f.write(content) + + +def load_state_dict_from_zero_checkpoint(model, checkpoint_dir, tag=None): + """ + 1. Put the provided model to cpu + 2. Convert ZeRO 2 or 3 checkpoint into a single fp32 consolidated ``state_dict`` + 3. Load it into the provided model + + Args: + - ``model``: the model object to update + - ``checkpoint_dir``: path to the desired checkpoint folder. (one that contains the tag-folder, like ``global_step14``) + - ``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`` + + Returns: + - ``model`: modified model + + Make sure you have plenty of CPU memory available before you call this function. If you don't + have enough use the ``zero_to_fp32.py`` utility to do the conversion. You will find it + conveniently placed for you in the checkpoint folder. + + A typical usage might be :: + + from deepspeed.utils.zero_to_fp32 import load_state_dict_from_zero_checkpoint + model = load_state_dict_from_zero_checkpoint(trainer.model, checkpoint_dir) + # submit to model hub or save the model to share with others + + Note, that once this was run, the ``model`` will no longer be usable in the deepspeed context + of the same application. i.e. you will need to re-initialize the deepspeed engine, since + ``model.load_state_dict(state_dict)`` will remove all the deepspeed magic from it. + + """ + logger.info("Extracting fp32 weights") + state_dict = get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir, tag) + + logger.info("Overwriting model with fp32 weights") + model = model.cpu() + model.load_state_dict(state_dict, strict=False) + + return model + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument("checkpoint_dir", + type=str, + help="path to the desired checkpoint folder, e.g., path/checkpoint-12") + parser.add_argument("output_dir", + type=str, + help="directory to the pytorch fp32 state_dict output files" + "(e.g. path/checkpoint-12-output/)") + parser.add_argument( + "--max_shard_size", + type=str, + default="5GB", + help="The maximum size for a checkpoint before being sharded. Checkpoints shard will then be each of size" + "lower than this size. If expressed as a string, needs to be digits followed by a unit (like `5MB`" + "We default it to 5GB in order for models to be able to run easily on free-tier google colab instances" + "without CPU OOM issues.") + parser.add_argument( + "--safe_serialization", + default=False, + action='store_true', + help="Whether to save the model using `safetensors` or the traditional PyTorch way (that uses `pickle`).") + parser.add_argument("-t", + "--tag", + type=str, + default=None, + help="checkpoint tag used as a unique identifier for checkpoint. e.g., global_step1") + parser.add_argument("--exclude_frozen_parameters", action='store_true', help="exclude frozen parameters") + parser.add_argument("-d", "--debug", action='store_true', help="enable debug") + args = parser.parse_args() + + debug = args.debug + + convert_zero_checkpoint_to_fp32_state_dict(args.checkpoint_dir, + args.output_dir, + max_shard_size=args.max_shard_size, + safe_serialization=args.safe_serialization, + tag=args.tag, + exclude_frozen_parameters=args.exclude_frozen_parameters) diff --git a/qwen3/amid/checkpoint-1570/README.md b/qwen3/amid/checkpoint-1570/README.md new file mode 100644 index 0000000000000000000000000000000000000000..776f98d43659dd923b8c3e5649c5ae66d1f99f3e --- /dev/null +++ b/qwen3/amid/checkpoint-1570/README.md @@ -0,0 +1,208 @@ +--- +base_model: Qwen/Qwen3-0.6B +library_name: peft +pipeline_tag: text-generation +tags: +- base_model:adapter:Qwen/Qwen3-0.6B +- llama-factory +- lora +- transformers +--- + +# Model Card for Model ID + + + + + +## Model Details + +### Model Description + + + + + +- **Developed by:** [More Information Needed] +- **Funded by [optional]:** [More Information Needed] +- **Shared by [optional]:** [More Information Needed] +- **Model type:** [More Information Needed] +- **Language(s) (NLP):** [More Information Needed] +- **License:** [More Information Needed] +- **Finetuned from model [optional]:** [More Information Needed] + +### Model Sources [optional] + + + +- **Repository:** [More Information Needed] +- **Paper [optional]:** [More Information Needed] +- **Demo [optional]:** [More Information Needed] + +## Uses + + + +### Direct Use + + + +[More Information Needed] + +### Downstream Use [optional] + + + +[More Information Needed] + +### Out-of-Scope Use + + + +[More Information Needed] + +## Bias, Risks, and Limitations + + + +[More Information Needed] + +### Recommendations + + + +Users (both direct and downstream) should be made aware of the risks, biases and limitations of the model. More information needed for further recommendations. + +## How to Get Started with the Model + +Use the code below to get started with the model. + +[More Information Needed] + +## Training Details + +### Training Data + + + +[More Information Needed] + +### Training Procedure + + + +#### Preprocessing [optional] + +[More Information Needed] + + +#### Training Hyperparameters + +- **Training regime:** [More Information Needed] + +#### Speeds, Sizes, Times [optional] + + + +[More Information Needed] + +## Evaluation + + + +### Testing Data, Factors & Metrics + +#### Testing Data + + + +[More Information Needed] + +#### Factors + + + +[More Information Needed] + +#### Metrics + + + +[More Information Needed] + +### Results + +[More Information Needed] + +#### Summary + + + +## Model Examination [optional] + + + +[More Information Needed] + +## Environmental Impact + + + +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). + +- **Hardware Type:** [More Information Needed] +- **Hours used:** [More Information Needed] +- **Cloud Provider:** [More Information Needed] +- **Compute Region:** [More Information Needed] +- **Carbon Emitted:** [More Information Needed] + +## Technical Specifications [optional] + +### Model Architecture and Objective + +[More Information Needed] + +### Compute Infrastructure + +[More Information Needed] + +#### Hardware + +[More Information Needed] + +#### Software + +[More Information Needed] + +## Citation [optional] + + + +**BibTeX:** + +[More Information Needed] + +**APA:** + +[More Information Needed] + +## Glossary [optional] + + + +[More Information Needed] + +## More Information [optional] + +[More Information Needed] + +## Model Card Authors [optional] + +[More Information Needed] + +## Model Card Contact + +[More Information Needed] +### Framework versions + +- PEFT 0.18.1 \ No newline at end of file diff --git a/qwen3/amid/checkpoint-1570/adapter_config.json b/qwen3/amid/checkpoint-1570/adapter_config.json new file mode 100644 index 0000000000000000000000000000000000000000..16362f47190537658d6b04519de786417a5f6c2f --- /dev/null +++ b/qwen3/amid/checkpoint-1570/adapter_config.json @@ -0,0 +1,46 @@ +{ + "alora_invocation_tokens": null, + "alpha_pattern": {}, + "arrow_config": null, + "auto_mapping": null, + "base_model_name_or_path": "Qwen/Qwen3-0.6B", + "bias": "none", + "corda_config": null, + "ensure_weight_tying": false, + "eva_config": null, + "exclude_modules": null, + "fan_in_fan_out": false, + "inference_mode": true, + "init_lora_weights": true, + "layer_replication": null, + "layers_pattern": null, + "layers_to_transform": null, + "loftq_config": {}, + "lora_alpha": 64, + "lora_bias": false, + "lora_dropout": 0.1, + "megatron_config": null, + "megatron_core": "megatron.core", + "modules_to_save": null, + "peft_type": "LORA", + "peft_version": "0.18.1", + "qalora_group_size": 16, + "r": 32, + "rank_pattern": {}, + "revision": null, + "target_modules": [ + "v_proj", + "q_proj", + "o_proj", + "gate_proj", + "up_proj", + "k_proj", + "down_proj" + ], + "target_parameters": null, + "task_type": "CAUSAL_LM", + "trainable_token_indices": null, + "use_dora": false, + "use_qalora": false, + "use_rslora": false +} \ No newline at end of file diff --git a/qwen3/amid/checkpoint-1570/adapter_model.safetensors b/qwen3/amid/checkpoint-1570/adapter_model.safetensors new file mode 100644 index 0000000000000000000000000000000000000000..93524c4b229da26352140faae8b8d1bed15559bc --- /dev/null +++ b/qwen3/amid/checkpoint-1570/adapter_model.safetensors @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:db85fbee8a5b8671bb7eea278430126deabd15db5ca476d10a9fd242caf6c334 +size 40422560 diff --git a/qwen3/amid/checkpoint-1570/chat_template.jinja b/qwen3/amid/checkpoint-1570/chat_template.jinja new file mode 100644 index 0000000000000000000000000000000000000000..01be9b307daa2d425f7c168c9fb145a286e0afb4 --- /dev/null +++ b/qwen3/amid/checkpoint-1570/chat_template.jinja @@ -0,0 +1,89 @@ +{%- if tools %} + {{- '<|im_start|>system\n' }} + {%- if messages[0].role == 'system' %} + {{- messages[0].content + '\n\n' }} + {%- endif %} + {{- "# Tools\n\nYou may call one or more functions to assist with the user query.\n\nYou are provided with function signatures within XML tags:\n" }} + {%- for tool in tools %} + {{- "\n" }} + {{- tool | tojson }} + {%- endfor %} + {{- "\n\n\nFor each function call, return a json object with function name and arguments within XML tags:\n\n{\"name\": , \"arguments\": }\n<|im_end|>\n" }} +{%- else %} + {%- if messages[0].role == 'system' %} + {{- '<|im_start|>system\n' + messages[0].content + '<|im_end|>\n' }} + {%- endif %} +{%- endif %} +{%- set ns = namespace(multi_step_tool=true, last_query_index=messages|length - 1) %} +{%- for message in messages[::-1] %} + {%- set index = (messages|length - 1) - loop.index0 %} + {%- if ns.multi_step_tool and message.role == "user" and message.content is string and not(message.content.startswith('') and message.content.endswith('')) %} + {%- set ns.multi_step_tool = false %} + {%- set ns.last_query_index = index %} + {%- endif %} +{%- endfor %} +{%- for message in messages %} + {%- if message.content is string %} + {%- set content = message.content %} + {%- else %} + {%- set content = '' %} + {%- endif %} + {%- if (message.role == "user") or (message.role == "system" and not loop.first) %} + {{- '<|im_start|>' + message.role + '\n' + content + '<|im_end|>' + '\n' }} + {%- elif message.role == "assistant" %} + {%- set reasoning_content = '' %} + {%- if message.reasoning_content is string %} + {%- set reasoning_content = message.reasoning_content %} + {%- else %} + {%- if '' in content %} + {%- set reasoning_content = content.split('')[0].rstrip('\n').split('')[-1].lstrip('\n') %} + {%- set content = content.split('')[-1].lstrip('\n') %} + {%- endif %} + {%- endif %} + {%- if loop.index0 > ns.last_query_index %} + {%- if loop.last or (not loop.last and reasoning_content) %} + {{- '<|im_start|>' + message.role + '\n\n' + reasoning_content.strip('\n') + '\n\n\n' + content.lstrip('\n') }} + {%- else %} + {{- '<|im_start|>' + message.role + '\n' + content }} + {%- endif %} + {%- else %} + {{- '<|im_start|>' + message.role + '\n' + content }} + {%- endif %} + {%- if message.tool_calls %} + {%- for tool_call in message.tool_calls %} + {%- if (loop.first and content) or (not loop.first) %} + {{- '\n' }} + {%- endif %} + {%- if tool_call.function %} + {%- set tool_call = tool_call.function %} + {%- endif %} + {{- '\n{"name": "' }} + {{- tool_call.name }} + {{- '", "arguments": ' }} + {%- if tool_call.arguments is string %} + {{- tool_call.arguments }} + {%- else %} + {{- tool_call.arguments | tojson }} + {%- endif %} + {{- '}\n' }} + {%- endfor %} + {%- endif %} + {{- '<|im_end|>\n' }} + {%- elif message.role == "tool" %} + {%- if loop.first or (messages[loop.index0 - 1].role != "tool") %} + {{- '<|im_start|>user' }} + {%- endif %} + {{- '\n\n' }} + {{- content }} + {{- '\n' }} + {%- if loop.last or (messages[loop.index0 + 1].role != "tool") %} + {{- '<|im_end|>\n' }} + {%- endif %} + {%- endif %} +{%- endfor %} +{%- if add_generation_prompt %} + {{- '<|im_start|>assistant\n' }} + {%- if enable_thinking is defined and enable_thinking is false %} + {{- '\n\n\n\n' }} + {%- endif %} +{%- endif %} \ No newline at end of file diff --git a/qwen3/amid/checkpoint-1570/global_step1570/bf16_zero_pp_rank_0_mp_rank_00_optim_states.pt b/qwen3/amid/checkpoint-1570/global_step1570/bf16_zero_pp_rank_0_mp_rank_00_optim_states.pt new file mode 100644 index 0000000000000000000000000000000000000000..b2a17da452982fbffb2c4120f5d2c208bc177b3f --- /dev/null +++ b/qwen3/amid/checkpoint-1570/global_step1570/bf16_zero_pp_rank_0_mp_rank_00_optim_states.pt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1c8a2fb2070f7e001bc99481db2203d5aa9bf9e5ffcb975a0d649c8b3afd2e3d +size 121135557 diff --git a/qwen3/amid/checkpoint-1570/global_step1570/bf16_zero_pp_rank_1_mp_rank_00_optim_states.pt b/qwen3/amid/checkpoint-1570/global_step1570/bf16_zero_pp_rank_1_mp_rank_00_optim_states.pt new file mode 100644 index 0000000000000000000000000000000000000000..69f98096e3ef7d0022322f2b8be4afcfadb6e9ab --- /dev/null +++ b/qwen3/amid/checkpoint-1570/global_step1570/bf16_zero_pp_rank_1_mp_rank_00_optim_states.pt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:14e01dfbc51732351c410136faeca403b1f7b4bf8d7dc4d3fed0e8fe44352467 +size 121135749 diff --git a/qwen3/amid/checkpoint-1570/global_step1570/mp_rank_00_model_states.pt b/qwen3/amid/checkpoint-1570/global_step1570/mp_rank_00_model_states.pt new file mode 100644 index 0000000000000000000000000000000000000000..49eda819fd2374e2ceb2c262558ba7272fffab7a --- /dev/null +++ b/qwen3/amid/checkpoint-1570/global_step1570/mp_rank_00_model_states.pt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:30a51ab7a4e9a5c35e16652def3c25f866a3914f6bd6c7f31e27993036a6619c +size 351841765 diff --git a/qwen3/amid/checkpoint-1570/latest b/qwen3/amid/checkpoint-1570/latest new file mode 100644 index 0000000000000000000000000000000000000000..18c2fcff58fa6daa0a2e7c3a015552a69085778b --- /dev/null +++ b/qwen3/amid/checkpoint-1570/latest @@ -0,0 +1 @@ +global_step1570 \ No newline at end of file diff --git a/qwen3/amid/checkpoint-1570/rng_state_0.pth b/qwen3/amid/checkpoint-1570/rng_state_0.pth new file mode 100644 index 0000000000000000000000000000000000000000..928e2f15274bc26236f1b69d09740ff4421e3412 --- /dev/null +++ b/qwen3/amid/checkpoint-1570/rng_state_0.pth @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bd57b79bb2ca202aa5c978ef0a2bf65f56add247a12c8c298d32cf0c38ee2b3c +size 14917 diff --git a/qwen3/amid/checkpoint-1570/rng_state_1.pth b/qwen3/amid/checkpoint-1570/rng_state_1.pth new file mode 100644 index 0000000000000000000000000000000000000000..0ed396f7be83535575cdd77fea793c4b9f9d0a18 --- /dev/null +++ b/qwen3/amid/checkpoint-1570/rng_state_1.pth @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1703a50a85e61da94a321183a031f61260e7309d0f19e4f03215e48c454d4087 +size 14917 diff --git a/qwen3/amid/checkpoint-1570/scheduler.pt b/qwen3/amid/checkpoint-1570/scheduler.pt new file mode 100644 index 0000000000000000000000000000000000000000..e22954463492d8a070ae427c95418df61893c54c --- /dev/null +++ b/qwen3/amid/checkpoint-1570/scheduler.pt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e6332fac17ae99a07597512c705658da2fd8429d1c39bb776b30e107c2cb7aae +size 1465 diff --git a/qwen3/amid/checkpoint-1570/tokenizer.json b/qwen3/amid/checkpoint-1570/tokenizer.json new file mode 100644 index 0000000000000000000000000000000000000000..c7afbed2efcdf019f88ab0572ec29d3bf595dfe2 --- /dev/null +++ b/qwen3/amid/checkpoint-1570/tokenizer.json @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:be75606093db2094d7cd20f3c2f385c212750648bd6ea4fb2bf507a6a4c55506 +size 11422650 diff --git a/qwen3/amid/checkpoint-1570/tokenizer_config.json b/qwen3/amid/checkpoint-1570/tokenizer_config.json new file mode 100644 index 0000000000000000000000000000000000000000..6623da03457d79d2cd4af9557e9f31407cdb835c --- /dev/null +++ b/qwen3/amid/checkpoint-1570/tokenizer_config.json @@ -0,0 +1,31 @@ +{ + "add_prefix_space": false, + "backend": "tokenizers", + "bos_token": null, + "clean_up_tokenization_spaces": false, + "eos_token": "<|im_end|>", + "errors": "replace", + "extra_special_tokens": [ + "<|im_start|>", + "<|im_end|>", + "<|object_ref_start|>", + "<|object_ref_end|>", + "<|box_start|>", + "<|box_end|>", + "<|quad_start|>", + "<|quad_end|>", + "<|vision_start|>", + "<|vision_end|>", + "<|vision_pad|>", + "<|image_pad|>", + "<|video_pad|>" + ], + "is_local": false, + "local_files_only": false, + "model_max_length": 131072, + "pad_token": "<|endoftext|>", + "padding_side": "right", + "split_special_tokens": false, + "tokenizer_class": "Qwen2Tokenizer", + "unk_token": null +} diff --git a/qwen3/amid/checkpoint-1570/trainer_state.json b/qwen3/amid/checkpoint-1570/trainer_state.json new file mode 100644 index 0000000000000000000000000000000000000000..2698a13a67fd52a3f87941f89b547407e0d10a72 --- /dev/null +++ b/qwen3/amid/checkpoint-1570/trainer_state.json @@ -0,0 +1,655 @@ +{ + "best_global_step": null, + "best_metric": null, + "best_model_checkpoint": null, + "epoch": 5.0, + "eval_steps": 500, + "global_step": 1570, + "is_hyper_param_search": false, + "is_local_process_zero": true, + "is_world_process_zero": true, + "log_history": [ + { + "epoch": 0.06382130035899482, + "grad_norm": 0.38384687900543213, + "learning_rate": 9.996390385474569e-05, + "loss": 0.27438180446624755, + "step": 20 + }, + { + "epoch": 0.12764260071798963, + "grad_norm": 0.38263317942619324, + "learning_rate": 9.984797509888031e-05, + "loss": 0.13717052936553956, + "step": 40 + }, + { + "epoch": 0.19146390107698444, + "grad_norm": 0.08620006591081619, + "learning_rate": 9.965229938050925e-05, + "loss": 0.13135391473770142, + "step": 60 + }, + { + "epoch": 0.25528520143597927, + "grad_norm": 0.15773959457874298, + "learning_rate": 9.937719005663432e-05, + "loss": 0.1076702356338501, + "step": 80 + }, + { + "epoch": 0.3191065017949741, + "grad_norm": 0.22962816059589386, + "learning_rate": 9.902308769000724e-05, + "loss": 0.08698999881744385, + "step": 100 + }, + { + "epoch": 0.3829278021539689, + "grad_norm": 0.12232966721057892, + "learning_rate": 9.859055934360789e-05, + "loss": 0.1128507375717163, + "step": 120 + }, + { + "epoch": 0.4467491025129637, + "grad_norm": 0.15597161650657654, + "learning_rate": 9.808029767254437e-05, + "loss": 0.1277535080909729, + "step": 140 + }, + { + "epoch": 0.5105704028719585, + "grad_norm": 0.7329031825065613, + "learning_rate": 9.749311981482817e-05, + "loss": 0.08885469436645507, + "step": 160 + }, + { + "epoch": 0.5743917032309533, + "grad_norm": 0.45483648777008057, + "learning_rate": 9.682996608280154e-05, + "loss": 0.07881734371185303, + "step": 180 + }, + { + "epoch": 0.6382130035899481, + "grad_norm": 0.16407009959220886, + "learning_rate": 9.609189845731207e-05, + "loss": 0.06113555431365967, + "step": 200 + }, + { + "epoch": 0.702034303948943, + "grad_norm": 0.07238732278347015, + "learning_rate": 9.52800988870462e-05, + "loss": 0.06768973469734192, + "step": 220 + }, + { + "epoch": 0.7658556043079378, + "grad_norm": 0.4741341471672058, + "learning_rate": 9.439586739574513e-05, + "loss": 0.04917148947715759, + "step": 240 + }, + { + "epoch": 0.8296769046669326, + "grad_norm": 0.36410900950431824, + "learning_rate": 9.344062000033414e-05, + "loss": 0.010153122991323472, + "step": 260 + }, + { + "epoch": 0.8934982050259274, + "grad_norm": 0.11222824454307556, + "learning_rate": 9.241588644329919e-05, + "loss": 0.00552816241979599, + "step": 280 + }, + { + "epoch": 0.9573195053849222, + "grad_norm": 0.47910866141319275, + "learning_rate": 9.132330774294252e-05, + "loss": 0.006760746240615845, + "step": 300 + }, + { + "epoch": 1.0, + "eval_generator_count": 1712.0, + "eval_generator_exact_match": 87.3832, + "eval_generator_rouge1": 99.2069, + "eval_generator_rouge2": 98.8793, + "eval_generator_rougeL": 98.7553, + "eval_loss": 0.012839075177907944, + "eval_runtime": 592.0147, + "eval_samples_per_second": 5.767, + "eval_selector_accuracy": 90.1869, + "eval_selector_count": 1712.0, + "eval_steps_per_second": 0.181, + "step": 314 + }, + { + "epoch": 1.0191463901076985, + "grad_norm": 0.27295932173728943, + "learning_rate": 9.01646335654399e-05, + "loss": 0.009849193692207336, + "step": 320 + }, + { + "epoch": 1.0829676904666932, + "grad_norm": 0.060826949775218964, + "learning_rate": 8.894171942290817e-05, + "loss": 0.005673223733901977, + "step": 340 + }, + { + "epoch": 1.146788990825688, + "grad_norm": 0.04862668365240097, + "learning_rate": 8.765652370197003e-05, + "loss": 0.005297792330384255, + "step": 360 + }, + { + "epoch": 1.210610291184683, + "grad_norm": 0.05064748600125313, + "learning_rate": 8.631110452757467e-05, + "loss": 0.0021365636959671972, + "step": 380 + }, + { + "epoch": 1.2744315915436777, + "grad_norm": 0.05359279736876488, + "learning_rate": 8.490761646709642e-05, + "loss": 0.00429258793592453, + "step": 400 + }, + { + "epoch": 1.3382528919026724, + "grad_norm": 0.11369121074676514, + "learning_rate": 8.344830707998953e-05, + "loss": 0.0034508116543292998, + "step": 420 + }, + { + "epoch": 1.4020741922616673, + "grad_norm": 0.01604766771197319, + "learning_rate": 8.193551331852458e-05, + "loss": 0.0028350137174129484, + "step": 440 + }, + { + "epoch": 1.4658954926206622, + "grad_norm": 0.15401995182037354, + "learning_rate": 8.037165778537033e-05, + "loss": 0.005546276643872261, + "step": 460 + }, + { + "epoch": 1.5297167929796571, + "grad_norm": 0.5877118706703186, + "learning_rate": 7.875924485401427e-05, + "loss": 0.0044526983052492145, + "step": 480 + }, + { + "epoch": 1.5935380933386518, + "grad_norm": 0.10250785946846008, + "learning_rate": 7.710085665823444e-05, + "loss": 0.0056363165378570555, + "step": 500 + }, + { + "epoch": 1.6573593936976465, + "grad_norm": 0.043251167982816696, + "learning_rate": 7.539914895704521e-05, + "loss": 0.0032581716775894167, + "step": 520 + }, + { + "epoch": 1.7211806940566414, + "grad_norm": 0.2089434117078781, + "learning_rate": 7.365684688173908e-05, + "loss": 0.004207362234592438, + "step": 540 + }, + { + "epoch": 1.7850019944156363, + "grad_norm": 0.14037534594535828, + "learning_rate": 7.18767405718347e-05, + "loss": 0.0019151581451296805, + "step": 560 + }, + { + "epoch": 1.848823294774631, + "grad_norm": 0.22862067818641663, + "learning_rate": 7.006168070692036e-05, + "loss": 0.004427855834364891, + "step": 580 + }, + { + "epoch": 1.9126445951336257, + "grad_norm": 0.03684071823954582, + "learning_rate": 6.821457394154786e-05, + "loss": 0.0017833203077316285, + "step": 600 + }, + { + "epoch": 1.9764658954926206, + "grad_norm": 0.0672929510474205, + "learning_rate": 6.633837825048768e-05, + "loss": 0.0035866759717464447, + "step": 620 + }, + { + "epoch": 2.0, + "eval_generator_count": 1712.0, + "eval_generator_exact_match": 93.5164, + "eval_generator_rouge1": 99.7294, + "eval_generator_rouge2": 99.5697, + "eval_generator_rougeL": 99.5152, + "eval_loss": 0.006910035386681557, + "eval_runtime": 591.6591, + "eval_samples_per_second": 5.77, + "eval_selector_accuracy": 96.9042, + "eval_selector_count": 1712.0, + "eval_steps_per_second": 0.181, + "step": 628 + }, + { + "epoch": 2.038292780215397, + "grad_norm": 0.029134005308151245, + "learning_rate": 6.443609819179926e-05, + "loss": 0.0020816387608647347, + "step": 640 + }, + { + "epoch": 2.102114080574392, + "grad_norm": 0.17367292940616608, + "learning_rate": 6.251078009530256e-05, + "loss": 0.0019141122698783874, + "step": 660 + }, + { + "epoch": 2.1659353809333863, + "grad_norm": 0.016447540372610092, + "learning_rate": 6.0565507184155677e-05, + "loss": 0.0009251200594007969, + "step": 680 + }, + { + "epoch": 2.2297566812923812, + "grad_norm": 0.015570643357932568, + "learning_rate": 5.860339463735136e-05, + "loss": 0.0017806822434067726, + "step": 700 + }, + { + "epoch": 2.293577981651376, + "grad_norm": 0.010291235521435738, + "learning_rate": 5.662758460103895e-05, + "loss": 0.0010542120784521104, + "step": 720 + }, + { + "epoch": 2.357399282010371, + "grad_norm": 0.012873738072812557, + "learning_rate": 5.464124115666095e-05, + "loss": 0.0009571929462254047, + "step": 740 + }, + { + "epoch": 2.421220582369366, + "grad_norm": 0.009928264655172825, + "learning_rate": 5.264754525396212e-05, + "loss": 0.0007098949514329434, + "step": 760 + }, + { + "epoch": 2.4850418827283605, + "grad_norm": 0.014300181530416012, + "learning_rate": 5.06496896169857e-05, + "loss": 0.0007610605098307133, + "step": 780 + }, + { + "epoch": 2.5488631830873554, + "grad_norm": 0.03284010663628578, + "learning_rate": 4.865087363121384e-05, + "loss": 0.002758556976914406, + "step": 800 + }, + { + "epoch": 2.6126844834463503, + "grad_norm": 0.19087237119674683, + "learning_rate": 4.6654298220040673e-05, + "loss": 0.0011194748803973198, + "step": 820 + }, + { + "epoch": 2.6765057838053448, + "grad_norm": 0.02937050722539425, + "learning_rate": 4.466316071878229e-05, + "loss": 0.0014943076297640801, + "step": 840 + }, + { + "epoch": 2.74032708416434, + "grad_norm": 0.031206471845507622, + "learning_rate": 4.2680649754432913e-05, + "loss": 0.0027773819863796236, + "step": 860 + }, + { + "epoch": 2.8041483845233346, + "grad_norm": 0.019134322181344032, + "learning_rate": 4.070994013936646e-05, + "loss": 0.0018997505307197572, + "step": 880 + }, + { + "epoch": 2.8679696848823295, + "grad_norm": 0.2537505030632019, + "learning_rate": 3.8754187787161155e-05, + "loss": 0.0010082274675369263, + "step": 900 + }, + { + "epoch": 2.9317909852413244, + "grad_norm": 0.0017131563508883119, + "learning_rate": 3.681652465868875e-05, + "loss": 0.0012075364589691161, + "step": 920 + }, + { + "epoch": 2.995612285600319, + "grad_norm": 0.03925931081175804, + "learning_rate": 3.490005374656184e-05, + "loss": 0.000642749946564436, + "step": 940 + }, + { + "epoch": 3.0, + "eval_generator_count": 1712.0, + "eval_generator_exact_match": 95.3855, + "eval_generator_rouge1": 99.8982, + "eval_generator_rouge2": 99.8084, + "eval_generator_rougeL": 99.6633, + "eval_loss": 0.0056763943284749985, + "eval_runtime": 590.3317, + "eval_samples_per_second": 5.783, + "eval_selector_accuracy": 96.5537, + "eval_selector_count": 1712.0, + "eval_steps_per_second": 0.181, + "step": 942 + }, + { + "epoch": 3.057439170323095, + "grad_norm": 0.0036900911945849657, + "learning_rate": 3.3007844105971336e-05, + "loss": 0.0012762822210788728, + "step": 960 + }, + { + "epoch": 3.12126047068209, + "grad_norm": 0.028549807146191597, + "learning_rate": 3.114292593987149e-05, + "loss": 0.0006767791230231524, + "step": 980 + }, + { + "epoch": 3.185081771041085, + "grad_norm": 0.007299487479031086, + "learning_rate": 2.9308285746383408e-05, + "loss": 0.0012082518078386784, + "step": 1000 + }, + { + "epoch": 3.24890307140008, + "grad_norm": 0.03702578693628311, + "learning_rate": 2.7506861536187867e-05, + "loss": 0.0014168912544846534, + "step": 1020 + }, + { + "epoch": 3.3127243717590744, + "grad_norm": 0.21273940801620483, + "learning_rate": 2.5741538127566396e-05, + "loss": 0.0012415657751262189, + "step": 1040 + }, + { + "epoch": 3.3765456721180693, + "grad_norm": 0.0033840558025985956, + "learning_rate": 2.4015142526625115e-05, + "loss": 0.0009985800832509994, + "step": 1060 + }, + { + "epoch": 3.4403669724770642, + "grad_norm": 0.020664699375629425, + "learning_rate": 2.233043940009967e-05, + "loss": 0.0011398554779589176, + "step": 1080 + }, + { + "epoch": 3.504188272836059, + "grad_norm": 0.0015457016415894032, + "learning_rate": 2.0690126647990974e-05, + "loss": 0.0016313906759023666, + "step": 1100 + }, + { + "epoch": 3.568009573195054, + "grad_norm": 0.011757194995880127, + "learning_rate": 1.9096831083121828e-05, + "loss": 0.0010684640146791935, + "step": 1120 + }, + { + "epoch": 3.6318308735540485, + "grad_norm": 0.007703748065978289, + "learning_rate": 1.7553104224533324e-05, + "loss": 0.0006688186898827553, + "step": 1140 + }, + { + "epoch": 3.6956521739130435, + "grad_norm": 0.04895896837115288, + "learning_rate": 1.606141821145735e-05, + "loss": 0.0016563836485147475, + "step": 1160 + }, + { + "epoch": 3.7594734742720384, + "grad_norm": 0.04278242960572243, + "learning_rate": 1.4624161844408763e-05, + "loss": 0.0006196124479174614, + "step": 1180 + }, + { + "epoch": 3.823294774631033, + "grad_norm": 0.004100222606211901, + "learning_rate": 1.324363675973698e-05, + "loss": 0.0009099396876990796, + "step": 1200 + }, + { + "epoch": 3.8871160749900278, + "grad_norm": 0.06636715680360794, + "learning_rate": 1.1922053743763052e-05, + "loss": 0.0012004765681922435, + "step": 1220 + }, + { + "epoch": 3.9509373753490227, + "grad_norm": 0.005992025602608919, + "learning_rate": 1.0661529192404973e-05, + "loss": 0.0003460923908278346, + "step": 1240 + }, + { + "epoch": 4.0, + "eval_generator_count": 1712.0, + "eval_generator_exact_match": 95.8528, + "eval_generator_rouge1": 99.9186, + "eval_generator_rouge2": 99.8428, + "eval_generator_rougeL": 99.7108, + "eval_loss": 0.004311855416744947, + "eval_runtime": 587.5171, + "eval_samples_per_second": 5.811, + "eval_selector_accuracy": 98.1893, + "eval_selector_count": 1712.0, + "eval_steps_per_second": 0.182, + "step": 1256 + }, + { + "epoch": 4.0127642600717985, + "grad_norm": 0.12402024120092392, + "learning_rate": 9.464081721960592e-06, + "loss": 0.0005224554799497128, + "step": 1260 + }, + { + "epoch": 4.076585560430794, + "grad_norm": 0.032988350838422775, + "learning_rate": 8.331628936475818e-06, + "loss": 0.00022895974107086658, + "step": 1280 + }, + { + "epoch": 4.140406860789788, + "grad_norm": 0.002514337655156851, + "learning_rate": 7.2659843568748385e-06, + "loss": 0.00028093236032873393, + "step": 1300 + }, + { + "epoch": 4.204228161148784, + "grad_norm": 0.013952493667602539, + "learning_rate": 6.268854516770008e-06, + "loss": 0.0007838346064090729, + "step": 1320 + }, + { + "epoch": 4.268049461507778, + "grad_norm": 0.00595195172354579, + "learning_rate": 5.341836229602331e-06, + "loss": 0.0010836148634552956, + "step": 1340 + }, + { + "epoch": 4.331870761866773, + "grad_norm": 0.24550670385360718, + "learning_rate": 4.4864140314888216e-06, + "loss": 0.001040823757648468, + "step": 1360 + }, + { + "epoch": 4.395692062225768, + "grad_norm": 0.009249023161828518, + "learning_rate": 3.703957803871932e-06, + "loss": 0.0006210384890437126, + "step": 1380 + }, + { + "epoch": 4.4595133625847625, + "grad_norm": 0.010251481086015701, + "learning_rate": 2.9957205797780495e-06, + "loss": 0.0005129187367856503, + "step": 1400 + }, + { + "epoch": 4.523334662943758, + "grad_norm": 0.024013608694076538, + "learning_rate": 2.362836537198199e-06, + "loss": 0.0004933405201882124, + "step": 1420 + }, + { + "epoch": 4.587155963302752, + "grad_norm": 0.028239818289875984, + "learning_rate": 1.8063191828043703e-06, + "loss": 0.0005304558202624321, + "step": 1440 + }, + { + "epoch": 4.650977263661747, + "grad_norm": 0.01863635517656803, + "learning_rate": 1.3270597289100437e-06, + "loss": 0.00033774527255445717, + "step": 1460 + }, + { + "epoch": 4.714798564020742, + "grad_norm": 0.0036166764330118895, + "learning_rate": 9.258256662741205e-07, + "loss": 0.0002381577854976058, + "step": 1480 + }, + { + "epoch": 4.778619864379737, + "grad_norm": 0.016647396609187126, + "learning_rate": 6.032595350337341e-07, + "loss": 0.0005346011370420456, + "step": 1500 + }, + { + "epoch": 4.842441164738732, + "grad_norm": 0.14798367023468018, + "learning_rate": 3.5987789573421356e-07, + "loss": 0.0015266412869095803, + "step": 1520 + }, + { + "epoch": 4.9062624650977265, + "grad_norm": 0.1593816727399826, + "learning_rate": 1.9607050210401192e-07, + "loss": 0.0003545734565705061, + "step": 1540 + }, + { + "epoch": 4.970083765456721, + "grad_norm": 0.01692381501197815, + "learning_rate": 1.1209967689925832e-07, + "loss": 0.0004393013659864664, + "step": 1560 + }, + { + "epoch": 5.0, + "eval_generator_count": 1712.0, + "eval_generator_exact_match": 95.736, + "eval_generator_rouge1": 99.9082, + "eval_generator_rouge2": 99.8294, + "eval_generator_rougeL": 99.7068, + "eval_loss": 0.004025007598102093, + "eval_runtime": 591.5846, + "eval_samples_per_second": 5.771, + "eval_selector_accuracy": 98.6565, + "eval_selector_count": 1712.0, + "eval_steps_per_second": 0.181, + "step": 1570 + } + ], + "logging_steps": 20, + "max_steps": 1570, + "num_input_tokens_seen": 0, + "num_train_epochs": 5, + "save_steps": 500, + "stateful_callbacks": { + "TrainerControl": { + "args": { + "should_epoch_stop": false, + "should_evaluate": false, + "should_log": false, + "should_save": true, + "should_training_stop": true + }, + "attributes": {} + } + }, + "total_flos": 5.871444840310374e+16, + "train_batch_size": 2, + "trial_name": null, + "trial_params": null +} diff --git a/qwen3/amid/checkpoint-1570/training_args.bin b/qwen3/amid/checkpoint-1570/training_args.bin new file mode 100644 index 0000000000000000000000000000000000000000..571568fd8ab61d629f2a731739ee4c9e1309cca4 --- /dev/null +++ b/qwen3/amid/checkpoint-1570/training_args.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e67133ff7a80f6f166c03bd5f62d9c580548b0f6840a1ce3891dee623991e47a +size 7185 diff --git a/qwen3/amid/checkpoint-1570/zero_to_fp32.py b/qwen3/amid/checkpoint-1570/zero_to_fp32.py new file mode 100644 index 0000000000000000000000000000000000000000..f40f1f0acbbff30e8e8d29906b56aae4e8b8a138 --- /dev/null +++ b/qwen3/amid/checkpoint-1570/zero_to_fp32.py @@ -0,0 +1,790 @@ +#!/usr/bin/env python + +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: Apache-2.0 + +# DeepSpeed Team + +# This script extracts fp32 consolidated weights from a zero 1, 2 and 3 DeepSpeed checkpoints. It gets +# copied into the top level checkpoint dir, so the user can easily do the conversion at any point in +# the future. Once extracted, the weights don't require DeepSpeed and can be used in any +# application. +# +# example: +# python zero_to_fp32.py . output_dir/ +# or +# python zero_to_fp32.py . output_dir/ --safe_serialization + +import argparse +import torch +import glob +import math +import os +import re +import gc +import json +import numpy as np +from tqdm import tqdm +from collections import OrderedDict +from dataclasses import dataclass + +# while this script doesn't use deepspeed to recover data, since the checkpoints are pickled with +# DeepSpeed data structures it has to be available in the current python environment. +from deepspeed.utils import logger +from deepspeed.checkpoint.constants import (DS_VERSION, OPTIMIZER_STATE_DICT, SINGLE_PARTITION_OF_FP32_GROUPS, + FP32_FLAT_GROUPS, ZERO_STAGE, PARTITION_COUNT, PARAM_SHAPES, BUFFER_NAMES, + FROZEN_PARAM_SHAPES, FROZEN_PARAM_FRAGMENTS, AUTOEP_LAYERS_KEY, + AUTOEP_LAYERS_KEY_LEGACY, AUTOEP_ZERO3_EXPERT_STATE_FORMAT_KEY, + AUTOEP_ZERO3_PARTITIONED_EXPERT_STATE_FORMAT) + + +@dataclass +class zero_model_state: + buffers: dict() + param_shapes: dict() + shared_params: list + ds_version: int + frozen_param_shapes: dict() + frozen_param_fragments: dict() + + +debug = 0 + +# load to cpu +device = torch.device('cpu') + + +def atoi(text): + return int(text) if text.isdigit() else text + + +def natural_keys(text): + ''' + alist.sort(key=natural_keys) sorts in human order + http://nedbatchelder.com/blog/200712/human_sorting.html + (See Toothy's implementation in the comments) + ''' + return [atoi(c) for c in re.split(r'(\d+)', text)] + + +def get_model_state_file(checkpoint_dir, zero_stage): + if not os.path.isdir(checkpoint_dir): + raise FileNotFoundError(f"Directory '{checkpoint_dir}' doesn't exist") + + # there should be only one file + if zero_stage <= 2: + file = os.path.join(checkpoint_dir, "mp_rank_00_model_states.pt") + elif zero_stage == 3: + file = os.path.join(checkpoint_dir, "zero_pp_rank_0_mp_rank_00_model_states.pt") + + if not os.path.exists(file): + raise FileNotFoundError(f"can't find model states file at '{file}'") + + return file + + +def get_checkpoint_files(checkpoint_dir, glob_pattern): + # XXX: need to test that this simple glob rule works for multi-node setup too + ckpt_files = sorted(glob.glob(os.path.join(checkpoint_dir, glob_pattern)), key=natural_keys) + + if len(ckpt_files) == 0: + raise FileNotFoundError(f"can't find {glob_pattern} files in directory '{checkpoint_dir}'") + + return ckpt_files + + +def get_optim_files(checkpoint_dir): + return get_checkpoint_files(checkpoint_dir, "*_optim_states.pt") + + +def get_model_state_files(checkpoint_dir): + return get_checkpoint_files(checkpoint_dir, "*_model_states.pt") + + +def _has_autoep_zero3_partitioned_metadata(state_dict): + autoep_layers = state_dict.get(AUTOEP_LAYERS_KEY) + if autoep_layers is None: + autoep_layers = state_dict.get(AUTOEP_LAYERS_KEY_LEGACY) + if not isinstance(autoep_layers, list): + return False + return any( + isinstance(entry, dict) + and entry.get(AUTOEP_ZERO3_EXPERT_STATE_FORMAT_KEY) == AUTOEP_ZERO3_PARTITIONED_EXPERT_STATE_FORMAT + for entry in autoep_layers) + + +def _raise_if_autoep_zero3_partitioned_state(state_dict): + if _has_autoep_zero3_partitioned_metadata(state_dict): + raise NotImplementedError("zero_to_fp32 does not support AutoEP ZeRO-3 partition-native checkpoints. " + "AutoEP expert parameters are partitioned over expert replica groups, so " + "global data-parallel consolidation would produce incomplete expert tensors. " + "Use ds_to_universal.py for expert-aware conversion.") + + +def _raise_if_autoep_zero3_partitioned_checkpoint(model_files): + for file in model_files: + state_dict = torch.load(file, map_location=device, weights_only=False) + _raise_if_autoep_zero3_partitioned_state(state_dict) + + +def parse_model_states(files): + zero_model_states = [] + for file in files: + state_dict = torch.load(file, map_location=device, weights_only=False) + _raise_if_autoep_zero3_partitioned_state(state_dict) + + if BUFFER_NAMES not in state_dict: + raise ValueError(f"{file} is not a model state checkpoint") + buffer_names = state_dict[BUFFER_NAMES] + if debug: + print("Found buffers:", buffer_names) + + # recover just the buffers while restoring them to fp32 if they were saved in fp16 + buffers = {k: v.float() for k, v in state_dict["module"].items() if k in buffer_names} + param_shapes = state_dict[PARAM_SHAPES] + + # collect parameters that are included in param_shapes + param_names = [] + for s in param_shapes: + for name in s.keys(): + param_names.append(name) + + # update with frozen parameters + frozen_param_shapes = state_dict.get(FROZEN_PARAM_SHAPES, None) + if frozen_param_shapes is not None: + if debug: + print(f"Found frozen_param_shapes: {frozen_param_shapes}") + param_names += list(frozen_param_shapes.keys()) + + # handle shared params + shared_params = [[k, v] for k, v in state_dict["shared_params"].items()] + + ds_version = state_dict.get(DS_VERSION, None) + + frozen_param_fragments = state_dict.get(FROZEN_PARAM_FRAGMENTS, None) + + z_model_state = zero_model_state(buffers=buffers, + param_shapes=param_shapes, + shared_params=shared_params, + ds_version=ds_version, + frozen_param_shapes=frozen_param_shapes, + frozen_param_fragments=frozen_param_fragments) + zero_model_states.append(z_model_state) + + return zero_model_states + + +def parse_optim_states(files, ds_checkpoint_dir): + total_files = len(files) + state_dicts = [] + for f in tqdm(files, desc='Loading checkpoint shards'): + state_dict = torch.load(f, map_location=device, mmap=True, weights_only=False) + # immediately discard the potentially huge 2 optimizer states as we only care for fp32 master weights + # and also handle the case where it was already removed by another helper script + state_dict["optimizer_state_dict"].pop("optimizer_state_dict", None) + state_dicts.append(state_dict) + + if ZERO_STAGE not in state_dicts[0][OPTIMIZER_STATE_DICT]: + raise ValueError(f"{files[0]} is not a zero checkpoint") + zero_stage = state_dicts[0][OPTIMIZER_STATE_DICT][ZERO_STAGE] + world_size = state_dicts[0][OPTIMIZER_STATE_DICT][PARTITION_COUNT] + + # For ZeRO-2 each param group can have different partition_count as data parallelism for expert + # parameters can be different from data parallelism for non-expert parameters. So we can just + # use the max of the partition_count to get the dp world_size. + + if type(world_size) is list: + world_size = max(world_size) + + if world_size != total_files: + raise ValueError( + f"Expected {world_size} of '*_optim_states.pt' under '{ds_checkpoint_dir}' but found {total_files} files. " + "Possibly due to an overwrite of an old checkpoint, or a checkpoint didn't get saved by one or more processes." + ) + + # the groups are named differently in each stage + if zero_stage <= 2: + fp32_groups_key = SINGLE_PARTITION_OF_FP32_GROUPS + elif zero_stage == 3: + fp32_groups_key = FP32_FLAT_GROUPS + else: + raise ValueError(f"unknown zero stage {zero_stage}") + + fp32_flat_groups = [state_dicts[i][OPTIMIZER_STATE_DICT][fp32_groups_key] for i in range(len(state_dicts))] + return zero_stage, world_size, fp32_flat_groups + + +def _get_fp32_state_dict_from_zero_checkpoint(ds_checkpoint_dir, exclude_frozen_parameters): + """ + Returns fp32 state_dict reconstructed from ds checkpoint + + Args: + - ``ds_checkpoint_dir``: path to the deepspeed checkpoint folder (where the optimizer files are) + + """ + print(f"Processing zero checkpoint '{ds_checkpoint_dir}'") + + # parse_model_states rejects AutoEP ZeRO-3 partition-native checkpoints + # before the expensive optimizer-shard load below. + model_files = get_model_state_files(ds_checkpoint_dir) + zero_model_states = parse_model_states(model_files) + print(f'Parsing checkpoint created by deepspeed=={zero_model_states[0].ds_version}') + + optim_files = get_optim_files(ds_checkpoint_dir) + zero_stage, world_size, fp32_flat_groups = parse_optim_states(optim_files, ds_checkpoint_dir) + print(f"Detected checkpoint of type zero stage {zero_stage}, world_size: {world_size}") + + if zero_stage <= 2: + return _get_fp32_state_dict_from_zero2_checkpoint(world_size, fp32_flat_groups, zero_model_states, + exclude_frozen_parameters) + elif zero_stage == 3: + return _get_fp32_state_dict_from_zero3_checkpoint(world_size, fp32_flat_groups, zero_model_states, + exclude_frozen_parameters) + + +def _zero2_merge_frozen_params(state_dict, zero_model_states): + if zero_model_states[0].frozen_param_shapes is None or len(zero_model_states[0].frozen_param_shapes) == 0: + return + + frozen_param_shapes = zero_model_states[0].frozen_param_shapes + frozen_param_fragments = zero_model_states[0].frozen_param_fragments + + if debug: + num_elem = sum(s.numel() for s in frozen_param_shapes.values()) + print(f'rank 0: {FROZEN_PARAM_SHAPES}.numel = {num_elem}') + + wanted_params = len(frozen_param_shapes) + wanted_numel = sum(s.numel() for s in frozen_param_shapes.values()) + avail_numel = sum([p.numel() for p in frozen_param_fragments.values()]) + print(f'Frozen params: Have {avail_numel} numels to process.') + print(f'Frozen params: Need {wanted_numel} numels in {wanted_params} params') + + total_params = 0 + total_numel = 0 + for name, shape in frozen_param_shapes.items(): + total_params += 1 + unpartitioned_numel = shape.numel() + total_numel += unpartitioned_numel + + state_dict[name] = frozen_param_fragments[name] + + if debug: + print(f"{name} full shape: {shape} unpartitioned numel {unpartitioned_numel} ") + + print(f"Reconstructed Frozen fp32 state dict with {total_params} params {total_numel} elements") + + +def _has_callable(obj, fn): + attr = getattr(obj, fn, None) + return callable(attr) + + +def _zero2_merge_trainable_params(state_dict, world_size, fp32_flat_groups, zero_model_states): + param_shapes = zero_model_states[0].param_shapes + + # Reconstruction protocol: + # + # XXX: document this + + if debug: + for i in range(world_size): + for j in range(len(fp32_flat_groups[0])): + print(f"{FP32_FLAT_GROUPS}[{i}][{j}].shape={fp32_flat_groups[i][j].shape}") + + # XXX: memory usage doubles here (zero2) + num_param_groups = len(fp32_flat_groups[0]) + merged_single_partition_of_fp32_groups = [] + for i in range(num_param_groups): + merged_partitions = [sd[i] for sd in fp32_flat_groups] + full_single_fp32_vector = torch.cat(merged_partitions, 0) + merged_single_partition_of_fp32_groups.append(full_single_fp32_vector) + avail_numel = sum( + [full_single_fp32_vector.numel() for full_single_fp32_vector in merged_single_partition_of_fp32_groups]) + + if debug: + wanted_params = sum([len(shapes) for shapes in param_shapes]) + wanted_numel = sum([sum(shape.numel() for shape in shapes.values()) for shapes in param_shapes]) + # not asserting if there is a mismatch due to possible padding + print(f"Have {avail_numel} numels to process.") + print(f"Need {wanted_numel} numels in {wanted_params} params.") + + # params + # XXX: for huge models that can't fit into the host's RAM we will have to recode this to support + # out-of-core computing solution + total_numel = 0 + total_params = 0 + for shapes, full_single_fp32_vector in zip(param_shapes, merged_single_partition_of_fp32_groups): + offset = 0 + avail_numel = full_single_fp32_vector.numel() + for name, shape in shapes.items(): + + unpartitioned_numel = shape.numel() if _has_callable(shape, 'numel') else math.prod(shape) + total_numel += unpartitioned_numel + total_params += 1 + + if debug: + print(f"{name} full shape: {shape} unpartitioned numel {unpartitioned_numel} ") + state_dict[name] = full_single_fp32_vector.narrow(0, offset, unpartitioned_numel).view(shape) + offset += unpartitioned_numel + + # Z2 started to align to 2*world_size to improve nccl performance. Therefore both offset and + # avail_numel can differ by anywhere between 0..2*world_size. Due to two unrelated complex + # paddings performed in the code it's almost impossible to predict the exact numbers w/o the + # live optimizer object, so we are checking that the numbers are within the right range + align_to = 2 * world_size + + def zero2_align(x): + return align_to * math.ceil(x / align_to) + + if debug: + print(f"original offset={offset}, avail_numel={avail_numel}") + + offset = zero2_align(offset) + avail_numel = zero2_align(avail_numel) + + if debug: + print(f"aligned offset={offset}, avail_numel={avail_numel}") + + # Sanity check + if offset != avail_numel: + raise ValueError(f"consumed {offset} numels out of {avail_numel} - something is wrong") + + print(f"Reconstructed fp32 state dict with {total_params} params {total_numel} elements") + + +def _get_fp32_state_dict_from_zero2_checkpoint(world_size, fp32_flat_groups, zero_model_states, + exclude_frozen_parameters): + state_dict = OrderedDict() + + # buffers + buffers = zero_model_states[0].buffers + state_dict.update(buffers) + if debug: + print(f"added {len(buffers)} buffers") + + if not exclude_frozen_parameters: + _zero2_merge_frozen_params(state_dict, zero_model_states) + + _zero2_merge_trainable_params(state_dict, world_size, fp32_flat_groups, zero_model_states) + + # recover shared parameters + for pair in zero_model_states[0].shared_params: + if pair[1] in state_dict: + state_dict[pair[0]] = state_dict[pair[1]] + + return state_dict + + +def zero3_partitioned_param_info(unpartitioned_numel, world_size): + remainder = unpartitioned_numel % world_size + padding_numel = (world_size - remainder) if remainder else 0 + partitioned_numel = math.ceil(unpartitioned_numel / world_size) + return partitioned_numel, padding_numel + + +def _zero3_merge_frozen_params(state_dict, world_size, zero_model_states): + if zero_model_states[0].frozen_param_shapes is None or len(zero_model_states[0].frozen_param_shapes) == 0: + return + + if debug: + for i in range(world_size): + num_elem = sum(s.numel() for s in zero_model_states[i].frozen_param_fragments.values()) + print(f'rank {i}: {FROZEN_PARAM_SHAPES}.numel = {num_elem}') + + frozen_param_shapes = zero_model_states[0].frozen_param_shapes + wanted_params = len(frozen_param_shapes) + wanted_numel = sum(s.numel() for s in frozen_param_shapes.values()) + avail_numel = sum([p.numel() for p in zero_model_states[0].frozen_param_fragments.values()]) * world_size + print(f'Frozen params: Have {avail_numel} numels to process.') + print(f'Frozen params: Need {wanted_numel} numels in {wanted_params} params') + + total_params = 0 + total_numel = 0 + for name, shape in zero_model_states[0].frozen_param_shapes.items(): + total_params += 1 + unpartitioned_numel = shape.numel() + total_numel += unpartitioned_numel + + param_frags = tuple(model_state.frozen_param_fragments[name] for model_state in zero_model_states) + state_dict[name] = torch.cat(param_frags, 0).narrow(0, 0, unpartitioned_numel).view(shape) + + partitioned_numel, partitioned_padding_numel = zero3_partitioned_param_info(unpartitioned_numel, world_size) + + if debug: + print( + f"Frozen params: {total_params} {name} full shape: {shape} partition0 numel={partitioned_numel} partitioned_padding_numel={partitioned_padding_numel}" + ) + + print(f"Reconstructed Frozen fp32 state dict with {total_params} params {total_numel} elements") + + +class GatheredTensor: + """ + A pseudo tensor that collects partitioned weights. + It is more memory efficient when there are multiple groups. + """ + + def __init__(self, flat_groups, flat_groups_offset, offset, partitioned_numel, shape): + self.flat_groups = flat_groups + self.flat_groups_offset = flat_groups_offset + self.offset = offset + self.partitioned_numel = partitioned_numel + self.shape = shape + self.dtype = self.flat_groups[0][0].dtype + + def contiguous(self): + """ + Merge partitioned weights from flat_groups into a single tensor. + """ + end_idx = self.offset + self.partitioned_numel + world_size = len(self.flat_groups) + pad_flat_param_chunks = [] + + for rank_i in range(world_size): + # for each rank, we need to collect weights from related group/groups + flat_groups_at_rank_i = self.flat_groups[rank_i] + start_group_id = None + end_group_id = None + for group_id in range(len(self.flat_groups_offset)): + if self.flat_groups_offset[group_id] <= self.offset < self.flat_groups_offset[group_id + 1]: + start_group_id = group_id + if self.flat_groups_offset[group_id] < end_idx <= self.flat_groups_offset[group_id + 1]: + end_group_id = group_id + break + # collect weights from related group/groups + for group_id in range(start_group_id, end_group_id + 1): + flat_tensor = flat_groups_at_rank_i[group_id] + start_offset = self.offset - self.flat_groups_offset[group_id] + end_offset = min(end_idx, self.flat_groups_offset[group_id + 1]) - self.flat_groups_offset[group_id] + pad_flat_param_chunks.append(flat_tensor[start_offset:end_offset]) + + # collect weights from all ranks + pad_flat_param = torch.cat(pad_flat_param_chunks, dim=0) + param = pad_flat_param[:self.shape.numel()].view(self.shape).contiguous() + return param + + +def _zero3_merge_trainable_params(state_dict, world_size, fp32_flat_groups, zero_model_states): + param_shapes = zero_model_states[0].param_shapes + avail_numel = sum([flat_group.numel() for flat_group in fp32_flat_groups[0]]) * world_size + + # Reconstruction protocol: For zero3 we need to zip the partitions together at boundary of each + # param, re-consolidating each param, while dealing with padding if any + + # merge list of dicts, preserving order + param_shapes = {k: v for d in param_shapes for k, v in d.items()} + + if debug: + for i in range(world_size): + print(f"{FP32_FLAT_GROUPS}[{i}].shape={fp32_flat_groups[i].shape}") + + wanted_params = len(param_shapes) + wanted_numel = sum(shape.numel() for shape in param_shapes.values()) + # not asserting if there is a mismatch due to possible padding + avail_numel = fp32_flat_groups[0].numel() * world_size + print(f"Trainable params: Have {avail_numel} numels to process.") + print(f"Trainable params: Need {wanted_numel} numels in {wanted_params} params.") + + # params + # XXX: for huge models that can't fit into the host's RAM we will have to recode this to support + # out-of-core computing solution + offset = 0 + total_numel = 0 + total_params = 0 + flat_groups_offset = [0] + list(np.cumsum([flat_tensor.numel() for flat_tensor in fp32_flat_groups[0]])) + for name, shape in tqdm(param_shapes.items(), desc='Gathering sharded weights'): + unpartitioned_numel = shape.numel() + total_numel += unpartitioned_numel + total_params += 1 + partitioned_numel, partitioned_padding_numel = zero3_partitioned_param_info(unpartitioned_numel, world_size) + + if debug: + print( + f"Trainable params: {total_params} {name} full shape: {shape} partition0 numel={partitioned_numel} partitioned_padding_numel={partitioned_padding_numel}" + ) + + # memory efficient tensor + tensor = GatheredTensor(fp32_flat_groups, flat_groups_offset, offset, partitioned_numel, shape) + state_dict[name] = tensor + offset += partitioned_numel + + offset *= world_size + + # Sanity check + if offset != avail_numel: + raise ValueError(f"consumed {offset} numels out of {avail_numel} - something is wrong") + + print(f"Reconstructed Trainable fp32 state dict with {total_params} params {total_numel} elements") + + +def _get_fp32_state_dict_from_zero3_checkpoint(world_size, fp32_flat_groups, zero_model_states, + exclude_frozen_parameters): + state_dict = OrderedDict() + + # buffers + buffers = zero_model_states[0].buffers + state_dict.update(buffers) + if debug: + print(f"added {len(buffers)} buffers") + + if not exclude_frozen_parameters: + _zero3_merge_frozen_params(state_dict, world_size, zero_model_states) + + _zero3_merge_trainable_params(state_dict, world_size, fp32_flat_groups, zero_model_states) + + # recover shared parameters + for pair in zero_model_states[0].shared_params: + if pair[1] in state_dict: + state_dict[pair[0]] = state_dict[pair[1]] + + return state_dict + + +def to_torch_tensor(state_dict, return_empty_tensor=False): + """ + Convert state_dict of GatheredTensor to torch tensor + """ + torch_state_dict = {} + converted_tensors = {} + for name, tensor in state_dict.items(): + tensor_id = id(tensor) + if tensor_id in converted_tensors: # shared tensors + shared_tensor = torch_state_dict[converted_tensors[tensor_id]] + torch_state_dict[name] = shared_tensor + else: + converted_tensors[tensor_id] = name + if return_empty_tensor: + torch_state_dict[name] = torch.empty(tensor.shape, dtype=tensor.dtype) + else: + torch_state_dict[name] = tensor.contiguous() + return torch_state_dict + + +def get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir, + tag=None, + exclude_frozen_parameters=False, + lazy_mode=False): + """ + Convert ZeRO 2 or 3 checkpoint into a single fp32 consolidated state_dict that can be loaded with + ``load_state_dict()`` and used for training without DeepSpeed or shared with others, for example + via a model hub. + + Args: + - ``checkpoint_dir``: path to the desired checkpoint folder + - ``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`` + - ``exclude_frozen_parameters``: exclude frozen parameters + - ``lazy_mode``: get state_dict in lazy mode. It returns a dict of pesduo tensor instead of torch tensor, which is more memory efficient. + Convert the pesduo tensor to torch tensor by ``.contiguous()`` + + Returns: + - pytorch ``state_dict`` + + A typical usage might be :: + + from deepspeed.utils.zero_to_fp32 import get_fp32_state_dict_from_zero_checkpoint + # do the training and checkpoint saving + state_dict = get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir) # already on cpu + model = model.cpu() # move to cpu + model.load_state_dict(state_dict) + # submit to model hub or save the model to share with others + + In this example the ``model`` will no longer be usable in the deepspeed context of the same + application. i.e. you will need to re-initialize the deepspeed engine, since + ``model.load_state_dict(state_dict)`` will remove all the deepspeed magic from it. + + If you want it all done for you, use ``load_state_dict_from_zero_checkpoint`` instead. + + Note: the above usage may not work if your application doesn't have sufficient free CPU memory. + You may need to use the offline approach using the ``zero_to_fp32.py`` script that is saved with + the checkpoint. Or you can load state_dict in lazy mode :: + + from deepspeed.utils.zero_to_fp32 import get_fp32_state_dict_from_zero_checkpoint + state_dict = get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir, lazy_mode=True) # not on cpu + for name, lazy_tensor in state_dict.item(): + tensor = lazy_tensor.contiguous() # to cpu + print(name, tensor) + # del tensor to release memory if it no longer in use + """ + if tag is None: + latest_path = os.path.join(checkpoint_dir, 'latest') + if os.path.isfile(latest_path): + with open(latest_path, 'r') as fd: + tag = fd.read().strip() + else: + raise ValueError(f"Unable to find 'latest' file at {latest_path}") + + ds_checkpoint_dir = os.path.join(checkpoint_dir, tag) + + if not os.path.isdir(ds_checkpoint_dir): + raise FileNotFoundError(f"Directory '{ds_checkpoint_dir}' doesn't exist") + + state_dict = _get_fp32_state_dict_from_zero_checkpoint(ds_checkpoint_dir, exclude_frozen_parameters) + if lazy_mode: + return state_dict + else: + return to_torch_tensor(state_dict) + + +def convert_zero_checkpoint_to_fp32_state_dict(checkpoint_dir, + output_dir, + max_shard_size="5GB", + safe_serialization=False, + tag=None, + exclude_frozen_parameters=False): + """ + Convert ZeRO 2 or 3 checkpoint into a single fp32 consolidated ``state_dict`` file that can be + loaded with ``torch.load(file)`` + ``load_state_dict()`` and used for training without DeepSpeed. + + Args: + - ``checkpoint_dir``: path to the desired checkpoint folder. (one that contains the tag-folder, like ``global_step14``) + - ``output_dir``: directory to the pytorch fp32 state_dict output files + - ``max_shard_size``: the maximum size for a checkpoint before being sharded, default value is 5GB + - ``safe_serialization``: whether to save the model using `safetensors` or the traditional PyTorch way (that uses `pickle`). + - ``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`` + - ``exclude_frozen_parameters``: exclude frozen parameters + """ + + # Dependency pre-check + if safe_serialization: + try: + from safetensors.torch import save_file + except ImportError: + print('If you want to use `safe_serialization`, please `pip install safetensors`') + raise + if max_shard_size is not None: + try: + from huggingface_hub import split_torch_state_dict_into_shards + except ImportError: + print('If you want to use `max_shard_size`, please `pip install huggingface_hub`') + raise + + # Convert zero checkpoint to state_dict + state_dict = get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir, + tag, + exclude_frozen_parameters, + lazy_mode=True) + + # Shard the model if it is too big. + weights_name = "model.safetensors" if safe_serialization else "pytorch_model.bin" + if max_shard_size is not None: + filename_pattern = weights_name.replace(".bin", "{suffix}.bin").replace(".safetensors", "{suffix}.safetensors") + # an memory-efficient approach for sharding + empty_state_dict = to_torch_tensor(state_dict, return_empty_tensor=True) + state_dict_split = split_torch_state_dict_into_shards(empty_state_dict, + filename_pattern=filename_pattern, + max_shard_size=max_shard_size) + else: + from collections import namedtuple + StateDictSplit = namedtuple("StateDictSplit", ["is_sharded", "filename_to_tensors"]) + state_dict_split = StateDictSplit(is_sharded=False, + filename_to_tensors={weights_name: list(state_dict.keys())}) + + # Save the model by shard + os.makedirs(output_dir, exist_ok=True) + filename_to_tensors = state_dict_split.filename_to_tensors.items() + for shard_file, tensors in tqdm(filename_to_tensors, desc="Saving checkpoint shards"): + shard_state_dict = {tensor_name: state_dict[tensor_name] for tensor_name in tensors} + shard_state_dict = to_torch_tensor(shard_state_dict) + output_path = os.path.join(output_dir, shard_file) + if safe_serialization: + save_file(shard_state_dict, output_path, metadata={"format": "pt"}) + else: + torch.save(shard_state_dict, output_path) + # release the memory of current shard + for tensor_name in list(shard_state_dict.keys()): + del state_dict[tensor_name] + del shard_state_dict[tensor_name] + del shard_state_dict + gc.collect() + + # Save index if sharded + if state_dict_split.is_sharded: + index = { + "metadata": state_dict_split.metadata, + "weight_map": state_dict_split.tensor_to_filename, + } + save_index_file = "model.safetensors.index.json" if safe_serialization else "pytorch_model.bin.index.json" + save_index_file = os.path.join(output_dir, save_index_file) + with open(save_index_file, "w", encoding="utf-8") as f: + content = json.dumps(index, indent=2, sort_keys=True) + "\n" + f.write(content) + + +def load_state_dict_from_zero_checkpoint(model, checkpoint_dir, tag=None): + """ + 1. Put the provided model to cpu + 2. Convert ZeRO 2 or 3 checkpoint into a single fp32 consolidated ``state_dict`` + 3. Load it into the provided model + + Args: + - ``model``: the model object to update + - ``checkpoint_dir``: path to the desired checkpoint folder. (one that contains the tag-folder, like ``global_step14``) + - ``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`` + + Returns: + - ``model`: modified model + + Make sure you have plenty of CPU memory available before you call this function. If you don't + have enough use the ``zero_to_fp32.py`` utility to do the conversion. You will find it + conveniently placed for you in the checkpoint folder. + + A typical usage might be :: + + from deepspeed.utils.zero_to_fp32 import load_state_dict_from_zero_checkpoint + model = load_state_dict_from_zero_checkpoint(trainer.model, checkpoint_dir) + # submit to model hub or save the model to share with others + + Note, that once this was run, the ``model`` will no longer be usable in the deepspeed context + of the same application. i.e. you will need to re-initialize the deepspeed engine, since + ``model.load_state_dict(state_dict)`` will remove all the deepspeed magic from it. + + """ + logger.info("Extracting fp32 weights") + state_dict = get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir, tag) + + logger.info("Overwriting model with fp32 weights") + model = model.cpu() + model.load_state_dict(state_dict, strict=False) + + return model + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument("checkpoint_dir", + type=str, + help="path to the desired checkpoint folder, e.g., path/checkpoint-12") + parser.add_argument("output_dir", + type=str, + help="directory to the pytorch fp32 state_dict output files" + "(e.g. path/checkpoint-12-output/)") + parser.add_argument( + "--max_shard_size", + type=str, + default="5GB", + help="The maximum size for a checkpoint before being sharded. Checkpoints shard will then be each of size" + "lower than this size. If expressed as a string, needs to be digits followed by a unit (like `5MB`" + "We default it to 5GB in order for models to be able to run easily on free-tier google colab instances" + "without CPU OOM issues.") + parser.add_argument( + "--safe_serialization", + default=False, + action='store_true', + help="Whether to save the model using `safetensors` or the traditional PyTorch way (that uses `pickle`).") + parser.add_argument("-t", + "--tag", + type=str, + default=None, + help="checkpoint tag used as a unique identifier for checkpoint. e.g., global_step1") + parser.add_argument("--exclude_frozen_parameters", action='store_true', help="exclude frozen parameters") + parser.add_argument("-d", "--debug", action='store_true', help="enable debug") + args = parser.parse_args() + + debug = args.debug + + convert_zero_checkpoint_to_fp32_state_dict(args.checkpoint_dir, + args.output_dir, + max_shard_size=args.max_shard_size, + safe_serialization=args.safe_serialization, + tag=args.tag, + exclude_frozen_parameters=args.exclude_frozen_parameters) diff --git a/qwen3/amid/checkpoint-314/README.md b/qwen3/amid/checkpoint-314/README.md new file mode 100644 index 0000000000000000000000000000000000000000..776f98d43659dd923b8c3e5649c5ae66d1f99f3e --- /dev/null +++ b/qwen3/amid/checkpoint-314/README.md @@ -0,0 +1,208 @@ +--- +base_model: Qwen/Qwen3-0.6B +library_name: peft +pipeline_tag: text-generation +tags: +- base_model:adapter:Qwen/Qwen3-0.6B +- llama-factory +- lora +- transformers +--- + +# Model Card for Model ID + + + + + +## Model Details + +### Model Description + + + + + +- **Developed by:** [More Information Needed] +- **Funded by [optional]:** [More Information Needed] +- **Shared by [optional]:** [More Information Needed] +- **Model type:** [More Information Needed] +- **Language(s) (NLP):** [More Information Needed] +- **License:** [More Information Needed] +- **Finetuned from model [optional]:** [More Information Needed] + +### Model Sources [optional] + + + +- **Repository:** [More Information Needed] +- **Paper [optional]:** [More Information Needed] +- **Demo [optional]:** [More Information Needed] + +## Uses + + + +### Direct Use + + + +[More Information Needed] + +### Downstream Use [optional] + + + +[More Information Needed] + +### Out-of-Scope Use + + + +[More Information Needed] + +## Bias, Risks, and Limitations + + + +[More Information Needed] + +### Recommendations + + + +Users (both direct and downstream) should be made aware of the risks, biases and limitations of the model. More information needed for further recommendations. + +## How to Get Started with the Model + +Use the code below to get started with the model. + +[More Information Needed] + +## Training Details + +### Training Data + + + +[More Information Needed] + +### Training Procedure + + + +#### Preprocessing [optional] + +[More Information Needed] + + +#### Training Hyperparameters + +- **Training regime:** [More Information Needed] + +#### Speeds, Sizes, Times [optional] + + + +[More Information Needed] + +## Evaluation + + + +### Testing Data, Factors & Metrics + +#### Testing Data + + + +[More Information Needed] + +#### Factors + + + +[More Information Needed] + +#### Metrics + + + +[More Information Needed] + +### Results + +[More Information Needed] + +#### Summary + + + +## Model Examination [optional] + + + +[More Information Needed] + +## Environmental Impact + + + +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). + +- **Hardware Type:** [More Information Needed] +- **Hours used:** [More Information Needed] +- **Cloud Provider:** [More Information Needed] +- **Compute Region:** [More Information Needed] +- **Carbon Emitted:** [More Information Needed] + +## Technical Specifications [optional] + +### Model Architecture and Objective + +[More Information Needed] + +### Compute Infrastructure + +[More Information Needed] + +#### Hardware + +[More Information Needed] + +#### Software + +[More Information Needed] + +## Citation [optional] + + + +**BibTeX:** + +[More Information Needed] + +**APA:** + +[More Information Needed] + +## Glossary [optional] + + + +[More Information Needed] + +## More Information [optional] + +[More Information Needed] + +## Model Card Authors [optional] + +[More Information Needed] + +## Model Card Contact + +[More Information Needed] +### Framework versions + +- PEFT 0.18.1 \ No newline at end of file diff --git a/qwen3/amid/checkpoint-314/adapter_config.json b/qwen3/amid/checkpoint-314/adapter_config.json new file mode 100644 index 0000000000000000000000000000000000000000..16362f47190537658d6b04519de786417a5f6c2f --- /dev/null +++ b/qwen3/amid/checkpoint-314/adapter_config.json @@ -0,0 +1,46 @@ +{ + "alora_invocation_tokens": null, + "alpha_pattern": {}, + "arrow_config": null, + "auto_mapping": null, + "base_model_name_or_path": "Qwen/Qwen3-0.6B", + "bias": "none", + "corda_config": null, + "ensure_weight_tying": false, + "eva_config": null, + "exclude_modules": null, + "fan_in_fan_out": false, + "inference_mode": true, + "init_lora_weights": true, + "layer_replication": null, + "layers_pattern": null, + "layers_to_transform": null, + "loftq_config": {}, + "lora_alpha": 64, + "lora_bias": false, + "lora_dropout": 0.1, + "megatron_config": null, + "megatron_core": "megatron.core", + "modules_to_save": null, + "peft_type": "LORA", + "peft_version": "0.18.1", + "qalora_group_size": 16, + "r": 32, + "rank_pattern": {}, + "revision": null, + "target_modules": [ + "v_proj", + "q_proj", + "o_proj", + "gate_proj", + "up_proj", + "k_proj", + "down_proj" + ], + "target_parameters": null, + "task_type": "CAUSAL_LM", + "trainable_token_indices": null, + "use_dora": false, + "use_qalora": false, + "use_rslora": false +} \ No newline at end of file diff --git a/qwen3/amid/checkpoint-314/adapter_model.safetensors b/qwen3/amid/checkpoint-314/adapter_model.safetensors new file mode 100644 index 0000000000000000000000000000000000000000..b23a97434be3be41e630afe1a0af9e491893d213 --- /dev/null +++ b/qwen3/amid/checkpoint-314/adapter_model.safetensors @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:819b56a96acbcec984ed0fb2f70a3c64d727524acc5ee849ced515dec088b2d5 +size 40422560 diff --git a/qwen3/amid/checkpoint-314/chat_template.jinja b/qwen3/amid/checkpoint-314/chat_template.jinja new file mode 100644 index 0000000000000000000000000000000000000000..01be9b307daa2d425f7c168c9fb145a286e0afb4 --- /dev/null +++ b/qwen3/amid/checkpoint-314/chat_template.jinja @@ -0,0 +1,89 @@ +{%- if tools %} + {{- '<|im_start|>system\n' }} + {%- if messages[0].role == 'system' %} + {{- messages[0].content + '\n\n' }} + {%- endif %} + {{- "# Tools\n\nYou may call one or more functions to assist with the user query.\n\nYou are provided with function signatures within XML tags:\n" }} + {%- for tool in tools %} + {{- "\n" }} + {{- tool | tojson }} + {%- endfor %} + {{- "\n\n\nFor each function call, return a json object with function name and arguments within XML tags:\n\n{\"name\": , \"arguments\": }\n<|im_end|>\n" }} +{%- else %} + {%- if messages[0].role == 'system' %} + {{- '<|im_start|>system\n' + messages[0].content + '<|im_end|>\n' }} + {%- endif %} +{%- endif %} +{%- set ns = namespace(multi_step_tool=true, last_query_index=messages|length - 1) %} +{%- for message in messages[::-1] %} + {%- set index = (messages|length - 1) - loop.index0 %} + {%- if ns.multi_step_tool and message.role == "user" and message.content is string and not(message.content.startswith('') and message.content.endswith('')) %} + {%- set ns.multi_step_tool = false %} + {%- set ns.last_query_index = index %} + {%- endif %} +{%- endfor %} +{%- for message in messages %} + {%- if message.content is string %} + {%- set content = message.content %} + {%- else %} + {%- set content = '' %} + {%- endif %} + {%- if (message.role == "user") or (message.role == "system" and not loop.first) %} + {{- '<|im_start|>' + message.role + '\n' + content + '<|im_end|>' + '\n' }} + {%- elif message.role == "assistant" %} + {%- set reasoning_content = '' %} + {%- if message.reasoning_content is string %} + {%- set reasoning_content = message.reasoning_content %} + {%- else %} + {%- if '' in content %} + {%- set reasoning_content = content.split('')[0].rstrip('\n').split('')[-1].lstrip('\n') %} + {%- set content = content.split('')[-1].lstrip('\n') %} + {%- endif %} + {%- endif %} + {%- if loop.index0 > ns.last_query_index %} + {%- if loop.last or (not loop.last and reasoning_content) %} + {{- '<|im_start|>' + message.role + '\n\n' + reasoning_content.strip('\n') + '\n\n\n' + content.lstrip('\n') }} + {%- else %} + {{- '<|im_start|>' + message.role + '\n' + content }} + {%- endif %} + {%- else %} + {{- '<|im_start|>' + message.role + '\n' + content }} + {%- endif %} + {%- if message.tool_calls %} + {%- for tool_call in message.tool_calls %} + {%- if (loop.first and content) or (not loop.first) %} + {{- '\n' }} + {%- endif %} + {%- if tool_call.function %} + {%- set tool_call = tool_call.function %} + {%- endif %} + {{- '\n{"name": "' }} + {{- tool_call.name }} + {{- '", "arguments": ' }} + {%- if tool_call.arguments is string %} + {{- tool_call.arguments }} + {%- else %} + {{- tool_call.arguments | tojson }} + {%- endif %} + {{- '}\n' }} + {%- endfor %} + {%- endif %} + {{- '<|im_end|>\n' }} + {%- elif message.role == "tool" %} + {%- if loop.first or (messages[loop.index0 - 1].role != "tool") %} + {{- '<|im_start|>user' }} + {%- endif %} + {{- '\n\n' }} + {{- content }} + {{- '\n' }} + {%- if loop.last or (messages[loop.index0 + 1].role != "tool") %} + {{- '<|im_end|>\n' }} + {%- endif %} + {%- endif %} +{%- endfor %} +{%- if add_generation_prompt %} + {{- '<|im_start|>assistant\n' }} + {%- if enable_thinking is defined and enable_thinking is false %} + {{- '\n\n\n\n' }} + {%- endif %} +{%- endif %} \ No newline at end of file diff --git a/qwen3/amid/checkpoint-314/global_step314/bf16_zero_pp_rank_0_mp_rank_00_optim_states.pt b/qwen3/amid/checkpoint-314/global_step314/bf16_zero_pp_rank_0_mp_rank_00_optim_states.pt new file mode 100644 index 0000000000000000000000000000000000000000..672fc2344ac3fce9a37b71054471c9f755cb4e3e --- /dev/null +++ b/qwen3/amid/checkpoint-314/global_step314/bf16_zero_pp_rank_0_mp_rank_00_optim_states.pt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3cf04e8382c2e8daba7ce0547f28dc0bba6cbd2ab62fda8b602564525f4b12c3 +size 121135557 diff --git a/qwen3/amid/checkpoint-314/global_step314/bf16_zero_pp_rank_1_mp_rank_00_optim_states.pt b/qwen3/amid/checkpoint-314/global_step314/bf16_zero_pp_rank_1_mp_rank_00_optim_states.pt new file mode 100644 index 0000000000000000000000000000000000000000..29a56298d21a5c7c0d6a4d0c4c44c688439cfd2e --- /dev/null +++ b/qwen3/amid/checkpoint-314/global_step314/bf16_zero_pp_rank_1_mp_rank_00_optim_states.pt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:80b1a0a2b5fa241dbf640d8ef1bb61ffe49a12a3719b2f5832ef3ade0f0444c1 +size 121135749 diff --git a/qwen3/amid/checkpoint-314/global_step314/mp_rank_00_model_states.pt b/qwen3/amid/checkpoint-314/global_step314/mp_rank_00_model_states.pt new file mode 100644 index 0000000000000000000000000000000000000000..92f5c2d640fd5581bdd0addfc56693fca2bfaad8 --- /dev/null +++ b/qwen3/amid/checkpoint-314/global_step314/mp_rank_00_model_states.pt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:51f7326388d5f9abc2bd8ef5dc008c578b2cf58cd5a1b02c8cb29ce1608c1d2b +size 351841765 diff --git a/qwen3/amid/checkpoint-314/latest b/qwen3/amid/checkpoint-314/latest new file mode 100644 index 0000000000000000000000000000000000000000..a9786513b1a514db2c3a9da7408844635663d55d --- /dev/null +++ b/qwen3/amid/checkpoint-314/latest @@ -0,0 +1 @@ +global_step314 \ No newline at end of file diff --git a/qwen3/amid/checkpoint-314/rng_state_0.pth b/qwen3/amid/checkpoint-314/rng_state_0.pth new file mode 100644 index 0000000000000000000000000000000000000000..c83b1c0fbf28c44631daf9c84d4dca2490a24c36 --- /dev/null +++ b/qwen3/amid/checkpoint-314/rng_state_0.pth @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fdba92889c38478a7a838b8eb355ab882c464bbba5c4d3c73edec3f82d60d0a2 +size 14917 diff --git a/qwen3/amid/checkpoint-314/rng_state_1.pth b/qwen3/amid/checkpoint-314/rng_state_1.pth new file mode 100644 index 0000000000000000000000000000000000000000..9d3d426bd9b5bf50e3a60467650048b9c0db604d --- /dev/null +++ b/qwen3/amid/checkpoint-314/rng_state_1.pth @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e89a8da6898755602708e3be195153442a313c7b82548f2de733720343c1812e +size 14917 diff --git a/qwen3/amid/checkpoint-314/scheduler.pt b/qwen3/amid/checkpoint-314/scheduler.pt new file mode 100644 index 0000000000000000000000000000000000000000..a3cb460802cda03bf0833a98a6f1428a3fd4f585 --- /dev/null +++ b/qwen3/amid/checkpoint-314/scheduler.pt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:17e254b5642bb75983fd5105bec79b35376cfbc99d29702287668b8767d46149 +size 1465 diff --git a/qwen3/amid/checkpoint-314/tokenizer.json b/qwen3/amid/checkpoint-314/tokenizer.json new file mode 100644 index 0000000000000000000000000000000000000000..c7afbed2efcdf019f88ab0572ec29d3bf595dfe2 --- /dev/null +++ b/qwen3/amid/checkpoint-314/tokenizer.json @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:be75606093db2094d7cd20f3c2f385c212750648bd6ea4fb2bf507a6a4c55506 +size 11422650 diff --git a/qwen3/amid/checkpoint-314/tokenizer_config.json b/qwen3/amid/checkpoint-314/tokenizer_config.json new file mode 100644 index 0000000000000000000000000000000000000000..6623da03457d79d2cd4af9557e9f31407cdb835c --- /dev/null +++ b/qwen3/amid/checkpoint-314/tokenizer_config.json @@ -0,0 +1,31 @@ +{ + "add_prefix_space": false, + "backend": "tokenizers", + "bos_token": null, + "clean_up_tokenization_spaces": false, + "eos_token": "<|im_end|>", + "errors": "replace", + "extra_special_tokens": [ + "<|im_start|>", + "<|im_end|>", + "<|object_ref_start|>", + "<|object_ref_end|>", + "<|box_start|>", + "<|box_end|>", + "<|quad_start|>", + "<|quad_end|>", + "<|vision_start|>", + "<|vision_end|>", + "<|vision_pad|>", + "<|image_pad|>", + "<|video_pad|>" + ], + "is_local": false, + "local_files_only": false, + "model_max_length": 131072, + "pad_token": "<|endoftext|>", + "padding_side": "right", + "split_special_tokens": false, + "tokenizer_class": "Qwen2Tokenizer", + "unk_token": null +} diff --git a/qwen3/amid/checkpoint-314/trainer_state.json b/qwen3/amid/checkpoint-314/trainer_state.json new file mode 100644 index 0000000000000000000000000000000000000000..eff54052fb7f9d2c53302dc45c83e4ff4abee4d0 --- /dev/null +++ b/qwen3/amid/checkpoint-314/trainer_state.json @@ -0,0 +1,154 @@ +{ + "best_global_step": null, + "best_metric": null, + "best_model_checkpoint": null, + "epoch": 1.0, + "eval_steps": 500, + "global_step": 314, + "is_hyper_param_search": false, + "is_local_process_zero": true, + "is_world_process_zero": true, + "log_history": [ + { + "epoch": 0.06382130035899482, + "grad_norm": 0.38384687900543213, + "learning_rate": 9.996390385474569e-05, + "loss": 0.27438180446624755, + "step": 20 + }, + { + "epoch": 0.12764260071798963, + "grad_norm": 0.38263317942619324, + "learning_rate": 9.984797509888031e-05, + "loss": 0.13717052936553956, + "step": 40 + }, + { + "epoch": 0.19146390107698444, + "grad_norm": 0.08620006591081619, + "learning_rate": 9.965229938050925e-05, + "loss": 0.13135391473770142, + "step": 60 + }, + { + "epoch": 0.25528520143597927, + "grad_norm": 0.15773959457874298, + "learning_rate": 9.937719005663432e-05, + "loss": 0.1076702356338501, + "step": 80 + }, + { + "epoch": 0.3191065017949741, + "grad_norm": 0.22962816059589386, + "learning_rate": 9.902308769000724e-05, + "loss": 0.08698999881744385, + "step": 100 + }, + { + "epoch": 0.3829278021539689, + "grad_norm": 0.12232966721057892, + "learning_rate": 9.859055934360789e-05, + "loss": 0.1128507375717163, + "step": 120 + }, + { + "epoch": 0.4467491025129637, + "grad_norm": 0.15597161650657654, + "learning_rate": 9.808029767254437e-05, + "loss": 0.1277535080909729, + "step": 140 + }, + { + "epoch": 0.5105704028719585, + "grad_norm": 0.7329031825065613, + "learning_rate": 9.749311981482817e-05, + "loss": 0.08885469436645507, + "step": 160 + }, + { + "epoch": 0.5743917032309533, + "grad_norm": 0.45483648777008057, + "learning_rate": 9.682996608280154e-05, + "loss": 0.07881734371185303, + "step": 180 + }, + { + "epoch": 0.6382130035899481, + "grad_norm": 0.16407009959220886, + "learning_rate": 9.609189845731207e-05, + "loss": 0.06113555431365967, + "step": 200 + }, + { + "epoch": 0.702034303948943, + "grad_norm": 0.07238732278347015, + "learning_rate": 9.52800988870462e-05, + "loss": 0.06768973469734192, + "step": 220 + }, + { + "epoch": 0.7658556043079378, + "grad_norm": 0.4741341471672058, + "learning_rate": 9.439586739574513e-05, + "loss": 0.04917148947715759, + "step": 240 + }, + { + "epoch": 0.8296769046669326, + "grad_norm": 0.36410900950431824, + "learning_rate": 9.344062000033414e-05, + "loss": 0.010153122991323472, + "step": 260 + }, + { + "epoch": 0.8934982050259274, + "grad_norm": 0.11222824454307556, + "learning_rate": 9.241588644329919e-05, + "loss": 0.00552816241979599, + "step": 280 + }, + { + "epoch": 0.9573195053849222, + "grad_norm": 0.47910866141319275, + "learning_rate": 9.132330774294252e-05, + "loss": 0.006760746240615845, + "step": 300 + }, + { + "epoch": 1.0, + "eval_generator_count": 1712.0, + "eval_generator_exact_match": 87.3832, + "eval_generator_rouge1": 99.2069, + "eval_generator_rouge2": 98.8793, + "eval_generator_rougeL": 98.7553, + "eval_loss": 0.012839075177907944, + "eval_runtime": 592.0147, + "eval_samples_per_second": 5.767, + "eval_selector_accuracy": 90.1869, + "eval_selector_count": 1712.0, + "eval_steps_per_second": 0.181, + "step": 314 + } + ], + "logging_steps": 20, + "max_steps": 1570, + "num_input_tokens_seen": 0, + "num_train_epochs": 5, + "save_steps": 500, + "stateful_callbacks": { + "TrainerControl": { + "args": { + "should_epoch_stop": false, + "should_evaluate": false, + "should_log": false, + "should_save": true, + "should_training_stop": false + }, + "attributes": {} + } + }, + "total_flos": 1.172842003562496e+16, + "train_batch_size": 2, + "trial_name": null, + "trial_params": null +} diff --git a/qwen3/amid/checkpoint-314/training_args.bin b/qwen3/amid/checkpoint-314/training_args.bin new file mode 100644 index 0000000000000000000000000000000000000000..571568fd8ab61d629f2a731739ee4c9e1309cca4 --- /dev/null +++ b/qwen3/amid/checkpoint-314/training_args.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e67133ff7a80f6f166c03bd5f62d9c580548b0f6840a1ce3891dee623991e47a +size 7185 diff --git a/qwen3/amid/checkpoint-314/zero_to_fp32.py b/qwen3/amid/checkpoint-314/zero_to_fp32.py new file mode 100644 index 0000000000000000000000000000000000000000..f40f1f0acbbff30e8e8d29906b56aae4e8b8a138 --- /dev/null +++ b/qwen3/amid/checkpoint-314/zero_to_fp32.py @@ -0,0 +1,790 @@ +#!/usr/bin/env python + +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: Apache-2.0 + +# DeepSpeed Team + +# This script extracts fp32 consolidated weights from a zero 1, 2 and 3 DeepSpeed checkpoints. It gets +# copied into the top level checkpoint dir, so the user can easily do the conversion at any point in +# the future. Once extracted, the weights don't require DeepSpeed and can be used in any +# application. +# +# example: +# python zero_to_fp32.py . output_dir/ +# or +# python zero_to_fp32.py . output_dir/ --safe_serialization + +import argparse +import torch +import glob +import math +import os +import re +import gc +import json +import numpy as np +from tqdm import tqdm +from collections import OrderedDict +from dataclasses import dataclass + +# while this script doesn't use deepspeed to recover data, since the checkpoints are pickled with +# DeepSpeed data structures it has to be available in the current python environment. +from deepspeed.utils import logger +from deepspeed.checkpoint.constants import (DS_VERSION, OPTIMIZER_STATE_DICT, SINGLE_PARTITION_OF_FP32_GROUPS, + FP32_FLAT_GROUPS, ZERO_STAGE, PARTITION_COUNT, PARAM_SHAPES, BUFFER_NAMES, + FROZEN_PARAM_SHAPES, FROZEN_PARAM_FRAGMENTS, AUTOEP_LAYERS_KEY, + AUTOEP_LAYERS_KEY_LEGACY, AUTOEP_ZERO3_EXPERT_STATE_FORMAT_KEY, + AUTOEP_ZERO3_PARTITIONED_EXPERT_STATE_FORMAT) + + +@dataclass +class zero_model_state: + buffers: dict() + param_shapes: dict() + shared_params: list + ds_version: int + frozen_param_shapes: dict() + frozen_param_fragments: dict() + + +debug = 0 + +# load to cpu +device = torch.device('cpu') + + +def atoi(text): + return int(text) if text.isdigit() else text + + +def natural_keys(text): + ''' + alist.sort(key=natural_keys) sorts in human order + http://nedbatchelder.com/blog/200712/human_sorting.html + (See Toothy's implementation in the comments) + ''' + return [atoi(c) for c in re.split(r'(\d+)', text)] + + +def get_model_state_file(checkpoint_dir, zero_stage): + if not os.path.isdir(checkpoint_dir): + raise FileNotFoundError(f"Directory '{checkpoint_dir}' doesn't exist") + + # there should be only one file + if zero_stage <= 2: + file = os.path.join(checkpoint_dir, "mp_rank_00_model_states.pt") + elif zero_stage == 3: + file = os.path.join(checkpoint_dir, "zero_pp_rank_0_mp_rank_00_model_states.pt") + + if not os.path.exists(file): + raise FileNotFoundError(f"can't find model states file at '{file}'") + + return file + + +def get_checkpoint_files(checkpoint_dir, glob_pattern): + # XXX: need to test that this simple glob rule works for multi-node setup too + ckpt_files = sorted(glob.glob(os.path.join(checkpoint_dir, glob_pattern)), key=natural_keys) + + if len(ckpt_files) == 0: + raise FileNotFoundError(f"can't find {glob_pattern} files in directory '{checkpoint_dir}'") + + return ckpt_files + + +def get_optim_files(checkpoint_dir): + return get_checkpoint_files(checkpoint_dir, "*_optim_states.pt") + + +def get_model_state_files(checkpoint_dir): + return get_checkpoint_files(checkpoint_dir, "*_model_states.pt") + + +def _has_autoep_zero3_partitioned_metadata(state_dict): + autoep_layers = state_dict.get(AUTOEP_LAYERS_KEY) + if autoep_layers is None: + autoep_layers = state_dict.get(AUTOEP_LAYERS_KEY_LEGACY) + if not isinstance(autoep_layers, list): + return False + return any( + isinstance(entry, dict) + and entry.get(AUTOEP_ZERO3_EXPERT_STATE_FORMAT_KEY) == AUTOEP_ZERO3_PARTITIONED_EXPERT_STATE_FORMAT + for entry in autoep_layers) + + +def _raise_if_autoep_zero3_partitioned_state(state_dict): + if _has_autoep_zero3_partitioned_metadata(state_dict): + raise NotImplementedError("zero_to_fp32 does not support AutoEP ZeRO-3 partition-native checkpoints. " + "AutoEP expert parameters are partitioned over expert replica groups, so " + "global data-parallel consolidation would produce incomplete expert tensors. " + "Use ds_to_universal.py for expert-aware conversion.") + + +def _raise_if_autoep_zero3_partitioned_checkpoint(model_files): + for file in model_files: + state_dict = torch.load(file, map_location=device, weights_only=False) + _raise_if_autoep_zero3_partitioned_state(state_dict) + + +def parse_model_states(files): + zero_model_states = [] + for file in files: + state_dict = torch.load(file, map_location=device, weights_only=False) + _raise_if_autoep_zero3_partitioned_state(state_dict) + + if BUFFER_NAMES not in state_dict: + raise ValueError(f"{file} is not a model state checkpoint") + buffer_names = state_dict[BUFFER_NAMES] + if debug: + print("Found buffers:", buffer_names) + + # recover just the buffers while restoring them to fp32 if they were saved in fp16 + buffers = {k: v.float() for k, v in state_dict["module"].items() if k in buffer_names} + param_shapes = state_dict[PARAM_SHAPES] + + # collect parameters that are included in param_shapes + param_names = [] + for s in param_shapes: + for name in s.keys(): + param_names.append(name) + + # update with frozen parameters + frozen_param_shapes = state_dict.get(FROZEN_PARAM_SHAPES, None) + if frozen_param_shapes is not None: + if debug: + print(f"Found frozen_param_shapes: {frozen_param_shapes}") + param_names += list(frozen_param_shapes.keys()) + + # handle shared params + shared_params = [[k, v] for k, v in state_dict["shared_params"].items()] + + ds_version = state_dict.get(DS_VERSION, None) + + frozen_param_fragments = state_dict.get(FROZEN_PARAM_FRAGMENTS, None) + + z_model_state = zero_model_state(buffers=buffers, + param_shapes=param_shapes, + shared_params=shared_params, + ds_version=ds_version, + frozen_param_shapes=frozen_param_shapes, + frozen_param_fragments=frozen_param_fragments) + zero_model_states.append(z_model_state) + + return zero_model_states + + +def parse_optim_states(files, ds_checkpoint_dir): + total_files = len(files) + state_dicts = [] + for f in tqdm(files, desc='Loading checkpoint shards'): + state_dict = torch.load(f, map_location=device, mmap=True, weights_only=False) + # immediately discard the potentially huge 2 optimizer states as we only care for fp32 master weights + # and also handle the case where it was already removed by another helper script + state_dict["optimizer_state_dict"].pop("optimizer_state_dict", None) + state_dicts.append(state_dict) + + if ZERO_STAGE not in state_dicts[0][OPTIMIZER_STATE_DICT]: + raise ValueError(f"{files[0]} is not a zero checkpoint") + zero_stage = state_dicts[0][OPTIMIZER_STATE_DICT][ZERO_STAGE] + world_size = state_dicts[0][OPTIMIZER_STATE_DICT][PARTITION_COUNT] + + # For ZeRO-2 each param group can have different partition_count as data parallelism for expert + # parameters can be different from data parallelism for non-expert parameters. So we can just + # use the max of the partition_count to get the dp world_size. + + if type(world_size) is list: + world_size = max(world_size) + + if world_size != total_files: + raise ValueError( + f"Expected {world_size} of '*_optim_states.pt' under '{ds_checkpoint_dir}' but found {total_files} files. " + "Possibly due to an overwrite of an old checkpoint, or a checkpoint didn't get saved by one or more processes." + ) + + # the groups are named differently in each stage + if zero_stage <= 2: + fp32_groups_key = SINGLE_PARTITION_OF_FP32_GROUPS + elif zero_stage == 3: + fp32_groups_key = FP32_FLAT_GROUPS + else: + raise ValueError(f"unknown zero stage {zero_stage}") + + fp32_flat_groups = [state_dicts[i][OPTIMIZER_STATE_DICT][fp32_groups_key] for i in range(len(state_dicts))] + return zero_stage, world_size, fp32_flat_groups + + +def _get_fp32_state_dict_from_zero_checkpoint(ds_checkpoint_dir, exclude_frozen_parameters): + """ + Returns fp32 state_dict reconstructed from ds checkpoint + + Args: + - ``ds_checkpoint_dir``: path to the deepspeed checkpoint folder (where the optimizer files are) + + """ + print(f"Processing zero checkpoint '{ds_checkpoint_dir}'") + + # parse_model_states rejects AutoEP ZeRO-3 partition-native checkpoints + # before the expensive optimizer-shard load below. + model_files = get_model_state_files(ds_checkpoint_dir) + zero_model_states = parse_model_states(model_files) + print(f'Parsing checkpoint created by deepspeed=={zero_model_states[0].ds_version}') + + optim_files = get_optim_files(ds_checkpoint_dir) + zero_stage, world_size, fp32_flat_groups = parse_optim_states(optim_files, ds_checkpoint_dir) + print(f"Detected checkpoint of type zero stage {zero_stage}, world_size: {world_size}") + + if zero_stage <= 2: + return _get_fp32_state_dict_from_zero2_checkpoint(world_size, fp32_flat_groups, zero_model_states, + exclude_frozen_parameters) + elif zero_stage == 3: + return _get_fp32_state_dict_from_zero3_checkpoint(world_size, fp32_flat_groups, zero_model_states, + exclude_frozen_parameters) + + +def _zero2_merge_frozen_params(state_dict, zero_model_states): + if zero_model_states[0].frozen_param_shapes is None or len(zero_model_states[0].frozen_param_shapes) == 0: + return + + frozen_param_shapes = zero_model_states[0].frozen_param_shapes + frozen_param_fragments = zero_model_states[0].frozen_param_fragments + + if debug: + num_elem = sum(s.numel() for s in frozen_param_shapes.values()) + print(f'rank 0: {FROZEN_PARAM_SHAPES}.numel = {num_elem}') + + wanted_params = len(frozen_param_shapes) + wanted_numel = sum(s.numel() for s in frozen_param_shapes.values()) + avail_numel = sum([p.numel() for p in frozen_param_fragments.values()]) + print(f'Frozen params: Have {avail_numel} numels to process.') + print(f'Frozen params: Need {wanted_numel} numels in {wanted_params} params') + + total_params = 0 + total_numel = 0 + for name, shape in frozen_param_shapes.items(): + total_params += 1 + unpartitioned_numel = shape.numel() + total_numel += unpartitioned_numel + + state_dict[name] = frozen_param_fragments[name] + + if debug: + print(f"{name} full shape: {shape} unpartitioned numel {unpartitioned_numel} ") + + print(f"Reconstructed Frozen fp32 state dict with {total_params} params {total_numel} elements") + + +def _has_callable(obj, fn): + attr = getattr(obj, fn, None) + return callable(attr) + + +def _zero2_merge_trainable_params(state_dict, world_size, fp32_flat_groups, zero_model_states): + param_shapes = zero_model_states[0].param_shapes + + # Reconstruction protocol: + # + # XXX: document this + + if debug: + for i in range(world_size): + for j in range(len(fp32_flat_groups[0])): + print(f"{FP32_FLAT_GROUPS}[{i}][{j}].shape={fp32_flat_groups[i][j].shape}") + + # XXX: memory usage doubles here (zero2) + num_param_groups = len(fp32_flat_groups[0]) + merged_single_partition_of_fp32_groups = [] + for i in range(num_param_groups): + merged_partitions = [sd[i] for sd in fp32_flat_groups] + full_single_fp32_vector = torch.cat(merged_partitions, 0) + merged_single_partition_of_fp32_groups.append(full_single_fp32_vector) + avail_numel = sum( + [full_single_fp32_vector.numel() for full_single_fp32_vector in merged_single_partition_of_fp32_groups]) + + if debug: + wanted_params = sum([len(shapes) for shapes in param_shapes]) + wanted_numel = sum([sum(shape.numel() for shape in shapes.values()) for shapes in param_shapes]) + # not asserting if there is a mismatch due to possible padding + print(f"Have {avail_numel} numels to process.") + print(f"Need {wanted_numel} numels in {wanted_params} params.") + + # params + # XXX: for huge models that can't fit into the host's RAM we will have to recode this to support + # out-of-core computing solution + total_numel = 0 + total_params = 0 + for shapes, full_single_fp32_vector in zip(param_shapes, merged_single_partition_of_fp32_groups): + offset = 0 + avail_numel = full_single_fp32_vector.numel() + for name, shape in shapes.items(): + + unpartitioned_numel = shape.numel() if _has_callable(shape, 'numel') else math.prod(shape) + total_numel += unpartitioned_numel + total_params += 1 + + if debug: + print(f"{name} full shape: {shape} unpartitioned numel {unpartitioned_numel} ") + state_dict[name] = full_single_fp32_vector.narrow(0, offset, unpartitioned_numel).view(shape) + offset += unpartitioned_numel + + # Z2 started to align to 2*world_size to improve nccl performance. Therefore both offset and + # avail_numel can differ by anywhere between 0..2*world_size. Due to two unrelated complex + # paddings performed in the code it's almost impossible to predict the exact numbers w/o the + # live optimizer object, so we are checking that the numbers are within the right range + align_to = 2 * world_size + + def zero2_align(x): + return align_to * math.ceil(x / align_to) + + if debug: + print(f"original offset={offset}, avail_numel={avail_numel}") + + offset = zero2_align(offset) + avail_numel = zero2_align(avail_numel) + + if debug: + print(f"aligned offset={offset}, avail_numel={avail_numel}") + + # Sanity check + if offset != avail_numel: + raise ValueError(f"consumed {offset} numels out of {avail_numel} - something is wrong") + + print(f"Reconstructed fp32 state dict with {total_params} params {total_numel} elements") + + +def _get_fp32_state_dict_from_zero2_checkpoint(world_size, fp32_flat_groups, zero_model_states, + exclude_frozen_parameters): + state_dict = OrderedDict() + + # buffers + buffers = zero_model_states[0].buffers + state_dict.update(buffers) + if debug: + print(f"added {len(buffers)} buffers") + + if not exclude_frozen_parameters: + _zero2_merge_frozen_params(state_dict, zero_model_states) + + _zero2_merge_trainable_params(state_dict, world_size, fp32_flat_groups, zero_model_states) + + # recover shared parameters + for pair in zero_model_states[0].shared_params: + if pair[1] in state_dict: + state_dict[pair[0]] = state_dict[pair[1]] + + return state_dict + + +def zero3_partitioned_param_info(unpartitioned_numel, world_size): + remainder = unpartitioned_numel % world_size + padding_numel = (world_size - remainder) if remainder else 0 + partitioned_numel = math.ceil(unpartitioned_numel / world_size) + return partitioned_numel, padding_numel + + +def _zero3_merge_frozen_params(state_dict, world_size, zero_model_states): + if zero_model_states[0].frozen_param_shapes is None or len(zero_model_states[0].frozen_param_shapes) == 0: + return + + if debug: + for i in range(world_size): + num_elem = sum(s.numel() for s in zero_model_states[i].frozen_param_fragments.values()) + print(f'rank {i}: {FROZEN_PARAM_SHAPES}.numel = {num_elem}') + + frozen_param_shapes = zero_model_states[0].frozen_param_shapes + wanted_params = len(frozen_param_shapes) + wanted_numel = sum(s.numel() for s in frozen_param_shapes.values()) + avail_numel = sum([p.numel() for p in zero_model_states[0].frozen_param_fragments.values()]) * world_size + print(f'Frozen params: Have {avail_numel} numels to process.') + print(f'Frozen params: Need {wanted_numel} numels in {wanted_params} params') + + total_params = 0 + total_numel = 0 + for name, shape in zero_model_states[0].frozen_param_shapes.items(): + total_params += 1 + unpartitioned_numel = shape.numel() + total_numel += unpartitioned_numel + + param_frags = tuple(model_state.frozen_param_fragments[name] for model_state in zero_model_states) + state_dict[name] = torch.cat(param_frags, 0).narrow(0, 0, unpartitioned_numel).view(shape) + + partitioned_numel, partitioned_padding_numel = zero3_partitioned_param_info(unpartitioned_numel, world_size) + + if debug: + print( + f"Frozen params: {total_params} {name} full shape: {shape} partition0 numel={partitioned_numel} partitioned_padding_numel={partitioned_padding_numel}" + ) + + print(f"Reconstructed Frozen fp32 state dict with {total_params} params {total_numel} elements") + + +class GatheredTensor: + """ + A pseudo tensor that collects partitioned weights. + It is more memory efficient when there are multiple groups. + """ + + def __init__(self, flat_groups, flat_groups_offset, offset, partitioned_numel, shape): + self.flat_groups = flat_groups + self.flat_groups_offset = flat_groups_offset + self.offset = offset + self.partitioned_numel = partitioned_numel + self.shape = shape + self.dtype = self.flat_groups[0][0].dtype + + def contiguous(self): + """ + Merge partitioned weights from flat_groups into a single tensor. + """ + end_idx = self.offset + self.partitioned_numel + world_size = len(self.flat_groups) + pad_flat_param_chunks = [] + + for rank_i in range(world_size): + # for each rank, we need to collect weights from related group/groups + flat_groups_at_rank_i = self.flat_groups[rank_i] + start_group_id = None + end_group_id = None + for group_id in range(len(self.flat_groups_offset)): + if self.flat_groups_offset[group_id] <= self.offset < self.flat_groups_offset[group_id + 1]: + start_group_id = group_id + if self.flat_groups_offset[group_id] < end_idx <= self.flat_groups_offset[group_id + 1]: + end_group_id = group_id + break + # collect weights from related group/groups + for group_id in range(start_group_id, end_group_id + 1): + flat_tensor = flat_groups_at_rank_i[group_id] + start_offset = self.offset - self.flat_groups_offset[group_id] + end_offset = min(end_idx, self.flat_groups_offset[group_id + 1]) - self.flat_groups_offset[group_id] + pad_flat_param_chunks.append(flat_tensor[start_offset:end_offset]) + + # collect weights from all ranks + pad_flat_param = torch.cat(pad_flat_param_chunks, dim=0) + param = pad_flat_param[:self.shape.numel()].view(self.shape).contiguous() + return param + + +def _zero3_merge_trainable_params(state_dict, world_size, fp32_flat_groups, zero_model_states): + param_shapes = zero_model_states[0].param_shapes + avail_numel = sum([flat_group.numel() for flat_group in fp32_flat_groups[0]]) * world_size + + # Reconstruction protocol: For zero3 we need to zip the partitions together at boundary of each + # param, re-consolidating each param, while dealing with padding if any + + # merge list of dicts, preserving order + param_shapes = {k: v for d in param_shapes for k, v in d.items()} + + if debug: + for i in range(world_size): + print(f"{FP32_FLAT_GROUPS}[{i}].shape={fp32_flat_groups[i].shape}") + + wanted_params = len(param_shapes) + wanted_numel = sum(shape.numel() for shape in param_shapes.values()) + # not asserting if there is a mismatch due to possible padding + avail_numel = fp32_flat_groups[0].numel() * world_size + print(f"Trainable params: Have {avail_numel} numels to process.") + print(f"Trainable params: Need {wanted_numel} numels in {wanted_params} params.") + + # params + # XXX: for huge models that can't fit into the host's RAM we will have to recode this to support + # out-of-core computing solution + offset = 0 + total_numel = 0 + total_params = 0 + flat_groups_offset = [0] + list(np.cumsum([flat_tensor.numel() for flat_tensor in fp32_flat_groups[0]])) + for name, shape in tqdm(param_shapes.items(), desc='Gathering sharded weights'): + unpartitioned_numel = shape.numel() + total_numel += unpartitioned_numel + total_params += 1 + partitioned_numel, partitioned_padding_numel = zero3_partitioned_param_info(unpartitioned_numel, world_size) + + if debug: + print( + f"Trainable params: {total_params} {name} full shape: {shape} partition0 numel={partitioned_numel} partitioned_padding_numel={partitioned_padding_numel}" + ) + + # memory efficient tensor + tensor = GatheredTensor(fp32_flat_groups, flat_groups_offset, offset, partitioned_numel, shape) + state_dict[name] = tensor + offset += partitioned_numel + + offset *= world_size + + # Sanity check + if offset != avail_numel: + raise ValueError(f"consumed {offset} numels out of {avail_numel} - something is wrong") + + print(f"Reconstructed Trainable fp32 state dict with {total_params} params {total_numel} elements") + + +def _get_fp32_state_dict_from_zero3_checkpoint(world_size, fp32_flat_groups, zero_model_states, + exclude_frozen_parameters): + state_dict = OrderedDict() + + # buffers + buffers = zero_model_states[0].buffers + state_dict.update(buffers) + if debug: + print(f"added {len(buffers)} buffers") + + if not exclude_frozen_parameters: + _zero3_merge_frozen_params(state_dict, world_size, zero_model_states) + + _zero3_merge_trainable_params(state_dict, world_size, fp32_flat_groups, zero_model_states) + + # recover shared parameters + for pair in zero_model_states[0].shared_params: + if pair[1] in state_dict: + state_dict[pair[0]] = state_dict[pair[1]] + + return state_dict + + +def to_torch_tensor(state_dict, return_empty_tensor=False): + """ + Convert state_dict of GatheredTensor to torch tensor + """ + torch_state_dict = {} + converted_tensors = {} + for name, tensor in state_dict.items(): + tensor_id = id(tensor) + if tensor_id in converted_tensors: # shared tensors + shared_tensor = torch_state_dict[converted_tensors[tensor_id]] + torch_state_dict[name] = shared_tensor + else: + converted_tensors[tensor_id] = name + if return_empty_tensor: + torch_state_dict[name] = torch.empty(tensor.shape, dtype=tensor.dtype) + else: + torch_state_dict[name] = tensor.contiguous() + return torch_state_dict + + +def get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir, + tag=None, + exclude_frozen_parameters=False, + lazy_mode=False): + """ + Convert ZeRO 2 or 3 checkpoint into a single fp32 consolidated state_dict that can be loaded with + ``load_state_dict()`` and used for training without DeepSpeed or shared with others, for example + via a model hub. + + Args: + - ``checkpoint_dir``: path to the desired checkpoint folder + - ``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`` + - ``exclude_frozen_parameters``: exclude frozen parameters + - ``lazy_mode``: get state_dict in lazy mode. It returns a dict of pesduo tensor instead of torch tensor, which is more memory efficient. + Convert the pesduo tensor to torch tensor by ``.contiguous()`` + + Returns: + - pytorch ``state_dict`` + + A typical usage might be :: + + from deepspeed.utils.zero_to_fp32 import get_fp32_state_dict_from_zero_checkpoint + # do the training and checkpoint saving + state_dict = get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir) # already on cpu + model = model.cpu() # move to cpu + model.load_state_dict(state_dict) + # submit to model hub or save the model to share with others + + In this example the ``model`` will no longer be usable in the deepspeed context of the same + application. i.e. you will need to re-initialize the deepspeed engine, since + ``model.load_state_dict(state_dict)`` will remove all the deepspeed magic from it. + + If you want it all done for you, use ``load_state_dict_from_zero_checkpoint`` instead. + + Note: the above usage may not work if your application doesn't have sufficient free CPU memory. + You may need to use the offline approach using the ``zero_to_fp32.py`` script that is saved with + the checkpoint. Or you can load state_dict in lazy mode :: + + from deepspeed.utils.zero_to_fp32 import get_fp32_state_dict_from_zero_checkpoint + state_dict = get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir, lazy_mode=True) # not on cpu + for name, lazy_tensor in state_dict.item(): + tensor = lazy_tensor.contiguous() # to cpu + print(name, tensor) + # del tensor to release memory if it no longer in use + """ + if tag is None: + latest_path = os.path.join(checkpoint_dir, 'latest') + if os.path.isfile(latest_path): + with open(latest_path, 'r') as fd: + tag = fd.read().strip() + else: + raise ValueError(f"Unable to find 'latest' file at {latest_path}") + + ds_checkpoint_dir = os.path.join(checkpoint_dir, tag) + + if not os.path.isdir(ds_checkpoint_dir): + raise FileNotFoundError(f"Directory '{ds_checkpoint_dir}' doesn't exist") + + state_dict = _get_fp32_state_dict_from_zero_checkpoint(ds_checkpoint_dir, exclude_frozen_parameters) + if lazy_mode: + return state_dict + else: + return to_torch_tensor(state_dict) + + +def convert_zero_checkpoint_to_fp32_state_dict(checkpoint_dir, + output_dir, + max_shard_size="5GB", + safe_serialization=False, + tag=None, + exclude_frozen_parameters=False): + """ + Convert ZeRO 2 or 3 checkpoint into a single fp32 consolidated ``state_dict`` file that can be + loaded with ``torch.load(file)`` + ``load_state_dict()`` and used for training without DeepSpeed. + + Args: + - ``checkpoint_dir``: path to the desired checkpoint folder. (one that contains the tag-folder, like ``global_step14``) + - ``output_dir``: directory to the pytorch fp32 state_dict output files + - ``max_shard_size``: the maximum size for a checkpoint before being sharded, default value is 5GB + - ``safe_serialization``: whether to save the model using `safetensors` or the traditional PyTorch way (that uses `pickle`). + - ``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`` + - ``exclude_frozen_parameters``: exclude frozen parameters + """ + + # Dependency pre-check + if safe_serialization: + try: + from safetensors.torch import save_file + except ImportError: + print('If you want to use `safe_serialization`, please `pip install safetensors`') + raise + if max_shard_size is not None: + try: + from huggingface_hub import split_torch_state_dict_into_shards + except ImportError: + print('If you want to use `max_shard_size`, please `pip install huggingface_hub`') + raise + + # Convert zero checkpoint to state_dict + state_dict = get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir, + tag, + exclude_frozen_parameters, + lazy_mode=True) + + # Shard the model if it is too big. + weights_name = "model.safetensors" if safe_serialization else "pytorch_model.bin" + if max_shard_size is not None: + filename_pattern = weights_name.replace(".bin", "{suffix}.bin").replace(".safetensors", "{suffix}.safetensors") + # an memory-efficient approach for sharding + empty_state_dict = to_torch_tensor(state_dict, return_empty_tensor=True) + state_dict_split = split_torch_state_dict_into_shards(empty_state_dict, + filename_pattern=filename_pattern, + max_shard_size=max_shard_size) + else: + from collections import namedtuple + StateDictSplit = namedtuple("StateDictSplit", ["is_sharded", "filename_to_tensors"]) + state_dict_split = StateDictSplit(is_sharded=False, + filename_to_tensors={weights_name: list(state_dict.keys())}) + + # Save the model by shard + os.makedirs(output_dir, exist_ok=True) + filename_to_tensors = state_dict_split.filename_to_tensors.items() + for shard_file, tensors in tqdm(filename_to_tensors, desc="Saving checkpoint shards"): + shard_state_dict = {tensor_name: state_dict[tensor_name] for tensor_name in tensors} + shard_state_dict = to_torch_tensor(shard_state_dict) + output_path = os.path.join(output_dir, shard_file) + if safe_serialization: + save_file(shard_state_dict, output_path, metadata={"format": "pt"}) + else: + torch.save(shard_state_dict, output_path) + # release the memory of current shard + for tensor_name in list(shard_state_dict.keys()): + del state_dict[tensor_name] + del shard_state_dict[tensor_name] + del shard_state_dict + gc.collect() + + # Save index if sharded + if state_dict_split.is_sharded: + index = { + "metadata": state_dict_split.metadata, + "weight_map": state_dict_split.tensor_to_filename, + } + save_index_file = "model.safetensors.index.json" if safe_serialization else "pytorch_model.bin.index.json" + save_index_file = os.path.join(output_dir, save_index_file) + with open(save_index_file, "w", encoding="utf-8") as f: + content = json.dumps(index, indent=2, sort_keys=True) + "\n" + f.write(content) + + +def load_state_dict_from_zero_checkpoint(model, checkpoint_dir, tag=None): + """ + 1. Put the provided model to cpu + 2. Convert ZeRO 2 or 3 checkpoint into a single fp32 consolidated ``state_dict`` + 3. Load it into the provided model + + Args: + - ``model``: the model object to update + - ``checkpoint_dir``: path to the desired checkpoint folder. (one that contains the tag-folder, like ``global_step14``) + - ``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`` + + Returns: + - ``model`: modified model + + Make sure you have plenty of CPU memory available before you call this function. If you don't + have enough use the ``zero_to_fp32.py`` utility to do the conversion. You will find it + conveniently placed for you in the checkpoint folder. + + A typical usage might be :: + + from deepspeed.utils.zero_to_fp32 import load_state_dict_from_zero_checkpoint + model = load_state_dict_from_zero_checkpoint(trainer.model, checkpoint_dir) + # submit to model hub or save the model to share with others + + Note, that once this was run, the ``model`` will no longer be usable in the deepspeed context + of the same application. i.e. you will need to re-initialize the deepspeed engine, since + ``model.load_state_dict(state_dict)`` will remove all the deepspeed magic from it. + + """ + logger.info("Extracting fp32 weights") + state_dict = get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir, tag) + + logger.info("Overwriting model with fp32 weights") + model = model.cpu() + model.load_state_dict(state_dict, strict=False) + + return model + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument("checkpoint_dir", + type=str, + help="path to the desired checkpoint folder, e.g., path/checkpoint-12") + parser.add_argument("output_dir", + type=str, + help="directory to the pytorch fp32 state_dict output files" + "(e.g. path/checkpoint-12-output/)") + parser.add_argument( + "--max_shard_size", + type=str, + default="5GB", + help="The maximum size for a checkpoint before being sharded. Checkpoints shard will then be each of size" + "lower than this size. If expressed as a string, needs to be digits followed by a unit (like `5MB`" + "We default it to 5GB in order for models to be able to run easily on free-tier google colab instances" + "without CPU OOM issues.") + parser.add_argument( + "--safe_serialization", + default=False, + action='store_true', + help="Whether to save the model using `safetensors` or the traditional PyTorch way (that uses `pickle`).") + parser.add_argument("-t", + "--tag", + type=str, + default=None, + help="checkpoint tag used as a unique identifier for checkpoint. e.g., global_step1") + parser.add_argument("--exclude_frozen_parameters", action='store_true', help="exclude frozen parameters") + parser.add_argument("-d", "--debug", action='store_true', help="enable debug") + args = parser.parse_args() + + debug = args.debug + + convert_zero_checkpoint_to_fp32_state_dict(args.checkpoint_dir, + args.output_dir, + max_shard_size=args.max_shard_size, + safe_serialization=args.safe_serialization, + tag=args.tag, + exclude_frozen_parameters=args.exclude_frozen_parameters) diff --git a/qwen3/amid/checkpoint-628/README.md b/qwen3/amid/checkpoint-628/README.md new file mode 100644 index 0000000000000000000000000000000000000000..776f98d43659dd923b8c3e5649c5ae66d1f99f3e --- /dev/null +++ b/qwen3/amid/checkpoint-628/README.md @@ -0,0 +1,208 @@ +--- +base_model: Qwen/Qwen3-0.6B +library_name: peft +pipeline_tag: text-generation +tags: +- base_model:adapter:Qwen/Qwen3-0.6B +- llama-factory +- lora +- transformers +--- + +# Model Card for Model ID + + + + + +## Model Details + +### Model Description + + + + + +- **Developed by:** [More Information Needed] +- **Funded by [optional]:** [More Information Needed] +- **Shared by [optional]:** [More Information Needed] +- **Model type:** [More Information Needed] +- **Language(s) (NLP):** [More Information Needed] +- **License:** [More Information Needed] +- **Finetuned from model [optional]:** [More Information Needed] + +### Model Sources [optional] + + + +- **Repository:** [More Information Needed] +- **Paper [optional]:** [More Information Needed] +- **Demo [optional]:** [More Information Needed] + +## Uses + + + +### Direct Use + + + +[More Information Needed] + +### Downstream Use [optional] + + + +[More Information Needed] + +### Out-of-Scope Use + + + +[More Information Needed] + +## Bias, Risks, and Limitations + + + +[More Information Needed] + +### Recommendations + + + +Users (both direct and downstream) should be made aware of the risks, biases and limitations of the model. More information needed for further recommendations. + +## How to Get Started with the Model + +Use the code below to get started with the model. + +[More Information Needed] + +## Training Details + +### Training Data + + + +[More Information Needed] + +### Training Procedure + + + +#### Preprocessing [optional] + +[More Information Needed] + + +#### Training Hyperparameters + +- **Training regime:** [More Information Needed] + +#### Speeds, Sizes, Times [optional] + + + +[More Information Needed] + +## Evaluation + + + +### Testing Data, Factors & Metrics + +#### Testing Data + + + +[More Information Needed] + +#### Factors + + + +[More Information Needed] + +#### Metrics + + + +[More Information Needed] + +### Results + +[More Information Needed] + +#### Summary + + + +## Model Examination [optional] + + + +[More Information Needed] + +## Environmental Impact + + + +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). + +- **Hardware Type:** [More Information Needed] +- **Hours used:** [More Information Needed] +- **Cloud Provider:** [More Information Needed] +- **Compute Region:** [More Information Needed] +- **Carbon Emitted:** [More Information Needed] + +## Technical Specifications [optional] + +### Model Architecture and Objective + +[More Information Needed] + +### Compute Infrastructure + +[More Information Needed] + +#### Hardware + +[More Information Needed] + +#### Software + +[More Information Needed] + +## Citation [optional] + + + +**BibTeX:** + +[More Information Needed] + +**APA:** + +[More Information Needed] + +## Glossary [optional] + + + +[More Information Needed] + +## More Information [optional] + +[More Information Needed] + +## Model Card Authors [optional] + +[More Information Needed] + +## Model Card Contact + +[More Information Needed] +### Framework versions + +- PEFT 0.18.1 \ No newline at end of file diff --git a/qwen3/amid/checkpoint-628/adapter_config.json b/qwen3/amid/checkpoint-628/adapter_config.json new file mode 100644 index 0000000000000000000000000000000000000000..16362f47190537658d6b04519de786417a5f6c2f --- /dev/null +++ b/qwen3/amid/checkpoint-628/adapter_config.json @@ -0,0 +1,46 @@ +{ + "alora_invocation_tokens": null, + "alpha_pattern": {}, + "arrow_config": null, + "auto_mapping": null, + "base_model_name_or_path": "Qwen/Qwen3-0.6B", + "bias": "none", + "corda_config": null, + "ensure_weight_tying": false, + "eva_config": null, + "exclude_modules": null, + "fan_in_fan_out": false, + "inference_mode": true, + "init_lora_weights": true, + "layer_replication": null, + "layers_pattern": null, + "layers_to_transform": null, + "loftq_config": {}, + "lora_alpha": 64, + "lora_bias": false, + "lora_dropout": 0.1, + "megatron_config": null, + "megatron_core": "megatron.core", + "modules_to_save": null, + "peft_type": "LORA", + "peft_version": "0.18.1", + "qalora_group_size": 16, + "r": 32, + "rank_pattern": {}, + "revision": null, + "target_modules": [ + "v_proj", + "q_proj", + "o_proj", + "gate_proj", + "up_proj", + "k_proj", + "down_proj" + ], + "target_parameters": null, + "task_type": "CAUSAL_LM", + "trainable_token_indices": null, + "use_dora": false, + "use_qalora": false, + "use_rslora": false +} \ No newline at end of file diff --git a/qwen3/amid/checkpoint-628/adapter_model.safetensors b/qwen3/amid/checkpoint-628/adapter_model.safetensors new file mode 100644 index 0000000000000000000000000000000000000000..eff5c2f18672c814bd1e6945688d53b0ba456d98 --- /dev/null +++ b/qwen3/amid/checkpoint-628/adapter_model.safetensors @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3c389c80927963f79f7ce42996bf58ac7aae228480a2b389697bf4ec6f1b1ca8 +size 40422560 diff --git a/qwen3/amid/checkpoint-628/chat_template.jinja b/qwen3/amid/checkpoint-628/chat_template.jinja new file mode 100644 index 0000000000000000000000000000000000000000..01be9b307daa2d425f7c168c9fb145a286e0afb4 --- /dev/null +++ b/qwen3/amid/checkpoint-628/chat_template.jinja @@ -0,0 +1,89 @@ +{%- if tools %} + {{- '<|im_start|>system\n' }} + {%- if messages[0].role == 'system' %} + {{- messages[0].content + '\n\n' }} + {%- endif %} + {{- "# Tools\n\nYou may call one or more functions to assist with the user query.\n\nYou are provided with function signatures within XML tags:\n" }} + {%- for tool in tools %} + {{- "\n" }} + {{- tool | tojson }} + {%- endfor %} + {{- "\n\n\nFor each function call, return a json object with function name and arguments within XML tags:\n\n{\"name\": , \"arguments\": }\n<|im_end|>\n" }} +{%- else %} + {%- if messages[0].role == 'system' %} + {{- '<|im_start|>system\n' + messages[0].content + '<|im_end|>\n' }} + {%- endif %} +{%- endif %} +{%- set ns = namespace(multi_step_tool=true, last_query_index=messages|length - 1) %} +{%- for message in messages[::-1] %} + {%- set index = (messages|length - 1) - loop.index0 %} + {%- if ns.multi_step_tool and message.role == "user" and message.content is string and not(message.content.startswith('') and message.content.endswith('')) %} + {%- set ns.multi_step_tool = false %} + {%- set ns.last_query_index = index %} + {%- endif %} +{%- endfor %} +{%- for message in messages %} + {%- if message.content is string %} + {%- set content = message.content %} + {%- else %} + {%- set content = '' %} + {%- endif %} + {%- if (message.role == "user") or (message.role == "system" and not loop.first) %} + {{- '<|im_start|>' + message.role + '\n' + content + '<|im_end|>' + '\n' }} + {%- elif message.role == "assistant" %} + {%- set reasoning_content = '' %} + {%- if message.reasoning_content is string %} + {%- set reasoning_content = message.reasoning_content %} + {%- else %} + {%- if '' in content %} + {%- set reasoning_content = content.split('')[0].rstrip('\n').split('')[-1].lstrip('\n') %} + {%- set content = content.split('')[-1].lstrip('\n') %} + {%- endif %} + {%- endif %} + {%- if loop.index0 > ns.last_query_index %} + {%- if loop.last or (not loop.last and reasoning_content) %} + {{- '<|im_start|>' + message.role + '\n\n' + reasoning_content.strip('\n') + '\n\n\n' + content.lstrip('\n') }} + {%- else %} + {{- '<|im_start|>' + message.role + '\n' + content }} + {%- endif %} + {%- else %} + {{- '<|im_start|>' + message.role + '\n' + content }} + {%- endif %} + {%- if message.tool_calls %} + {%- for tool_call in message.tool_calls %} + {%- if (loop.first and content) or (not loop.first) %} + {{- '\n' }} + {%- endif %} + {%- if tool_call.function %} + {%- set tool_call = tool_call.function %} + {%- endif %} + {{- '\n{"name": "' }} + {{- tool_call.name }} + {{- '", "arguments": ' }} + {%- if tool_call.arguments is string %} + {{- tool_call.arguments }} + {%- else %} + {{- tool_call.arguments | tojson }} + {%- endif %} + {{- '}\n' }} + {%- endfor %} + {%- endif %} + {{- '<|im_end|>\n' }} + {%- elif message.role == "tool" %} + {%- if loop.first or (messages[loop.index0 - 1].role != "tool") %} + {{- '<|im_start|>user' }} + {%- endif %} + {{- '\n\n' }} + {{- content }} + {{- '\n' }} + {%- if loop.last or (messages[loop.index0 + 1].role != "tool") %} + {{- '<|im_end|>\n' }} + {%- endif %} + {%- endif %} +{%- endfor %} +{%- if add_generation_prompt %} + {{- '<|im_start|>assistant\n' }} + {%- if enable_thinking is defined and enable_thinking is false %} + {{- '\n\n\n\n' }} + {%- endif %} +{%- endif %} \ No newline at end of file diff --git a/qwen3/amid/checkpoint-628/global_step628/bf16_zero_pp_rank_0_mp_rank_00_optim_states.pt b/qwen3/amid/checkpoint-628/global_step628/bf16_zero_pp_rank_0_mp_rank_00_optim_states.pt new file mode 100644 index 0000000000000000000000000000000000000000..b9fe3375336715538c345cf6a6785a3b7bb158fb --- /dev/null +++ b/qwen3/amid/checkpoint-628/global_step628/bf16_zero_pp_rank_0_mp_rank_00_optim_states.pt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4f1e23dd6dcb516558f88b2f93393cbdf049e7fd6f9856cbdf98e8bd50ef685e +size 121135557 diff --git a/qwen3/amid/checkpoint-628/global_step628/bf16_zero_pp_rank_1_mp_rank_00_optim_states.pt b/qwen3/amid/checkpoint-628/global_step628/bf16_zero_pp_rank_1_mp_rank_00_optim_states.pt new file mode 100644 index 0000000000000000000000000000000000000000..621ea987db06a11b70b35757c04bf9e7adef162f --- /dev/null +++ b/qwen3/amid/checkpoint-628/global_step628/bf16_zero_pp_rank_1_mp_rank_00_optim_states.pt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8069a1dac0872d05ac2f54e1ed805c47b45310bbcad4e7ba63e22e58906a0d11 +size 121135749 diff --git a/qwen3/amid/checkpoint-628/global_step628/mp_rank_00_model_states.pt b/qwen3/amid/checkpoint-628/global_step628/mp_rank_00_model_states.pt new file mode 100644 index 0000000000000000000000000000000000000000..605b010f654e21ee5503b6dc6402faf3910acec8 --- /dev/null +++ b/qwen3/amid/checkpoint-628/global_step628/mp_rank_00_model_states.pt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bbf2f57dcb83df3e0f068c6e0b4767c8d1ef6a5e02ce0f6b0b5ebedb4ad97c47 +size 351841765 diff --git a/qwen3/amid/checkpoint-628/latest b/qwen3/amid/checkpoint-628/latest new file mode 100644 index 0000000000000000000000000000000000000000..af055c3db05dcb2af541005f22308dbd946aba65 --- /dev/null +++ b/qwen3/amid/checkpoint-628/latest @@ -0,0 +1 @@ +global_step628 \ No newline at end of file diff --git a/qwen3/amid/checkpoint-628/rng_state_0.pth b/qwen3/amid/checkpoint-628/rng_state_0.pth new file mode 100644 index 0000000000000000000000000000000000000000..f3ea7d402f1624f296420a075d283430bc36cae8 --- /dev/null +++ b/qwen3/amid/checkpoint-628/rng_state_0.pth @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8bf9f12c4ef51f269865246a370b77796f13cfe2423d7c104ba089255731e5e0 +size 14917 diff --git a/qwen3/amid/checkpoint-628/rng_state_1.pth b/qwen3/amid/checkpoint-628/rng_state_1.pth new file mode 100644 index 0000000000000000000000000000000000000000..9581325e77eefdaebabc9a563e5ac399f9155ffb --- /dev/null +++ b/qwen3/amid/checkpoint-628/rng_state_1.pth @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0b6d50fa9ea1e53c22b6a8e937368cbc670dadbe5385fa480760ee21b0618315 +size 14917 diff --git a/qwen3/amid/checkpoint-628/scheduler.pt b/qwen3/amid/checkpoint-628/scheduler.pt new file mode 100644 index 0000000000000000000000000000000000000000..96c0cabcd99be4945ffbd7897ecc5367ac4beb28 --- /dev/null +++ b/qwen3/amid/checkpoint-628/scheduler.pt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bb823a2c51d7fb42dfe3b693a7159784285dbf38c5a797e6e73292096123ab7a +size 1465 diff --git a/qwen3/amid/checkpoint-628/tokenizer.json b/qwen3/amid/checkpoint-628/tokenizer.json new file mode 100644 index 0000000000000000000000000000000000000000..c7afbed2efcdf019f88ab0572ec29d3bf595dfe2 --- /dev/null +++ b/qwen3/amid/checkpoint-628/tokenizer.json @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:be75606093db2094d7cd20f3c2f385c212750648bd6ea4fb2bf507a6a4c55506 +size 11422650 diff --git a/qwen3/amid/checkpoint-628/tokenizer_config.json b/qwen3/amid/checkpoint-628/tokenizer_config.json new file mode 100644 index 0000000000000000000000000000000000000000..6623da03457d79d2cd4af9557e9f31407cdb835c --- /dev/null +++ b/qwen3/amid/checkpoint-628/tokenizer_config.json @@ -0,0 +1,31 @@ +{ + "add_prefix_space": false, + "backend": "tokenizers", + "bos_token": null, + "clean_up_tokenization_spaces": false, + "eos_token": "<|im_end|>", + "errors": "replace", + "extra_special_tokens": [ + "<|im_start|>", + "<|im_end|>", + "<|object_ref_start|>", + "<|object_ref_end|>", + "<|box_start|>", + "<|box_end|>", + "<|quad_start|>", + "<|quad_end|>", + "<|vision_start|>", + "<|vision_end|>", + "<|vision_pad|>", + "<|image_pad|>", + "<|video_pad|>" + ], + "is_local": false, + "local_files_only": false, + "model_max_length": 131072, + "pad_token": "<|endoftext|>", + "padding_side": "right", + "split_special_tokens": false, + "tokenizer_class": "Qwen2Tokenizer", + "unk_token": null +} diff --git a/qwen3/amid/checkpoint-628/trainer_state.json b/qwen3/amid/checkpoint-628/trainer_state.json new file mode 100644 index 0000000000000000000000000000000000000000..2a3ac10923096e3ff393a11e2d3f600154815aa4 --- /dev/null +++ b/qwen3/amid/checkpoint-628/trainer_state.json @@ -0,0 +1,281 @@ +{ + "best_global_step": null, + "best_metric": null, + "best_model_checkpoint": null, + "epoch": 2.0, + "eval_steps": 500, + "global_step": 628, + "is_hyper_param_search": false, + "is_local_process_zero": true, + "is_world_process_zero": true, + "log_history": [ + { + "epoch": 0.06382130035899482, + "grad_norm": 0.38384687900543213, + "learning_rate": 9.996390385474569e-05, + "loss": 0.27438180446624755, + "step": 20 + }, + { + "epoch": 0.12764260071798963, + "grad_norm": 0.38263317942619324, + "learning_rate": 9.984797509888031e-05, + "loss": 0.13717052936553956, + "step": 40 + }, + { + "epoch": 0.19146390107698444, + "grad_norm": 0.08620006591081619, + "learning_rate": 9.965229938050925e-05, + "loss": 0.13135391473770142, + "step": 60 + }, + { + "epoch": 0.25528520143597927, + "grad_norm": 0.15773959457874298, + "learning_rate": 9.937719005663432e-05, + "loss": 0.1076702356338501, + "step": 80 + }, + { + "epoch": 0.3191065017949741, + "grad_norm": 0.22962816059589386, + "learning_rate": 9.902308769000724e-05, + "loss": 0.08698999881744385, + "step": 100 + }, + { + "epoch": 0.3829278021539689, + "grad_norm": 0.12232966721057892, + "learning_rate": 9.859055934360789e-05, + "loss": 0.1128507375717163, + "step": 120 + }, + { + "epoch": 0.4467491025129637, + "grad_norm": 0.15597161650657654, + "learning_rate": 9.808029767254437e-05, + "loss": 0.1277535080909729, + "step": 140 + }, + { + "epoch": 0.5105704028719585, + "grad_norm": 0.7329031825065613, + "learning_rate": 9.749311981482817e-05, + "loss": 0.08885469436645507, + "step": 160 + }, + { + "epoch": 0.5743917032309533, + "grad_norm": 0.45483648777008057, + "learning_rate": 9.682996608280154e-05, + "loss": 0.07881734371185303, + "step": 180 + }, + { + "epoch": 0.6382130035899481, + "grad_norm": 0.16407009959220886, + "learning_rate": 9.609189845731207e-05, + "loss": 0.06113555431365967, + "step": 200 + }, + { + "epoch": 0.702034303948943, + "grad_norm": 0.07238732278347015, + "learning_rate": 9.52800988870462e-05, + "loss": 0.06768973469734192, + "step": 220 + }, + { + "epoch": 0.7658556043079378, + "grad_norm": 0.4741341471672058, + "learning_rate": 9.439586739574513e-05, + "loss": 0.04917148947715759, + "step": 240 + }, + { + "epoch": 0.8296769046669326, + "grad_norm": 0.36410900950431824, + "learning_rate": 9.344062000033414e-05, + "loss": 0.010153122991323472, + "step": 260 + }, + { + "epoch": 0.8934982050259274, + "grad_norm": 0.11222824454307556, + "learning_rate": 9.241588644329919e-05, + "loss": 0.00552816241979599, + "step": 280 + }, + { + "epoch": 0.9573195053849222, + "grad_norm": 0.47910866141319275, + "learning_rate": 9.132330774294252e-05, + "loss": 0.006760746240615845, + "step": 300 + }, + { + "epoch": 1.0, + "eval_generator_count": 1712.0, + "eval_generator_exact_match": 87.3832, + "eval_generator_rouge1": 99.2069, + "eval_generator_rouge2": 98.8793, + "eval_generator_rougeL": 98.7553, + "eval_loss": 0.012839075177907944, + "eval_runtime": 592.0147, + "eval_samples_per_second": 5.767, + "eval_selector_accuracy": 90.1869, + "eval_selector_count": 1712.0, + "eval_steps_per_second": 0.181, + "step": 314 + }, + { + "epoch": 1.0191463901076985, + "grad_norm": 0.27295932173728943, + "learning_rate": 9.01646335654399e-05, + "loss": 0.009849193692207336, + "step": 320 + }, + { + "epoch": 1.0829676904666932, + "grad_norm": 0.060826949775218964, + "learning_rate": 8.894171942290817e-05, + "loss": 0.005673223733901977, + "step": 340 + }, + { + "epoch": 1.146788990825688, + "grad_norm": 0.04862668365240097, + "learning_rate": 8.765652370197003e-05, + "loss": 0.005297792330384255, + "step": 360 + }, + { + "epoch": 1.210610291184683, + "grad_norm": 0.05064748600125313, + "learning_rate": 8.631110452757467e-05, + "loss": 0.0021365636959671972, + "step": 380 + }, + { + "epoch": 1.2744315915436777, + "grad_norm": 0.05359279736876488, + "learning_rate": 8.490761646709642e-05, + "loss": 0.00429258793592453, + "step": 400 + }, + { + "epoch": 1.3382528919026724, + "grad_norm": 0.11369121074676514, + "learning_rate": 8.344830707998953e-05, + "loss": 0.0034508116543292998, + "step": 420 + }, + { + "epoch": 1.4020741922616673, + "grad_norm": 0.01604766771197319, + "learning_rate": 8.193551331852458e-05, + "loss": 0.0028350137174129484, + "step": 440 + }, + { + "epoch": 1.4658954926206622, + "grad_norm": 0.15401995182037354, + "learning_rate": 8.037165778537033e-05, + "loss": 0.005546276643872261, + "step": 460 + }, + { + "epoch": 1.5297167929796571, + "grad_norm": 0.5877118706703186, + "learning_rate": 7.875924485401427e-05, + "loss": 0.0044526983052492145, + "step": 480 + }, + { + "epoch": 1.5935380933386518, + "grad_norm": 0.10250785946846008, + "learning_rate": 7.710085665823444e-05, + "loss": 0.0056363165378570555, + "step": 500 + }, + { + "epoch": 1.6573593936976465, + "grad_norm": 0.043251167982816696, + "learning_rate": 7.539914895704521e-05, + "loss": 0.0032581716775894167, + "step": 520 + }, + { + "epoch": 1.7211806940566414, + "grad_norm": 0.2089434117078781, + "learning_rate": 7.365684688173908e-05, + "loss": 0.004207362234592438, + "step": 540 + }, + { + "epoch": 1.7850019944156363, + "grad_norm": 0.14037534594535828, + "learning_rate": 7.18767405718347e-05, + "loss": 0.0019151581451296805, + "step": 560 + }, + { + "epoch": 1.848823294774631, + "grad_norm": 0.22862067818641663, + "learning_rate": 7.006168070692036e-05, + "loss": 0.004427855834364891, + "step": 580 + }, + { + "epoch": 1.9126445951336257, + "grad_norm": 0.03684071823954582, + "learning_rate": 6.821457394154786e-05, + "loss": 0.0017833203077316285, + "step": 600 + }, + { + "epoch": 1.9764658954926206, + "grad_norm": 0.0672929510474205, + "learning_rate": 6.633837825048768e-05, + "loss": 0.0035866759717464447, + "step": 620 + }, + { + "epoch": 2.0, + "eval_generator_count": 1712.0, + "eval_generator_exact_match": 93.5164, + "eval_generator_rouge1": 99.7294, + "eval_generator_rouge2": 99.5697, + "eval_generator_rougeL": 99.5152, + "eval_loss": 0.006910035386681557, + "eval_runtime": 591.6591, + "eval_samples_per_second": 5.77, + "eval_selector_accuracy": 96.9042, + "eval_selector_count": 1712.0, + "eval_steps_per_second": 0.181, + "step": 628 + } + ], + "logging_steps": 20, + "max_steps": 1570, + "num_input_tokens_seen": 0, + "num_train_epochs": 5, + "save_steps": 500, + "stateful_callbacks": { + "TrainerControl": { + "args": { + "should_epoch_stop": false, + "should_evaluate": false, + "should_log": false, + "should_save": true, + "should_training_stop": false + }, + "attributes": {} + } + }, + "total_flos": 2.346351770520781e+16, + "train_batch_size": 2, + "trial_name": null, + "trial_params": null +} diff --git a/qwen3/amid/checkpoint-628/training_args.bin b/qwen3/amid/checkpoint-628/training_args.bin new file mode 100644 index 0000000000000000000000000000000000000000..571568fd8ab61d629f2a731739ee4c9e1309cca4 --- /dev/null +++ b/qwen3/amid/checkpoint-628/training_args.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e67133ff7a80f6f166c03bd5f62d9c580548b0f6840a1ce3891dee623991e47a +size 7185 diff --git a/qwen3/amid/checkpoint-628/zero_to_fp32.py b/qwen3/amid/checkpoint-628/zero_to_fp32.py new file mode 100644 index 0000000000000000000000000000000000000000..f40f1f0acbbff30e8e8d29906b56aae4e8b8a138 --- /dev/null +++ b/qwen3/amid/checkpoint-628/zero_to_fp32.py @@ -0,0 +1,790 @@ +#!/usr/bin/env python + +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: Apache-2.0 + +# DeepSpeed Team + +# This script extracts fp32 consolidated weights from a zero 1, 2 and 3 DeepSpeed checkpoints. It gets +# copied into the top level checkpoint dir, so the user can easily do the conversion at any point in +# the future. Once extracted, the weights don't require DeepSpeed and can be used in any +# application. +# +# example: +# python zero_to_fp32.py . output_dir/ +# or +# python zero_to_fp32.py . output_dir/ --safe_serialization + +import argparse +import torch +import glob +import math +import os +import re +import gc +import json +import numpy as np +from tqdm import tqdm +from collections import OrderedDict +from dataclasses import dataclass + +# while this script doesn't use deepspeed to recover data, since the checkpoints are pickled with +# DeepSpeed data structures it has to be available in the current python environment. +from deepspeed.utils import logger +from deepspeed.checkpoint.constants import (DS_VERSION, OPTIMIZER_STATE_DICT, SINGLE_PARTITION_OF_FP32_GROUPS, + FP32_FLAT_GROUPS, ZERO_STAGE, PARTITION_COUNT, PARAM_SHAPES, BUFFER_NAMES, + FROZEN_PARAM_SHAPES, FROZEN_PARAM_FRAGMENTS, AUTOEP_LAYERS_KEY, + AUTOEP_LAYERS_KEY_LEGACY, AUTOEP_ZERO3_EXPERT_STATE_FORMAT_KEY, + AUTOEP_ZERO3_PARTITIONED_EXPERT_STATE_FORMAT) + + +@dataclass +class zero_model_state: + buffers: dict() + param_shapes: dict() + shared_params: list + ds_version: int + frozen_param_shapes: dict() + frozen_param_fragments: dict() + + +debug = 0 + +# load to cpu +device = torch.device('cpu') + + +def atoi(text): + return int(text) if text.isdigit() else text + + +def natural_keys(text): + ''' + alist.sort(key=natural_keys) sorts in human order + http://nedbatchelder.com/blog/200712/human_sorting.html + (See Toothy's implementation in the comments) + ''' + return [atoi(c) for c in re.split(r'(\d+)', text)] + + +def get_model_state_file(checkpoint_dir, zero_stage): + if not os.path.isdir(checkpoint_dir): + raise FileNotFoundError(f"Directory '{checkpoint_dir}' doesn't exist") + + # there should be only one file + if zero_stage <= 2: + file = os.path.join(checkpoint_dir, "mp_rank_00_model_states.pt") + elif zero_stage == 3: + file = os.path.join(checkpoint_dir, "zero_pp_rank_0_mp_rank_00_model_states.pt") + + if not os.path.exists(file): + raise FileNotFoundError(f"can't find model states file at '{file}'") + + return file + + +def get_checkpoint_files(checkpoint_dir, glob_pattern): + # XXX: need to test that this simple glob rule works for multi-node setup too + ckpt_files = sorted(glob.glob(os.path.join(checkpoint_dir, glob_pattern)), key=natural_keys) + + if len(ckpt_files) == 0: + raise FileNotFoundError(f"can't find {glob_pattern} files in directory '{checkpoint_dir}'") + + return ckpt_files + + +def get_optim_files(checkpoint_dir): + return get_checkpoint_files(checkpoint_dir, "*_optim_states.pt") + + +def get_model_state_files(checkpoint_dir): + return get_checkpoint_files(checkpoint_dir, "*_model_states.pt") + + +def _has_autoep_zero3_partitioned_metadata(state_dict): + autoep_layers = state_dict.get(AUTOEP_LAYERS_KEY) + if autoep_layers is None: + autoep_layers = state_dict.get(AUTOEP_LAYERS_KEY_LEGACY) + if not isinstance(autoep_layers, list): + return False + return any( + isinstance(entry, dict) + and entry.get(AUTOEP_ZERO3_EXPERT_STATE_FORMAT_KEY) == AUTOEP_ZERO3_PARTITIONED_EXPERT_STATE_FORMAT + for entry in autoep_layers) + + +def _raise_if_autoep_zero3_partitioned_state(state_dict): + if _has_autoep_zero3_partitioned_metadata(state_dict): + raise NotImplementedError("zero_to_fp32 does not support AutoEP ZeRO-3 partition-native checkpoints. " + "AutoEP expert parameters are partitioned over expert replica groups, so " + "global data-parallel consolidation would produce incomplete expert tensors. " + "Use ds_to_universal.py for expert-aware conversion.") + + +def _raise_if_autoep_zero3_partitioned_checkpoint(model_files): + for file in model_files: + state_dict = torch.load(file, map_location=device, weights_only=False) + _raise_if_autoep_zero3_partitioned_state(state_dict) + + +def parse_model_states(files): + zero_model_states = [] + for file in files: + state_dict = torch.load(file, map_location=device, weights_only=False) + _raise_if_autoep_zero3_partitioned_state(state_dict) + + if BUFFER_NAMES not in state_dict: + raise ValueError(f"{file} is not a model state checkpoint") + buffer_names = state_dict[BUFFER_NAMES] + if debug: + print("Found buffers:", buffer_names) + + # recover just the buffers while restoring them to fp32 if they were saved in fp16 + buffers = {k: v.float() for k, v in state_dict["module"].items() if k in buffer_names} + param_shapes = state_dict[PARAM_SHAPES] + + # collect parameters that are included in param_shapes + param_names = [] + for s in param_shapes: + for name in s.keys(): + param_names.append(name) + + # update with frozen parameters + frozen_param_shapes = state_dict.get(FROZEN_PARAM_SHAPES, None) + if frozen_param_shapes is not None: + if debug: + print(f"Found frozen_param_shapes: {frozen_param_shapes}") + param_names += list(frozen_param_shapes.keys()) + + # handle shared params + shared_params = [[k, v] for k, v in state_dict["shared_params"].items()] + + ds_version = state_dict.get(DS_VERSION, None) + + frozen_param_fragments = state_dict.get(FROZEN_PARAM_FRAGMENTS, None) + + z_model_state = zero_model_state(buffers=buffers, + param_shapes=param_shapes, + shared_params=shared_params, + ds_version=ds_version, + frozen_param_shapes=frozen_param_shapes, + frozen_param_fragments=frozen_param_fragments) + zero_model_states.append(z_model_state) + + return zero_model_states + + +def parse_optim_states(files, ds_checkpoint_dir): + total_files = len(files) + state_dicts = [] + for f in tqdm(files, desc='Loading checkpoint shards'): + state_dict = torch.load(f, map_location=device, mmap=True, weights_only=False) + # immediately discard the potentially huge 2 optimizer states as we only care for fp32 master weights + # and also handle the case where it was already removed by another helper script + state_dict["optimizer_state_dict"].pop("optimizer_state_dict", None) + state_dicts.append(state_dict) + + if ZERO_STAGE not in state_dicts[0][OPTIMIZER_STATE_DICT]: + raise ValueError(f"{files[0]} is not a zero checkpoint") + zero_stage = state_dicts[0][OPTIMIZER_STATE_DICT][ZERO_STAGE] + world_size = state_dicts[0][OPTIMIZER_STATE_DICT][PARTITION_COUNT] + + # For ZeRO-2 each param group can have different partition_count as data parallelism for expert + # parameters can be different from data parallelism for non-expert parameters. So we can just + # use the max of the partition_count to get the dp world_size. + + if type(world_size) is list: + world_size = max(world_size) + + if world_size != total_files: + raise ValueError( + f"Expected {world_size} of '*_optim_states.pt' under '{ds_checkpoint_dir}' but found {total_files} files. " + "Possibly due to an overwrite of an old checkpoint, or a checkpoint didn't get saved by one or more processes." + ) + + # the groups are named differently in each stage + if zero_stage <= 2: + fp32_groups_key = SINGLE_PARTITION_OF_FP32_GROUPS + elif zero_stage == 3: + fp32_groups_key = FP32_FLAT_GROUPS + else: + raise ValueError(f"unknown zero stage {zero_stage}") + + fp32_flat_groups = [state_dicts[i][OPTIMIZER_STATE_DICT][fp32_groups_key] for i in range(len(state_dicts))] + return zero_stage, world_size, fp32_flat_groups + + +def _get_fp32_state_dict_from_zero_checkpoint(ds_checkpoint_dir, exclude_frozen_parameters): + """ + Returns fp32 state_dict reconstructed from ds checkpoint + + Args: + - ``ds_checkpoint_dir``: path to the deepspeed checkpoint folder (where the optimizer files are) + + """ + print(f"Processing zero checkpoint '{ds_checkpoint_dir}'") + + # parse_model_states rejects AutoEP ZeRO-3 partition-native checkpoints + # before the expensive optimizer-shard load below. + model_files = get_model_state_files(ds_checkpoint_dir) + zero_model_states = parse_model_states(model_files) + print(f'Parsing checkpoint created by deepspeed=={zero_model_states[0].ds_version}') + + optim_files = get_optim_files(ds_checkpoint_dir) + zero_stage, world_size, fp32_flat_groups = parse_optim_states(optim_files, ds_checkpoint_dir) + print(f"Detected checkpoint of type zero stage {zero_stage}, world_size: {world_size}") + + if zero_stage <= 2: + return _get_fp32_state_dict_from_zero2_checkpoint(world_size, fp32_flat_groups, zero_model_states, + exclude_frozen_parameters) + elif zero_stage == 3: + return _get_fp32_state_dict_from_zero3_checkpoint(world_size, fp32_flat_groups, zero_model_states, + exclude_frozen_parameters) + + +def _zero2_merge_frozen_params(state_dict, zero_model_states): + if zero_model_states[0].frozen_param_shapes is None or len(zero_model_states[0].frozen_param_shapes) == 0: + return + + frozen_param_shapes = zero_model_states[0].frozen_param_shapes + frozen_param_fragments = zero_model_states[0].frozen_param_fragments + + if debug: + num_elem = sum(s.numel() for s in frozen_param_shapes.values()) + print(f'rank 0: {FROZEN_PARAM_SHAPES}.numel = {num_elem}') + + wanted_params = len(frozen_param_shapes) + wanted_numel = sum(s.numel() for s in frozen_param_shapes.values()) + avail_numel = sum([p.numel() for p in frozen_param_fragments.values()]) + print(f'Frozen params: Have {avail_numel} numels to process.') + print(f'Frozen params: Need {wanted_numel} numels in {wanted_params} params') + + total_params = 0 + total_numel = 0 + for name, shape in frozen_param_shapes.items(): + total_params += 1 + unpartitioned_numel = shape.numel() + total_numel += unpartitioned_numel + + state_dict[name] = frozen_param_fragments[name] + + if debug: + print(f"{name} full shape: {shape} unpartitioned numel {unpartitioned_numel} ") + + print(f"Reconstructed Frozen fp32 state dict with {total_params} params {total_numel} elements") + + +def _has_callable(obj, fn): + attr = getattr(obj, fn, None) + return callable(attr) + + +def _zero2_merge_trainable_params(state_dict, world_size, fp32_flat_groups, zero_model_states): + param_shapes = zero_model_states[0].param_shapes + + # Reconstruction protocol: + # + # XXX: document this + + if debug: + for i in range(world_size): + for j in range(len(fp32_flat_groups[0])): + print(f"{FP32_FLAT_GROUPS}[{i}][{j}].shape={fp32_flat_groups[i][j].shape}") + + # XXX: memory usage doubles here (zero2) + num_param_groups = len(fp32_flat_groups[0]) + merged_single_partition_of_fp32_groups = [] + for i in range(num_param_groups): + merged_partitions = [sd[i] for sd in fp32_flat_groups] + full_single_fp32_vector = torch.cat(merged_partitions, 0) + merged_single_partition_of_fp32_groups.append(full_single_fp32_vector) + avail_numel = sum( + [full_single_fp32_vector.numel() for full_single_fp32_vector in merged_single_partition_of_fp32_groups]) + + if debug: + wanted_params = sum([len(shapes) for shapes in param_shapes]) + wanted_numel = sum([sum(shape.numel() for shape in shapes.values()) for shapes in param_shapes]) + # not asserting if there is a mismatch due to possible padding + print(f"Have {avail_numel} numels to process.") + print(f"Need {wanted_numel} numels in {wanted_params} params.") + + # params + # XXX: for huge models that can't fit into the host's RAM we will have to recode this to support + # out-of-core computing solution + total_numel = 0 + total_params = 0 + for shapes, full_single_fp32_vector in zip(param_shapes, merged_single_partition_of_fp32_groups): + offset = 0 + avail_numel = full_single_fp32_vector.numel() + for name, shape in shapes.items(): + + unpartitioned_numel = shape.numel() if _has_callable(shape, 'numel') else math.prod(shape) + total_numel += unpartitioned_numel + total_params += 1 + + if debug: + print(f"{name} full shape: {shape} unpartitioned numel {unpartitioned_numel} ") + state_dict[name] = full_single_fp32_vector.narrow(0, offset, unpartitioned_numel).view(shape) + offset += unpartitioned_numel + + # Z2 started to align to 2*world_size to improve nccl performance. Therefore both offset and + # avail_numel can differ by anywhere between 0..2*world_size. Due to two unrelated complex + # paddings performed in the code it's almost impossible to predict the exact numbers w/o the + # live optimizer object, so we are checking that the numbers are within the right range + align_to = 2 * world_size + + def zero2_align(x): + return align_to * math.ceil(x / align_to) + + if debug: + print(f"original offset={offset}, avail_numel={avail_numel}") + + offset = zero2_align(offset) + avail_numel = zero2_align(avail_numel) + + if debug: + print(f"aligned offset={offset}, avail_numel={avail_numel}") + + # Sanity check + if offset != avail_numel: + raise ValueError(f"consumed {offset} numels out of {avail_numel} - something is wrong") + + print(f"Reconstructed fp32 state dict with {total_params} params {total_numel} elements") + + +def _get_fp32_state_dict_from_zero2_checkpoint(world_size, fp32_flat_groups, zero_model_states, + exclude_frozen_parameters): + state_dict = OrderedDict() + + # buffers + buffers = zero_model_states[0].buffers + state_dict.update(buffers) + if debug: + print(f"added {len(buffers)} buffers") + + if not exclude_frozen_parameters: + _zero2_merge_frozen_params(state_dict, zero_model_states) + + _zero2_merge_trainable_params(state_dict, world_size, fp32_flat_groups, zero_model_states) + + # recover shared parameters + for pair in zero_model_states[0].shared_params: + if pair[1] in state_dict: + state_dict[pair[0]] = state_dict[pair[1]] + + return state_dict + + +def zero3_partitioned_param_info(unpartitioned_numel, world_size): + remainder = unpartitioned_numel % world_size + padding_numel = (world_size - remainder) if remainder else 0 + partitioned_numel = math.ceil(unpartitioned_numel / world_size) + return partitioned_numel, padding_numel + + +def _zero3_merge_frozen_params(state_dict, world_size, zero_model_states): + if zero_model_states[0].frozen_param_shapes is None or len(zero_model_states[0].frozen_param_shapes) == 0: + return + + if debug: + for i in range(world_size): + num_elem = sum(s.numel() for s in zero_model_states[i].frozen_param_fragments.values()) + print(f'rank {i}: {FROZEN_PARAM_SHAPES}.numel = {num_elem}') + + frozen_param_shapes = zero_model_states[0].frozen_param_shapes + wanted_params = len(frozen_param_shapes) + wanted_numel = sum(s.numel() for s in frozen_param_shapes.values()) + avail_numel = sum([p.numel() for p in zero_model_states[0].frozen_param_fragments.values()]) * world_size + print(f'Frozen params: Have {avail_numel} numels to process.') + print(f'Frozen params: Need {wanted_numel} numels in {wanted_params} params') + + total_params = 0 + total_numel = 0 + for name, shape in zero_model_states[0].frozen_param_shapes.items(): + total_params += 1 + unpartitioned_numel = shape.numel() + total_numel += unpartitioned_numel + + param_frags = tuple(model_state.frozen_param_fragments[name] for model_state in zero_model_states) + state_dict[name] = torch.cat(param_frags, 0).narrow(0, 0, unpartitioned_numel).view(shape) + + partitioned_numel, partitioned_padding_numel = zero3_partitioned_param_info(unpartitioned_numel, world_size) + + if debug: + print( + f"Frozen params: {total_params} {name} full shape: {shape} partition0 numel={partitioned_numel} partitioned_padding_numel={partitioned_padding_numel}" + ) + + print(f"Reconstructed Frozen fp32 state dict with {total_params} params {total_numel} elements") + + +class GatheredTensor: + """ + A pseudo tensor that collects partitioned weights. + It is more memory efficient when there are multiple groups. + """ + + def __init__(self, flat_groups, flat_groups_offset, offset, partitioned_numel, shape): + self.flat_groups = flat_groups + self.flat_groups_offset = flat_groups_offset + self.offset = offset + self.partitioned_numel = partitioned_numel + self.shape = shape + self.dtype = self.flat_groups[0][0].dtype + + def contiguous(self): + """ + Merge partitioned weights from flat_groups into a single tensor. + """ + end_idx = self.offset + self.partitioned_numel + world_size = len(self.flat_groups) + pad_flat_param_chunks = [] + + for rank_i in range(world_size): + # for each rank, we need to collect weights from related group/groups + flat_groups_at_rank_i = self.flat_groups[rank_i] + start_group_id = None + end_group_id = None + for group_id in range(len(self.flat_groups_offset)): + if self.flat_groups_offset[group_id] <= self.offset < self.flat_groups_offset[group_id + 1]: + start_group_id = group_id + if self.flat_groups_offset[group_id] < end_idx <= self.flat_groups_offset[group_id + 1]: + end_group_id = group_id + break + # collect weights from related group/groups + for group_id in range(start_group_id, end_group_id + 1): + flat_tensor = flat_groups_at_rank_i[group_id] + start_offset = self.offset - self.flat_groups_offset[group_id] + end_offset = min(end_idx, self.flat_groups_offset[group_id + 1]) - self.flat_groups_offset[group_id] + pad_flat_param_chunks.append(flat_tensor[start_offset:end_offset]) + + # collect weights from all ranks + pad_flat_param = torch.cat(pad_flat_param_chunks, dim=0) + param = pad_flat_param[:self.shape.numel()].view(self.shape).contiguous() + return param + + +def _zero3_merge_trainable_params(state_dict, world_size, fp32_flat_groups, zero_model_states): + param_shapes = zero_model_states[0].param_shapes + avail_numel = sum([flat_group.numel() for flat_group in fp32_flat_groups[0]]) * world_size + + # Reconstruction protocol: For zero3 we need to zip the partitions together at boundary of each + # param, re-consolidating each param, while dealing with padding if any + + # merge list of dicts, preserving order + param_shapes = {k: v for d in param_shapes for k, v in d.items()} + + if debug: + for i in range(world_size): + print(f"{FP32_FLAT_GROUPS}[{i}].shape={fp32_flat_groups[i].shape}") + + wanted_params = len(param_shapes) + wanted_numel = sum(shape.numel() for shape in param_shapes.values()) + # not asserting if there is a mismatch due to possible padding + avail_numel = fp32_flat_groups[0].numel() * world_size + print(f"Trainable params: Have {avail_numel} numels to process.") + print(f"Trainable params: Need {wanted_numel} numels in {wanted_params} params.") + + # params + # XXX: for huge models that can't fit into the host's RAM we will have to recode this to support + # out-of-core computing solution + offset = 0 + total_numel = 0 + total_params = 0 + flat_groups_offset = [0] + list(np.cumsum([flat_tensor.numel() for flat_tensor in fp32_flat_groups[0]])) + for name, shape in tqdm(param_shapes.items(), desc='Gathering sharded weights'): + unpartitioned_numel = shape.numel() + total_numel += unpartitioned_numel + total_params += 1 + partitioned_numel, partitioned_padding_numel = zero3_partitioned_param_info(unpartitioned_numel, world_size) + + if debug: + print( + f"Trainable params: {total_params} {name} full shape: {shape} partition0 numel={partitioned_numel} partitioned_padding_numel={partitioned_padding_numel}" + ) + + # memory efficient tensor + tensor = GatheredTensor(fp32_flat_groups, flat_groups_offset, offset, partitioned_numel, shape) + state_dict[name] = tensor + offset += partitioned_numel + + offset *= world_size + + # Sanity check + if offset != avail_numel: + raise ValueError(f"consumed {offset} numels out of {avail_numel} - something is wrong") + + print(f"Reconstructed Trainable fp32 state dict with {total_params} params {total_numel} elements") + + +def _get_fp32_state_dict_from_zero3_checkpoint(world_size, fp32_flat_groups, zero_model_states, + exclude_frozen_parameters): + state_dict = OrderedDict() + + # buffers + buffers = zero_model_states[0].buffers + state_dict.update(buffers) + if debug: + print(f"added {len(buffers)} buffers") + + if not exclude_frozen_parameters: + _zero3_merge_frozen_params(state_dict, world_size, zero_model_states) + + _zero3_merge_trainable_params(state_dict, world_size, fp32_flat_groups, zero_model_states) + + # recover shared parameters + for pair in zero_model_states[0].shared_params: + if pair[1] in state_dict: + state_dict[pair[0]] = state_dict[pair[1]] + + return state_dict + + +def to_torch_tensor(state_dict, return_empty_tensor=False): + """ + Convert state_dict of GatheredTensor to torch tensor + """ + torch_state_dict = {} + converted_tensors = {} + for name, tensor in state_dict.items(): + tensor_id = id(tensor) + if tensor_id in converted_tensors: # shared tensors + shared_tensor = torch_state_dict[converted_tensors[tensor_id]] + torch_state_dict[name] = shared_tensor + else: + converted_tensors[tensor_id] = name + if return_empty_tensor: + torch_state_dict[name] = torch.empty(tensor.shape, dtype=tensor.dtype) + else: + torch_state_dict[name] = tensor.contiguous() + return torch_state_dict + + +def get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir, + tag=None, + exclude_frozen_parameters=False, + lazy_mode=False): + """ + Convert ZeRO 2 or 3 checkpoint into a single fp32 consolidated state_dict that can be loaded with + ``load_state_dict()`` and used for training without DeepSpeed or shared with others, for example + via a model hub. + + Args: + - ``checkpoint_dir``: path to the desired checkpoint folder + - ``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`` + - ``exclude_frozen_parameters``: exclude frozen parameters + - ``lazy_mode``: get state_dict in lazy mode. It returns a dict of pesduo tensor instead of torch tensor, which is more memory efficient. + Convert the pesduo tensor to torch tensor by ``.contiguous()`` + + Returns: + - pytorch ``state_dict`` + + A typical usage might be :: + + from deepspeed.utils.zero_to_fp32 import get_fp32_state_dict_from_zero_checkpoint + # do the training and checkpoint saving + state_dict = get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir) # already on cpu + model = model.cpu() # move to cpu + model.load_state_dict(state_dict) + # submit to model hub or save the model to share with others + + In this example the ``model`` will no longer be usable in the deepspeed context of the same + application. i.e. you will need to re-initialize the deepspeed engine, since + ``model.load_state_dict(state_dict)`` will remove all the deepspeed magic from it. + + If you want it all done for you, use ``load_state_dict_from_zero_checkpoint`` instead. + + Note: the above usage may not work if your application doesn't have sufficient free CPU memory. + You may need to use the offline approach using the ``zero_to_fp32.py`` script that is saved with + the checkpoint. Or you can load state_dict in lazy mode :: + + from deepspeed.utils.zero_to_fp32 import get_fp32_state_dict_from_zero_checkpoint + state_dict = get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir, lazy_mode=True) # not on cpu + for name, lazy_tensor in state_dict.item(): + tensor = lazy_tensor.contiguous() # to cpu + print(name, tensor) + # del tensor to release memory if it no longer in use + """ + if tag is None: + latest_path = os.path.join(checkpoint_dir, 'latest') + if os.path.isfile(latest_path): + with open(latest_path, 'r') as fd: + tag = fd.read().strip() + else: + raise ValueError(f"Unable to find 'latest' file at {latest_path}") + + ds_checkpoint_dir = os.path.join(checkpoint_dir, tag) + + if not os.path.isdir(ds_checkpoint_dir): + raise FileNotFoundError(f"Directory '{ds_checkpoint_dir}' doesn't exist") + + state_dict = _get_fp32_state_dict_from_zero_checkpoint(ds_checkpoint_dir, exclude_frozen_parameters) + if lazy_mode: + return state_dict + else: + return to_torch_tensor(state_dict) + + +def convert_zero_checkpoint_to_fp32_state_dict(checkpoint_dir, + output_dir, + max_shard_size="5GB", + safe_serialization=False, + tag=None, + exclude_frozen_parameters=False): + """ + Convert ZeRO 2 or 3 checkpoint into a single fp32 consolidated ``state_dict`` file that can be + loaded with ``torch.load(file)`` + ``load_state_dict()`` and used for training without DeepSpeed. + + Args: + - ``checkpoint_dir``: path to the desired checkpoint folder. (one that contains the tag-folder, like ``global_step14``) + - ``output_dir``: directory to the pytorch fp32 state_dict output files + - ``max_shard_size``: the maximum size for a checkpoint before being sharded, default value is 5GB + - ``safe_serialization``: whether to save the model using `safetensors` or the traditional PyTorch way (that uses `pickle`). + - ``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`` + - ``exclude_frozen_parameters``: exclude frozen parameters + """ + + # Dependency pre-check + if safe_serialization: + try: + from safetensors.torch import save_file + except ImportError: + print('If you want to use `safe_serialization`, please `pip install safetensors`') + raise + if max_shard_size is not None: + try: + from huggingface_hub import split_torch_state_dict_into_shards + except ImportError: + print('If you want to use `max_shard_size`, please `pip install huggingface_hub`') + raise + + # Convert zero checkpoint to state_dict + state_dict = get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir, + tag, + exclude_frozen_parameters, + lazy_mode=True) + + # Shard the model if it is too big. + weights_name = "model.safetensors" if safe_serialization else "pytorch_model.bin" + if max_shard_size is not None: + filename_pattern = weights_name.replace(".bin", "{suffix}.bin").replace(".safetensors", "{suffix}.safetensors") + # an memory-efficient approach for sharding + empty_state_dict = to_torch_tensor(state_dict, return_empty_tensor=True) + state_dict_split = split_torch_state_dict_into_shards(empty_state_dict, + filename_pattern=filename_pattern, + max_shard_size=max_shard_size) + else: + from collections import namedtuple + StateDictSplit = namedtuple("StateDictSplit", ["is_sharded", "filename_to_tensors"]) + state_dict_split = StateDictSplit(is_sharded=False, + filename_to_tensors={weights_name: list(state_dict.keys())}) + + # Save the model by shard + os.makedirs(output_dir, exist_ok=True) + filename_to_tensors = state_dict_split.filename_to_tensors.items() + for shard_file, tensors in tqdm(filename_to_tensors, desc="Saving checkpoint shards"): + shard_state_dict = {tensor_name: state_dict[tensor_name] for tensor_name in tensors} + shard_state_dict = to_torch_tensor(shard_state_dict) + output_path = os.path.join(output_dir, shard_file) + if safe_serialization: + save_file(shard_state_dict, output_path, metadata={"format": "pt"}) + else: + torch.save(shard_state_dict, output_path) + # release the memory of current shard + for tensor_name in list(shard_state_dict.keys()): + del state_dict[tensor_name] + del shard_state_dict[tensor_name] + del shard_state_dict + gc.collect() + + # Save index if sharded + if state_dict_split.is_sharded: + index = { + "metadata": state_dict_split.metadata, + "weight_map": state_dict_split.tensor_to_filename, + } + save_index_file = "model.safetensors.index.json" if safe_serialization else "pytorch_model.bin.index.json" + save_index_file = os.path.join(output_dir, save_index_file) + with open(save_index_file, "w", encoding="utf-8") as f: + content = json.dumps(index, indent=2, sort_keys=True) + "\n" + f.write(content) + + +def load_state_dict_from_zero_checkpoint(model, checkpoint_dir, tag=None): + """ + 1. Put the provided model to cpu + 2. Convert ZeRO 2 or 3 checkpoint into a single fp32 consolidated ``state_dict`` + 3. Load it into the provided model + + Args: + - ``model``: the model object to update + - ``checkpoint_dir``: path to the desired checkpoint folder. (one that contains the tag-folder, like ``global_step14``) + - ``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`` + + Returns: + - ``model`: modified model + + Make sure you have plenty of CPU memory available before you call this function. If you don't + have enough use the ``zero_to_fp32.py`` utility to do the conversion. You will find it + conveniently placed for you in the checkpoint folder. + + A typical usage might be :: + + from deepspeed.utils.zero_to_fp32 import load_state_dict_from_zero_checkpoint + model = load_state_dict_from_zero_checkpoint(trainer.model, checkpoint_dir) + # submit to model hub or save the model to share with others + + Note, that once this was run, the ``model`` will no longer be usable in the deepspeed context + of the same application. i.e. you will need to re-initialize the deepspeed engine, since + ``model.load_state_dict(state_dict)`` will remove all the deepspeed magic from it. + + """ + logger.info("Extracting fp32 weights") + state_dict = get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir, tag) + + logger.info("Overwriting model with fp32 weights") + model = model.cpu() + model.load_state_dict(state_dict, strict=False) + + return model + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument("checkpoint_dir", + type=str, + help="path to the desired checkpoint folder, e.g., path/checkpoint-12") + parser.add_argument("output_dir", + type=str, + help="directory to the pytorch fp32 state_dict output files" + "(e.g. path/checkpoint-12-output/)") + parser.add_argument( + "--max_shard_size", + type=str, + default="5GB", + help="The maximum size for a checkpoint before being sharded. Checkpoints shard will then be each of size" + "lower than this size. If expressed as a string, needs to be digits followed by a unit (like `5MB`" + "We default it to 5GB in order for models to be able to run easily on free-tier google colab instances" + "without CPU OOM issues.") + parser.add_argument( + "--safe_serialization", + default=False, + action='store_true', + help="Whether to save the model using `safetensors` or the traditional PyTorch way (that uses `pickle`).") + parser.add_argument("-t", + "--tag", + type=str, + default=None, + help="checkpoint tag used as a unique identifier for checkpoint. e.g., global_step1") + parser.add_argument("--exclude_frozen_parameters", action='store_true', help="exclude frozen parameters") + parser.add_argument("-d", "--debug", action='store_true', help="enable debug") + args = parser.parse_args() + + debug = args.debug + + convert_zero_checkpoint_to_fp32_state_dict(args.checkpoint_dir, + args.output_dir, + max_shard_size=args.max_shard_size, + safe_serialization=args.safe_serialization, + tag=args.tag, + exclude_frozen_parameters=args.exclude_frozen_parameters) diff --git a/qwen3/amid/checkpoint-942/README.md b/qwen3/amid/checkpoint-942/README.md new file mode 100644 index 0000000000000000000000000000000000000000..776f98d43659dd923b8c3e5649c5ae66d1f99f3e --- /dev/null +++ b/qwen3/amid/checkpoint-942/README.md @@ -0,0 +1,208 @@ +--- +base_model: Qwen/Qwen3-0.6B +library_name: peft +pipeline_tag: text-generation +tags: +- base_model:adapter:Qwen/Qwen3-0.6B +- llama-factory +- lora +- transformers +--- + +# Model Card for Model ID + + + + + +## Model Details + +### Model Description + + + + + +- **Developed by:** [More Information Needed] +- **Funded by [optional]:** [More Information Needed] +- **Shared by [optional]:** [More Information Needed] +- **Model type:** [More Information Needed] +- **Language(s) (NLP):** [More Information Needed] +- **License:** [More Information Needed] +- **Finetuned from model [optional]:** [More Information Needed] + +### Model Sources [optional] + + + +- **Repository:** [More Information Needed] +- **Paper [optional]:** [More Information Needed] +- **Demo [optional]:** [More Information Needed] + +## Uses + + + +### Direct Use + + + +[More Information Needed] + +### Downstream Use [optional] + + + +[More Information Needed] + +### Out-of-Scope Use + + + +[More Information Needed] + +## Bias, Risks, and Limitations + + + +[More Information Needed] + +### Recommendations + + + +Users (both direct and downstream) should be made aware of the risks, biases and limitations of the model. More information needed for further recommendations. + +## How to Get Started with the Model + +Use the code below to get started with the model. + +[More Information Needed] + +## Training Details + +### Training Data + + + +[More Information Needed] + +### Training Procedure + + + +#### Preprocessing [optional] + +[More Information Needed] + + +#### Training Hyperparameters + +- **Training regime:** [More Information Needed] + +#### Speeds, Sizes, Times [optional] + + + +[More Information Needed] + +## Evaluation + + + +### Testing Data, Factors & Metrics + +#### Testing Data + + + +[More Information Needed] + +#### Factors + + + +[More Information Needed] + +#### Metrics + + + +[More Information Needed] + +### Results + +[More Information Needed] + +#### Summary + + + +## Model Examination [optional] + + + +[More Information Needed] + +## Environmental Impact + + + +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). + +- **Hardware Type:** [More Information Needed] +- **Hours used:** [More Information Needed] +- **Cloud Provider:** [More Information Needed] +- **Compute Region:** [More Information Needed] +- **Carbon Emitted:** [More Information Needed] + +## Technical Specifications [optional] + +### Model Architecture and Objective + +[More Information Needed] + +### Compute Infrastructure + +[More Information Needed] + +#### Hardware + +[More Information Needed] + +#### Software + +[More Information Needed] + +## Citation [optional] + + + +**BibTeX:** + +[More Information Needed] + +**APA:** + +[More Information Needed] + +## Glossary [optional] + + + +[More Information Needed] + +## More Information [optional] + +[More Information Needed] + +## Model Card Authors [optional] + +[More Information Needed] + +## Model Card Contact + +[More Information Needed] +### Framework versions + +- PEFT 0.18.1 \ No newline at end of file diff --git a/qwen3/amid/checkpoint-942/adapter_config.json b/qwen3/amid/checkpoint-942/adapter_config.json new file mode 100644 index 0000000000000000000000000000000000000000..16362f47190537658d6b04519de786417a5f6c2f --- /dev/null +++ b/qwen3/amid/checkpoint-942/adapter_config.json @@ -0,0 +1,46 @@ +{ + "alora_invocation_tokens": null, + "alpha_pattern": {}, + "arrow_config": null, + "auto_mapping": null, + "base_model_name_or_path": "Qwen/Qwen3-0.6B", + "bias": "none", + "corda_config": null, + "ensure_weight_tying": false, + "eva_config": null, + "exclude_modules": null, + "fan_in_fan_out": false, + "inference_mode": true, + "init_lora_weights": true, + "layer_replication": null, + "layers_pattern": null, + "layers_to_transform": null, + "loftq_config": {}, + "lora_alpha": 64, + "lora_bias": false, + "lora_dropout": 0.1, + "megatron_config": null, + "megatron_core": "megatron.core", + "modules_to_save": null, + "peft_type": "LORA", + "peft_version": "0.18.1", + "qalora_group_size": 16, + "r": 32, + "rank_pattern": {}, + "revision": null, + "target_modules": [ + "v_proj", + "q_proj", + "o_proj", + "gate_proj", + "up_proj", + "k_proj", + "down_proj" + ], + "target_parameters": null, + "task_type": "CAUSAL_LM", + "trainable_token_indices": null, + "use_dora": false, + "use_qalora": false, + "use_rslora": false +} \ No newline at end of file diff --git a/qwen3/amid/checkpoint-942/adapter_model.safetensors b/qwen3/amid/checkpoint-942/adapter_model.safetensors new file mode 100644 index 0000000000000000000000000000000000000000..d82ae009b056b3cada54c54d53e197cf57018fc1 --- /dev/null +++ b/qwen3/amid/checkpoint-942/adapter_model.safetensors @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:42a66b61ac882bf27ec3608465ee839ade315ab4d05e90c6b29feafe1a79e596 +size 40422560 diff --git a/qwen3/amid/checkpoint-942/chat_template.jinja b/qwen3/amid/checkpoint-942/chat_template.jinja new file mode 100644 index 0000000000000000000000000000000000000000..01be9b307daa2d425f7c168c9fb145a286e0afb4 --- /dev/null +++ b/qwen3/amid/checkpoint-942/chat_template.jinja @@ -0,0 +1,89 @@ +{%- if tools %} + {{- '<|im_start|>system\n' }} + {%- if messages[0].role == 'system' %} + {{- messages[0].content + '\n\n' }} + {%- endif %} + {{- "# Tools\n\nYou may call one or more functions to assist with the user query.\n\nYou are provided with function signatures within XML tags:\n" }} + {%- for tool in tools %} + {{- "\n" }} + {{- tool | tojson }} + {%- endfor %} + {{- "\n\n\nFor each function call, return a json object with function name and arguments within XML tags:\n\n{\"name\": , \"arguments\": }\n<|im_end|>\n" }} +{%- else %} + {%- if messages[0].role == 'system' %} + {{- '<|im_start|>system\n' + messages[0].content + '<|im_end|>\n' }} + {%- endif %} +{%- endif %} +{%- set ns = namespace(multi_step_tool=true, last_query_index=messages|length - 1) %} +{%- for message in messages[::-1] %} + {%- set index = (messages|length - 1) - loop.index0 %} + {%- if ns.multi_step_tool and message.role == "user" and message.content is string and not(message.content.startswith('') and message.content.endswith('')) %} + {%- set ns.multi_step_tool = false %} + {%- set ns.last_query_index = index %} + {%- endif %} +{%- endfor %} +{%- for message in messages %} + {%- if message.content is string %} + {%- set content = message.content %} + {%- else %} + {%- set content = '' %} + {%- endif %} + {%- if (message.role == "user") or (message.role == "system" and not loop.first) %} + {{- '<|im_start|>' + message.role + '\n' + content + '<|im_end|>' + '\n' }} + {%- elif message.role == "assistant" %} + {%- set reasoning_content = '' %} + {%- if message.reasoning_content is string %} + {%- set reasoning_content = message.reasoning_content %} + {%- else %} + {%- if '' in content %} + {%- set reasoning_content = content.split('')[0].rstrip('\n').split('')[-1].lstrip('\n') %} + {%- set content = content.split('')[-1].lstrip('\n') %} + {%- endif %} + {%- endif %} + {%- if loop.index0 > ns.last_query_index %} + {%- if loop.last or (not loop.last and reasoning_content) %} + {{- '<|im_start|>' + message.role + '\n\n' + reasoning_content.strip('\n') + '\n\n\n' + content.lstrip('\n') }} + {%- else %} + {{- '<|im_start|>' + message.role + '\n' + content }} + {%- endif %} + {%- else %} + {{- '<|im_start|>' + message.role + '\n' + content }} + {%- endif %} + {%- if message.tool_calls %} + {%- for tool_call in message.tool_calls %} + {%- if (loop.first and content) or (not loop.first) %} + {{- '\n' }} + {%- endif %} + {%- if tool_call.function %} + {%- set tool_call = tool_call.function %} + {%- endif %} + {{- '\n{"name": "' }} + {{- tool_call.name }} + {{- '", "arguments": ' }} + {%- if tool_call.arguments is string %} + {{- tool_call.arguments }} + {%- else %} + {{- tool_call.arguments | tojson }} + {%- endif %} + {{- '}\n' }} + {%- endfor %} + {%- endif %} + {{- '<|im_end|>\n' }} + {%- elif message.role == "tool" %} + {%- if loop.first or (messages[loop.index0 - 1].role != "tool") %} + {{- '<|im_start|>user' }} + {%- endif %} + {{- '\n\n' }} + {{- content }} + {{- '\n' }} + {%- if loop.last or (messages[loop.index0 + 1].role != "tool") %} + {{- '<|im_end|>\n' }} + {%- endif %} + {%- endif %} +{%- endfor %} +{%- if add_generation_prompt %} + {{- '<|im_start|>assistant\n' }} + {%- if enable_thinking is defined and enable_thinking is false %} + {{- '\n\n\n\n' }} + {%- endif %} +{%- endif %} \ No newline at end of file diff --git a/qwen3/amid/checkpoint-942/global_step942/bf16_zero_pp_rank_0_mp_rank_00_optim_states.pt b/qwen3/amid/checkpoint-942/global_step942/bf16_zero_pp_rank_0_mp_rank_00_optim_states.pt new file mode 100644 index 0000000000000000000000000000000000000000..430aff02c35959ec02efb03036320b751b969159 --- /dev/null +++ b/qwen3/amid/checkpoint-942/global_step942/bf16_zero_pp_rank_0_mp_rank_00_optim_states.pt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f3366587ffc75b4047977e6e15443096b8b57493fda0e89a96b367f05499adeb +size 121135557 diff --git a/qwen3/amid/checkpoint-942/global_step942/bf16_zero_pp_rank_1_mp_rank_00_optim_states.pt b/qwen3/amid/checkpoint-942/global_step942/bf16_zero_pp_rank_1_mp_rank_00_optim_states.pt new file mode 100644 index 0000000000000000000000000000000000000000..087981fdf7d55983b4e15fe9ccaec7d77f73a91e --- /dev/null +++ b/qwen3/amid/checkpoint-942/global_step942/bf16_zero_pp_rank_1_mp_rank_00_optim_states.pt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4858a135049b98b9aa364311c5fbf77e482bdf035726ae5962dd3f4b021d3ffa +size 121135749 diff --git a/qwen3/amid/checkpoint-942/global_step942/mp_rank_00_model_states.pt b/qwen3/amid/checkpoint-942/global_step942/mp_rank_00_model_states.pt new file mode 100644 index 0000000000000000000000000000000000000000..5122c81878b1d13a21fdbe6fb35a872f7b98fa8a --- /dev/null +++ b/qwen3/amid/checkpoint-942/global_step942/mp_rank_00_model_states.pt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:45a146f178cca0f1049469fae5f2a961745eabf87ecd1fea5549d3f80cc853e0 +size 351841765 diff --git a/qwen3/amid/checkpoint-942/latest b/qwen3/amid/checkpoint-942/latest new file mode 100644 index 0000000000000000000000000000000000000000..4e9a68e4460aca593c480611a486d2a4cd73ef42 --- /dev/null +++ b/qwen3/amid/checkpoint-942/latest @@ -0,0 +1 @@ +global_step942 \ No newline at end of file diff --git a/qwen3/amid/checkpoint-942/rng_state_0.pth b/qwen3/amid/checkpoint-942/rng_state_0.pth new file mode 100644 index 0000000000000000000000000000000000000000..54f43bf1f663704b3073af0807e101057868ead8 --- /dev/null +++ b/qwen3/amid/checkpoint-942/rng_state_0.pth @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1dfb868039ddf2110ae2286a4ee4bea74f00ea64076a85da4fb4086aec87ba5d +size 14917 diff --git a/qwen3/amid/checkpoint-942/rng_state_1.pth b/qwen3/amid/checkpoint-942/rng_state_1.pth new file mode 100644 index 0000000000000000000000000000000000000000..f2fe299f679ce3632aaa6df223a4f01d59730243 --- /dev/null +++ b/qwen3/amid/checkpoint-942/rng_state_1.pth @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0eeb29092a9d04903a10dcd0c0f8397a7cade5f85c1d5bf69b75e46dd3a3ae3e +size 14917 diff --git a/qwen3/amid/checkpoint-942/scheduler.pt b/qwen3/amid/checkpoint-942/scheduler.pt new file mode 100644 index 0000000000000000000000000000000000000000..6b1f8af0480bf83ab728abfeff11bc3288214349 --- /dev/null +++ b/qwen3/amid/checkpoint-942/scheduler.pt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8076da6f897951c5bdf8649e4fba596e8c49819927746017442ffd85f40b18a3 +size 1465 diff --git a/qwen3/amid/checkpoint-942/tokenizer.json b/qwen3/amid/checkpoint-942/tokenizer.json new file mode 100644 index 0000000000000000000000000000000000000000..c7afbed2efcdf019f88ab0572ec29d3bf595dfe2 --- /dev/null +++ b/qwen3/amid/checkpoint-942/tokenizer.json @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:be75606093db2094d7cd20f3c2f385c212750648bd6ea4fb2bf507a6a4c55506 +size 11422650 diff --git a/qwen3/amid/checkpoint-942/tokenizer_config.json b/qwen3/amid/checkpoint-942/tokenizer_config.json new file mode 100644 index 0000000000000000000000000000000000000000..6623da03457d79d2cd4af9557e9f31407cdb835c --- /dev/null +++ b/qwen3/amid/checkpoint-942/tokenizer_config.json @@ -0,0 +1,31 @@ +{ + "add_prefix_space": false, + "backend": "tokenizers", + "bos_token": null, + "clean_up_tokenization_spaces": false, + "eos_token": "<|im_end|>", + "errors": "replace", + "extra_special_tokens": [ + "<|im_start|>", + "<|im_end|>", + "<|object_ref_start|>", + "<|object_ref_end|>", + "<|box_start|>", + "<|box_end|>", + "<|quad_start|>", + "<|quad_end|>", + "<|vision_start|>", + "<|vision_end|>", + "<|vision_pad|>", + "<|image_pad|>", + "<|video_pad|>" + ], + "is_local": false, + "local_files_only": false, + "model_max_length": 131072, + "pad_token": "<|endoftext|>", + "padding_side": "right", + "split_special_tokens": false, + "tokenizer_class": "Qwen2Tokenizer", + "unk_token": null +} diff --git a/qwen3/amid/checkpoint-942/trainer_state.json b/qwen3/amid/checkpoint-942/trainer_state.json new file mode 100644 index 0000000000000000000000000000000000000000..03fbdef9401c3d148fff75f43120c6c0c995e8a0 --- /dev/null +++ b/qwen3/amid/checkpoint-942/trainer_state.json @@ -0,0 +1,408 @@ +{ + "best_global_step": null, + "best_metric": null, + "best_model_checkpoint": null, + "epoch": 3.0, + "eval_steps": 500, + "global_step": 942, + "is_hyper_param_search": false, + "is_local_process_zero": true, + "is_world_process_zero": true, + "log_history": [ + { + "epoch": 0.06382130035899482, + "grad_norm": 0.38384687900543213, + "learning_rate": 9.996390385474569e-05, + "loss": 0.27438180446624755, + "step": 20 + }, + { + "epoch": 0.12764260071798963, + "grad_norm": 0.38263317942619324, + "learning_rate": 9.984797509888031e-05, + "loss": 0.13717052936553956, + "step": 40 + }, + { + "epoch": 0.19146390107698444, + "grad_norm": 0.08620006591081619, + "learning_rate": 9.965229938050925e-05, + "loss": 0.13135391473770142, + "step": 60 + }, + { + "epoch": 0.25528520143597927, + "grad_norm": 0.15773959457874298, + "learning_rate": 9.937719005663432e-05, + "loss": 0.1076702356338501, + "step": 80 + }, + { + "epoch": 0.3191065017949741, + "grad_norm": 0.22962816059589386, + "learning_rate": 9.902308769000724e-05, + "loss": 0.08698999881744385, + "step": 100 + }, + { + "epoch": 0.3829278021539689, + "grad_norm": 0.12232966721057892, + "learning_rate": 9.859055934360789e-05, + "loss": 0.1128507375717163, + "step": 120 + }, + { + "epoch": 0.4467491025129637, + "grad_norm": 0.15597161650657654, + "learning_rate": 9.808029767254437e-05, + "loss": 0.1277535080909729, + "step": 140 + }, + { + "epoch": 0.5105704028719585, + "grad_norm": 0.7329031825065613, + "learning_rate": 9.749311981482817e-05, + "loss": 0.08885469436645507, + "step": 160 + }, + { + "epoch": 0.5743917032309533, + "grad_norm": 0.45483648777008057, + "learning_rate": 9.682996608280154e-05, + "loss": 0.07881734371185303, + "step": 180 + }, + { + "epoch": 0.6382130035899481, + "grad_norm": 0.16407009959220886, + "learning_rate": 9.609189845731207e-05, + "loss": 0.06113555431365967, + "step": 200 + }, + { + "epoch": 0.702034303948943, + "grad_norm": 0.07238732278347015, + "learning_rate": 9.52800988870462e-05, + "loss": 0.06768973469734192, + "step": 220 + }, + { + "epoch": 0.7658556043079378, + "grad_norm": 0.4741341471672058, + "learning_rate": 9.439586739574513e-05, + "loss": 0.04917148947715759, + "step": 240 + }, + { + "epoch": 0.8296769046669326, + "grad_norm": 0.36410900950431824, + "learning_rate": 9.344062000033414e-05, + "loss": 0.010153122991323472, + "step": 260 + }, + { + "epoch": 0.8934982050259274, + "grad_norm": 0.11222824454307556, + "learning_rate": 9.241588644329919e-05, + "loss": 0.00552816241979599, + "step": 280 + }, + { + "epoch": 0.9573195053849222, + "grad_norm": 0.47910866141319275, + "learning_rate": 9.132330774294252e-05, + "loss": 0.006760746240615845, + "step": 300 + }, + { + "epoch": 1.0, + "eval_generator_count": 1712.0, + "eval_generator_exact_match": 87.3832, + "eval_generator_rouge1": 99.2069, + "eval_generator_rouge2": 98.8793, + "eval_generator_rougeL": 98.7553, + "eval_loss": 0.012839075177907944, + "eval_runtime": 592.0147, + "eval_samples_per_second": 5.767, + "eval_selector_accuracy": 90.1869, + "eval_selector_count": 1712.0, + "eval_steps_per_second": 0.181, + "step": 314 + }, + { + "epoch": 1.0191463901076985, + "grad_norm": 0.27295932173728943, + "learning_rate": 9.01646335654399e-05, + "loss": 0.009849193692207336, + "step": 320 + }, + { + "epoch": 1.0829676904666932, + "grad_norm": 0.060826949775218964, + "learning_rate": 8.894171942290817e-05, + "loss": 0.005673223733901977, + "step": 340 + }, + { + "epoch": 1.146788990825688, + "grad_norm": 0.04862668365240097, + "learning_rate": 8.765652370197003e-05, + "loss": 0.005297792330384255, + "step": 360 + }, + { + "epoch": 1.210610291184683, + "grad_norm": 0.05064748600125313, + "learning_rate": 8.631110452757467e-05, + "loss": 0.0021365636959671972, + "step": 380 + }, + { + "epoch": 1.2744315915436777, + "grad_norm": 0.05359279736876488, + "learning_rate": 8.490761646709642e-05, + "loss": 0.00429258793592453, + "step": 400 + }, + { + "epoch": 1.3382528919026724, + "grad_norm": 0.11369121074676514, + "learning_rate": 8.344830707998953e-05, + "loss": 0.0034508116543292998, + "step": 420 + }, + { + "epoch": 1.4020741922616673, + "grad_norm": 0.01604766771197319, + "learning_rate": 8.193551331852458e-05, + "loss": 0.0028350137174129484, + "step": 440 + }, + { + "epoch": 1.4658954926206622, + "grad_norm": 0.15401995182037354, + "learning_rate": 8.037165778537033e-05, + "loss": 0.005546276643872261, + "step": 460 + }, + { + "epoch": 1.5297167929796571, + "grad_norm": 0.5877118706703186, + "learning_rate": 7.875924485401427e-05, + "loss": 0.0044526983052492145, + "step": 480 + }, + { + "epoch": 1.5935380933386518, + "grad_norm": 0.10250785946846008, + "learning_rate": 7.710085665823444e-05, + "loss": 0.0056363165378570555, + "step": 500 + }, + { + "epoch": 1.6573593936976465, + "grad_norm": 0.043251167982816696, + "learning_rate": 7.539914895704521e-05, + "loss": 0.0032581716775894167, + "step": 520 + }, + { + "epoch": 1.7211806940566414, + "grad_norm": 0.2089434117078781, + "learning_rate": 7.365684688173908e-05, + "loss": 0.004207362234592438, + "step": 540 + }, + { + "epoch": 1.7850019944156363, + "grad_norm": 0.14037534594535828, + "learning_rate": 7.18767405718347e-05, + "loss": 0.0019151581451296805, + "step": 560 + }, + { + "epoch": 1.848823294774631, + "grad_norm": 0.22862067818641663, + "learning_rate": 7.006168070692036e-05, + "loss": 0.004427855834364891, + "step": 580 + }, + { + "epoch": 1.9126445951336257, + "grad_norm": 0.03684071823954582, + "learning_rate": 6.821457394154786e-05, + "loss": 0.0017833203077316285, + "step": 600 + }, + { + "epoch": 1.9764658954926206, + "grad_norm": 0.0672929510474205, + "learning_rate": 6.633837825048768e-05, + "loss": 0.0035866759717464447, + "step": 620 + }, + { + "epoch": 2.0, + "eval_generator_count": 1712.0, + "eval_generator_exact_match": 93.5164, + "eval_generator_rouge1": 99.7294, + "eval_generator_rouge2": 99.5697, + "eval_generator_rougeL": 99.5152, + "eval_loss": 0.006910035386681557, + "eval_runtime": 591.6591, + "eval_samples_per_second": 5.77, + "eval_selector_accuracy": 96.9042, + "eval_selector_count": 1712.0, + "eval_steps_per_second": 0.181, + "step": 628 + }, + { + "epoch": 2.038292780215397, + "grad_norm": 0.029134005308151245, + "learning_rate": 6.443609819179926e-05, + "loss": 0.0020816387608647347, + "step": 640 + }, + { + "epoch": 2.102114080574392, + "grad_norm": 0.17367292940616608, + "learning_rate": 6.251078009530256e-05, + "loss": 0.0019141122698783874, + "step": 660 + }, + { + "epoch": 2.1659353809333863, + "grad_norm": 0.016447540372610092, + "learning_rate": 6.0565507184155677e-05, + "loss": 0.0009251200594007969, + "step": 680 + }, + { + "epoch": 2.2297566812923812, + "grad_norm": 0.015570643357932568, + "learning_rate": 5.860339463735136e-05, + "loss": 0.0017806822434067726, + "step": 700 + }, + { + "epoch": 2.293577981651376, + "grad_norm": 0.010291235521435738, + "learning_rate": 5.662758460103895e-05, + "loss": 0.0010542120784521104, + "step": 720 + }, + { + "epoch": 2.357399282010371, + "grad_norm": 0.012873738072812557, + "learning_rate": 5.464124115666095e-05, + "loss": 0.0009571929462254047, + "step": 740 + }, + { + "epoch": 2.421220582369366, + "grad_norm": 0.009928264655172825, + "learning_rate": 5.264754525396212e-05, + "loss": 0.0007098949514329434, + "step": 760 + }, + { + "epoch": 2.4850418827283605, + "grad_norm": 0.014300181530416012, + "learning_rate": 5.06496896169857e-05, + "loss": 0.0007610605098307133, + "step": 780 + }, + { + "epoch": 2.5488631830873554, + "grad_norm": 0.03284010663628578, + "learning_rate": 4.865087363121384e-05, + "loss": 0.002758556976914406, + "step": 800 + }, + { + "epoch": 2.6126844834463503, + "grad_norm": 0.19087237119674683, + "learning_rate": 4.6654298220040673e-05, + "loss": 0.0011194748803973198, + "step": 820 + }, + { + "epoch": 2.6765057838053448, + "grad_norm": 0.02937050722539425, + "learning_rate": 4.466316071878229e-05, + "loss": 0.0014943076297640801, + "step": 840 + }, + { + "epoch": 2.74032708416434, + "grad_norm": 0.031206471845507622, + "learning_rate": 4.2680649754432913e-05, + "loss": 0.0027773819863796236, + "step": 860 + }, + { + "epoch": 2.8041483845233346, + "grad_norm": 0.019134322181344032, + "learning_rate": 4.070994013936646e-05, + "loss": 0.0018997505307197572, + "step": 880 + }, + { + "epoch": 2.8679696848823295, + "grad_norm": 0.2537505030632019, + "learning_rate": 3.8754187787161155e-05, + "loss": 0.0010082274675369263, + "step": 900 + }, + { + "epoch": 2.9317909852413244, + "grad_norm": 0.0017131563508883119, + "learning_rate": 3.681652465868875e-05, + "loss": 0.0012075364589691161, + "step": 920 + }, + { + "epoch": 2.995612285600319, + "grad_norm": 0.03925931081175804, + "learning_rate": 3.490005374656184e-05, + "loss": 0.000642749946564436, + "step": 940 + }, + { + "epoch": 3.0, + "eval_generator_count": 1712.0, + "eval_generator_exact_match": 95.3855, + "eval_generator_rouge1": 99.8982, + "eval_generator_rouge2": 99.8084, + "eval_generator_rougeL": 99.6633, + "eval_loss": 0.0056763943284749985, + "eval_runtime": 590.3317, + "eval_samples_per_second": 5.783, + "eval_selector_accuracy": 96.5537, + "eval_selector_count": 1712.0, + "eval_steps_per_second": 0.181, + "step": 942 + } + ], + "logging_steps": 20, + "max_steps": 1570, + "num_input_tokens_seen": 0, + "num_train_epochs": 5, + "save_steps": 500, + "stateful_callbacks": { + "TrainerControl": { + "args": { + "should_epoch_stop": false, + "should_evaluate": false, + "should_log": false, + "should_save": true, + "should_training_stop": false + }, + "attributes": {} + } + }, + "total_flos": 3.524157743353037e+16, + "train_batch_size": 2, + "trial_name": null, + "trial_params": null +} diff --git a/qwen3/amid/checkpoint-942/training_args.bin b/qwen3/amid/checkpoint-942/training_args.bin new file mode 100644 index 0000000000000000000000000000000000000000..571568fd8ab61d629f2a731739ee4c9e1309cca4 --- /dev/null +++ b/qwen3/amid/checkpoint-942/training_args.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e67133ff7a80f6f166c03bd5f62d9c580548b0f6840a1ce3891dee623991e47a +size 7185 diff --git a/qwen3/amid/checkpoint-942/zero_to_fp32.py b/qwen3/amid/checkpoint-942/zero_to_fp32.py new file mode 100644 index 0000000000000000000000000000000000000000..f40f1f0acbbff30e8e8d29906b56aae4e8b8a138 --- /dev/null +++ b/qwen3/amid/checkpoint-942/zero_to_fp32.py @@ -0,0 +1,790 @@ +#!/usr/bin/env python + +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: Apache-2.0 + +# DeepSpeed Team + +# This script extracts fp32 consolidated weights from a zero 1, 2 and 3 DeepSpeed checkpoints. It gets +# copied into the top level checkpoint dir, so the user can easily do the conversion at any point in +# the future. Once extracted, the weights don't require DeepSpeed and can be used in any +# application. +# +# example: +# python zero_to_fp32.py . output_dir/ +# or +# python zero_to_fp32.py . output_dir/ --safe_serialization + +import argparse +import torch +import glob +import math +import os +import re +import gc +import json +import numpy as np +from tqdm import tqdm +from collections import OrderedDict +from dataclasses import dataclass + +# while this script doesn't use deepspeed to recover data, since the checkpoints are pickled with +# DeepSpeed data structures it has to be available in the current python environment. +from deepspeed.utils import logger +from deepspeed.checkpoint.constants import (DS_VERSION, OPTIMIZER_STATE_DICT, SINGLE_PARTITION_OF_FP32_GROUPS, + FP32_FLAT_GROUPS, ZERO_STAGE, PARTITION_COUNT, PARAM_SHAPES, BUFFER_NAMES, + FROZEN_PARAM_SHAPES, FROZEN_PARAM_FRAGMENTS, AUTOEP_LAYERS_KEY, + AUTOEP_LAYERS_KEY_LEGACY, AUTOEP_ZERO3_EXPERT_STATE_FORMAT_KEY, + AUTOEP_ZERO3_PARTITIONED_EXPERT_STATE_FORMAT) + + +@dataclass +class zero_model_state: + buffers: dict() + param_shapes: dict() + shared_params: list + ds_version: int + frozen_param_shapes: dict() + frozen_param_fragments: dict() + + +debug = 0 + +# load to cpu +device = torch.device('cpu') + + +def atoi(text): + return int(text) if text.isdigit() else text + + +def natural_keys(text): + ''' + alist.sort(key=natural_keys) sorts in human order + http://nedbatchelder.com/blog/200712/human_sorting.html + (See Toothy's implementation in the comments) + ''' + return [atoi(c) for c in re.split(r'(\d+)', text)] + + +def get_model_state_file(checkpoint_dir, zero_stage): + if not os.path.isdir(checkpoint_dir): + raise FileNotFoundError(f"Directory '{checkpoint_dir}' doesn't exist") + + # there should be only one file + if zero_stage <= 2: + file = os.path.join(checkpoint_dir, "mp_rank_00_model_states.pt") + elif zero_stage == 3: + file = os.path.join(checkpoint_dir, "zero_pp_rank_0_mp_rank_00_model_states.pt") + + if not os.path.exists(file): + raise FileNotFoundError(f"can't find model states file at '{file}'") + + return file + + +def get_checkpoint_files(checkpoint_dir, glob_pattern): + # XXX: need to test that this simple glob rule works for multi-node setup too + ckpt_files = sorted(glob.glob(os.path.join(checkpoint_dir, glob_pattern)), key=natural_keys) + + if len(ckpt_files) == 0: + raise FileNotFoundError(f"can't find {glob_pattern} files in directory '{checkpoint_dir}'") + + return ckpt_files + + +def get_optim_files(checkpoint_dir): + return get_checkpoint_files(checkpoint_dir, "*_optim_states.pt") + + +def get_model_state_files(checkpoint_dir): + return get_checkpoint_files(checkpoint_dir, "*_model_states.pt") + + +def _has_autoep_zero3_partitioned_metadata(state_dict): + autoep_layers = state_dict.get(AUTOEP_LAYERS_KEY) + if autoep_layers is None: + autoep_layers = state_dict.get(AUTOEP_LAYERS_KEY_LEGACY) + if not isinstance(autoep_layers, list): + return False + return any( + isinstance(entry, dict) + and entry.get(AUTOEP_ZERO3_EXPERT_STATE_FORMAT_KEY) == AUTOEP_ZERO3_PARTITIONED_EXPERT_STATE_FORMAT + for entry in autoep_layers) + + +def _raise_if_autoep_zero3_partitioned_state(state_dict): + if _has_autoep_zero3_partitioned_metadata(state_dict): + raise NotImplementedError("zero_to_fp32 does not support AutoEP ZeRO-3 partition-native checkpoints. " + "AutoEP expert parameters are partitioned over expert replica groups, so " + "global data-parallel consolidation would produce incomplete expert tensors. " + "Use ds_to_universal.py for expert-aware conversion.") + + +def _raise_if_autoep_zero3_partitioned_checkpoint(model_files): + for file in model_files: + state_dict = torch.load(file, map_location=device, weights_only=False) + _raise_if_autoep_zero3_partitioned_state(state_dict) + + +def parse_model_states(files): + zero_model_states = [] + for file in files: + state_dict = torch.load(file, map_location=device, weights_only=False) + _raise_if_autoep_zero3_partitioned_state(state_dict) + + if BUFFER_NAMES not in state_dict: + raise ValueError(f"{file} is not a model state checkpoint") + buffer_names = state_dict[BUFFER_NAMES] + if debug: + print("Found buffers:", buffer_names) + + # recover just the buffers while restoring them to fp32 if they were saved in fp16 + buffers = {k: v.float() for k, v in state_dict["module"].items() if k in buffer_names} + param_shapes = state_dict[PARAM_SHAPES] + + # collect parameters that are included in param_shapes + param_names = [] + for s in param_shapes: + for name in s.keys(): + param_names.append(name) + + # update with frozen parameters + frozen_param_shapes = state_dict.get(FROZEN_PARAM_SHAPES, None) + if frozen_param_shapes is not None: + if debug: + print(f"Found frozen_param_shapes: {frozen_param_shapes}") + param_names += list(frozen_param_shapes.keys()) + + # handle shared params + shared_params = [[k, v] for k, v in state_dict["shared_params"].items()] + + ds_version = state_dict.get(DS_VERSION, None) + + frozen_param_fragments = state_dict.get(FROZEN_PARAM_FRAGMENTS, None) + + z_model_state = zero_model_state(buffers=buffers, + param_shapes=param_shapes, + shared_params=shared_params, + ds_version=ds_version, + frozen_param_shapes=frozen_param_shapes, + frozen_param_fragments=frozen_param_fragments) + zero_model_states.append(z_model_state) + + return zero_model_states + + +def parse_optim_states(files, ds_checkpoint_dir): + total_files = len(files) + state_dicts = [] + for f in tqdm(files, desc='Loading checkpoint shards'): + state_dict = torch.load(f, map_location=device, mmap=True, weights_only=False) + # immediately discard the potentially huge 2 optimizer states as we only care for fp32 master weights + # and also handle the case where it was already removed by another helper script + state_dict["optimizer_state_dict"].pop("optimizer_state_dict", None) + state_dicts.append(state_dict) + + if ZERO_STAGE not in state_dicts[0][OPTIMIZER_STATE_DICT]: + raise ValueError(f"{files[0]} is not a zero checkpoint") + zero_stage = state_dicts[0][OPTIMIZER_STATE_DICT][ZERO_STAGE] + world_size = state_dicts[0][OPTIMIZER_STATE_DICT][PARTITION_COUNT] + + # For ZeRO-2 each param group can have different partition_count as data parallelism for expert + # parameters can be different from data parallelism for non-expert parameters. So we can just + # use the max of the partition_count to get the dp world_size. + + if type(world_size) is list: + world_size = max(world_size) + + if world_size != total_files: + raise ValueError( + f"Expected {world_size} of '*_optim_states.pt' under '{ds_checkpoint_dir}' but found {total_files} files. " + "Possibly due to an overwrite of an old checkpoint, or a checkpoint didn't get saved by one or more processes." + ) + + # the groups are named differently in each stage + if zero_stage <= 2: + fp32_groups_key = SINGLE_PARTITION_OF_FP32_GROUPS + elif zero_stage == 3: + fp32_groups_key = FP32_FLAT_GROUPS + else: + raise ValueError(f"unknown zero stage {zero_stage}") + + fp32_flat_groups = [state_dicts[i][OPTIMIZER_STATE_DICT][fp32_groups_key] for i in range(len(state_dicts))] + return zero_stage, world_size, fp32_flat_groups + + +def _get_fp32_state_dict_from_zero_checkpoint(ds_checkpoint_dir, exclude_frozen_parameters): + """ + Returns fp32 state_dict reconstructed from ds checkpoint + + Args: + - ``ds_checkpoint_dir``: path to the deepspeed checkpoint folder (where the optimizer files are) + + """ + print(f"Processing zero checkpoint '{ds_checkpoint_dir}'") + + # parse_model_states rejects AutoEP ZeRO-3 partition-native checkpoints + # before the expensive optimizer-shard load below. + model_files = get_model_state_files(ds_checkpoint_dir) + zero_model_states = parse_model_states(model_files) + print(f'Parsing checkpoint created by deepspeed=={zero_model_states[0].ds_version}') + + optim_files = get_optim_files(ds_checkpoint_dir) + zero_stage, world_size, fp32_flat_groups = parse_optim_states(optim_files, ds_checkpoint_dir) + print(f"Detected checkpoint of type zero stage {zero_stage}, world_size: {world_size}") + + if zero_stage <= 2: + return _get_fp32_state_dict_from_zero2_checkpoint(world_size, fp32_flat_groups, zero_model_states, + exclude_frozen_parameters) + elif zero_stage == 3: + return _get_fp32_state_dict_from_zero3_checkpoint(world_size, fp32_flat_groups, zero_model_states, + exclude_frozen_parameters) + + +def _zero2_merge_frozen_params(state_dict, zero_model_states): + if zero_model_states[0].frozen_param_shapes is None or len(zero_model_states[0].frozen_param_shapes) == 0: + return + + frozen_param_shapes = zero_model_states[0].frozen_param_shapes + frozen_param_fragments = zero_model_states[0].frozen_param_fragments + + if debug: + num_elem = sum(s.numel() for s in frozen_param_shapes.values()) + print(f'rank 0: {FROZEN_PARAM_SHAPES}.numel = {num_elem}') + + wanted_params = len(frozen_param_shapes) + wanted_numel = sum(s.numel() for s in frozen_param_shapes.values()) + avail_numel = sum([p.numel() for p in frozen_param_fragments.values()]) + print(f'Frozen params: Have {avail_numel} numels to process.') + print(f'Frozen params: Need {wanted_numel} numels in {wanted_params} params') + + total_params = 0 + total_numel = 0 + for name, shape in frozen_param_shapes.items(): + total_params += 1 + unpartitioned_numel = shape.numel() + total_numel += unpartitioned_numel + + state_dict[name] = frozen_param_fragments[name] + + if debug: + print(f"{name} full shape: {shape} unpartitioned numel {unpartitioned_numel} ") + + print(f"Reconstructed Frozen fp32 state dict with {total_params} params {total_numel} elements") + + +def _has_callable(obj, fn): + attr = getattr(obj, fn, None) + return callable(attr) + + +def _zero2_merge_trainable_params(state_dict, world_size, fp32_flat_groups, zero_model_states): + param_shapes = zero_model_states[0].param_shapes + + # Reconstruction protocol: + # + # XXX: document this + + if debug: + for i in range(world_size): + for j in range(len(fp32_flat_groups[0])): + print(f"{FP32_FLAT_GROUPS}[{i}][{j}].shape={fp32_flat_groups[i][j].shape}") + + # XXX: memory usage doubles here (zero2) + num_param_groups = len(fp32_flat_groups[0]) + merged_single_partition_of_fp32_groups = [] + for i in range(num_param_groups): + merged_partitions = [sd[i] for sd in fp32_flat_groups] + full_single_fp32_vector = torch.cat(merged_partitions, 0) + merged_single_partition_of_fp32_groups.append(full_single_fp32_vector) + avail_numel = sum( + [full_single_fp32_vector.numel() for full_single_fp32_vector in merged_single_partition_of_fp32_groups]) + + if debug: + wanted_params = sum([len(shapes) for shapes in param_shapes]) + wanted_numel = sum([sum(shape.numel() for shape in shapes.values()) for shapes in param_shapes]) + # not asserting if there is a mismatch due to possible padding + print(f"Have {avail_numel} numels to process.") + print(f"Need {wanted_numel} numels in {wanted_params} params.") + + # params + # XXX: for huge models that can't fit into the host's RAM we will have to recode this to support + # out-of-core computing solution + total_numel = 0 + total_params = 0 + for shapes, full_single_fp32_vector in zip(param_shapes, merged_single_partition_of_fp32_groups): + offset = 0 + avail_numel = full_single_fp32_vector.numel() + for name, shape in shapes.items(): + + unpartitioned_numel = shape.numel() if _has_callable(shape, 'numel') else math.prod(shape) + total_numel += unpartitioned_numel + total_params += 1 + + if debug: + print(f"{name} full shape: {shape} unpartitioned numel {unpartitioned_numel} ") + state_dict[name] = full_single_fp32_vector.narrow(0, offset, unpartitioned_numel).view(shape) + offset += unpartitioned_numel + + # Z2 started to align to 2*world_size to improve nccl performance. Therefore both offset and + # avail_numel can differ by anywhere between 0..2*world_size. Due to two unrelated complex + # paddings performed in the code it's almost impossible to predict the exact numbers w/o the + # live optimizer object, so we are checking that the numbers are within the right range + align_to = 2 * world_size + + def zero2_align(x): + return align_to * math.ceil(x / align_to) + + if debug: + print(f"original offset={offset}, avail_numel={avail_numel}") + + offset = zero2_align(offset) + avail_numel = zero2_align(avail_numel) + + if debug: + print(f"aligned offset={offset}, avail_numel={avail_numel}") + + # Sanity check + if offset != avail_numel: + raise ValueError(f"consumed {offset} numels out of {avail_numel} - something is wrong") + + print(f"Reconstructed fp32 state dict with {total_params} params {total_numel} elements") + + +def _get_fp32_state_dict_from_zero2_checkpoint(world_size, fp32_flat_groups, zero_model_states, + exclude_frozen_parameters): + state_dict = OrderedDict() + + # buffers + buffers = zero_model_states[0].buffers + state_dict.update(buffers) + if debug: + print(f"added {len(buffers)} buffers") + + if not exclude_frozen_parameters: + _zero2_merge_frozen_params(state_dict, zero_model_states) + + _zero2_merge_trainable_params(state_dict, world_size, fp32_flat_groups, zero_model_states) + + # recover shared parameters + for pair in zero_model_states[0].shared_params: + if pair[1] in state_dict: + state_dict[pair[0]] = state_dict[pair[1]] + + return state_dict + + +def zero3_partitioned_param_info(unpartitioned_numel, world_size): + remainder = unpartitioned_numel % world_size + padding_numel = (world_size - remainder) if remainder else 0 + partitioned_numel = math.ceil(unpartitioned_numel / world_size) + return partitioned_numel, padding_numel + + +def _zero3_merge_frozen_params(state_dict, world_size, zero_model_states): + if zero_model_states[0].frozen_param_shapes is None or len(zero_model_states[0].frozen_param_shapes) == 0: + return + + if debug: + for i in range(world_size): + num_elem = sum(s.numel() for s in zero_model_states[i].frozen_param_fragments.values()) + print(f'rank {i}: {FROZEN_PARAM_SHAPES}.numel = {num_elem}') + + frozen_param_shapes = zero_model_states[0].frozen_param_shapes + wanted_params = len(frozen_param_shapes) + wanted_numel = sum(s.numel() for s in frozen_param_shapes.values()) + avail_numel = sum([p.numel() for p in zero_model_states[0].frozen_param_fragments.values()]) * world_size + print(f'Frozen params: Have {avail_numel} numels to process.') + print(f'Frozen params: Need {wanted_numel} numels in {wanted_params} params') + + total_params = 0 + total_numel = 0 + for name, shape in zero_model_states[0].frozen_param_shapes.items(): + total_params += 1 + unpartitioned_numel = shape.numel() + total_numel += unpartitioned_numel + + param_frags = tuple(model_state.frozen_param_fragments[name] for model_state in zero_model_states) + state_dict[name] = torch.cat(param_frags, 0).narrow(0, 0, unpartitioned_numel).view(shape) + + partitioned_numel, partitioned_padding_numel = zero3_partitioned_param_info(unpartitioned_numel, world_size) + + if debug: + print( + f"Frozen params: {total_params} {name} full shape: {shape} partition0 numel={partitioned_numel} partitioned_padding_numel={partitioned_padding_numel}" + ) + + print(f"Reconstructed Frozen fp32 state dict with {total_params} params {total_numel} elements") + + +class GatheredTensor: + """ + A pseudo tensor that collects partitioned weights. + It is more memory efficient when there are multiple groups. + """ + + def __init__(self, flat_groups, flat_groups_offset, offset, partitioned_numel, shape): + self.flat_groups = flat_groups + self.flat_groups_offset = flat_groups_offset + self.offset = offset + self.partitioned_numel = partitioned_numel + self.shape = shape + self.dtype = self.flat_groups[0][0].dtype + + def contiguous(self): + """ + Merge partitioned weights from flat_groups into a single tensor. + """ + end_idx = self.offset + self.partitioned_numel + world_size = len(self.flat_groups) + pad_flat_param_chunks = [] + + for rank_i in range(world_size): + # for each rank, we need to collect weights from related group/groups + flat_groups_at_rank_i = self.flat_groups[rank_i] + start_group_id = None + end_group_id = None + for group_id in range(len(self.flat_groups_offset)): + if self.flat_groups_offset[group_id] <= self.offset < self.flat_groups_offset[group_id + 1]: + start_group_id = group_id + if self.flat_groups_offset[group_id] < end_idx <= self.flat_groups_offset[group_id + 1]: + end_group_id = group_id + break + # collect weights from related group/groups + for group_id in range(start_group_id, end_group_id + 1): + flat_tensor = flat_groups_at_rank_i[group_id] + start_offset = self.offset - self.flat_groups_offset[group_id] + end_offset = min(end_idx, self.flat_groups_offset[group_id + 1]) - self.flat_groups_offset[group_id] + pad_flat_param_chunks.append(flat_tensor[start_offset:end_offset]) + + # collect weights from all ranks + pad_flat_param = torch.cat(pad_flat_param_chunks, dim=0) + param = pad_flat_param[:self.shape.numel()].view(self.shape).contiguous() + return param + + +def _zero3_merge_trainable_params(state_dict, world_size, fp32_flat_groups, zero_model_states): + param_shapes = zero_model_states[0].param_shapes + avail_numel = sum([flat_group.numel() for flat_group in fp32_flat_groups[0]]) * world_size + + # Reconstruction protocol: For zero3 we need to zip the partitions together at boundary of each + # param, re-consolidating each param, while dealing with padding if any + + # merge list of dicts, preserving order + param_shapes = {k: v for d in param_shapes for k, v in d.items()} + + if debug: + for i in range(world_size): + print(f"{FP32_FLAT_GROUPS}[{i}].shape={fp32_flat_groups[i].shape}") + + wanted_params = len(param_shapes) + wanted_numel = sum(shape.numel() for shape in param_shapes.values()) + # not asserting if there is a mismatch due to possible padding + avail_numel = fp32_flat_groups[0].numel() * world_size + print(f"Trainable params: Have {avail_numel} numels to process.") + print(f"Trainable params: Need {wanted_numel} numels in {wanted_params} params.") + + # params + # XXX: for huge models that can't fit into the host's RAM we will have to recode this to support + # out-of-core computing solution + offset = 0 + total_numel = 0 + total_params = 0 + flat_groups_offset = [0] + list(np.cumsum([flat_tensor.numel() for flat_tensor in fp32_flat_groups[0]])) + for name, shape in tqdm(param_shapes.items(), desc='Gathering sharded weights'): + unpartitioned_numel = shape.numel() + total_numel += unpartitioned_numel + total_params += 1 + partitioned_numel, partitioned_padding_numel = zero3_partitioned_param_info(unpartitioned_numel, world_size) + + if debug: + print( + f"Trainable params: {total_params} {name} full shape: {shape} partition0 numel={partitioned_numel} partitioned_padding_numel={partitioned_padding_numel}" + ) + + # memory efficient tensor + tensor = GatheredTensor(fp32_flat_groups, flat_groups_offset, offset, partitioned_numel, shape) + state_dict[name] = tensor + offset += partitioned_numel + + offset *= world_size + + # Sanity check + if offset != avail_numel: + raise ValueError(f"consumed {offset} numels out of {avail_numel} - something is wrong") + + print(f"Reconstructed Trainable fp32 state dict with {total_params} params {total_numel} elements") + + +def _get_fp32_state_dict_from_zero3_checkpoint(world_size, fp32_flat_groups, zero_model_states, + exclude_frozen_parameters): + state_dict = OrderedDict() + + # buffers + buffers = zero_model_states[0].buffers + state_dict.update(buffers) + if debug: + print(f"added {len(buffers)} buffers") + + if not exclude_frozen_parameters: + _zero3_merge_frozen_params(state_dict, world_size, zero_model_states) + + _zero3_merge_trainable_params(state_dict, world_size, fp32_flat_groups, zero_model_states) + + # recover shared parameters + for pair in zero_model_states[0].shared_params: + if pair[1] in state_dict: + state_dict[pair[0]] = state_dict[pair[1]] + + return state_dict + + +def to_torch_tensor(state_dict, return_empty_tensor=False): + """ + Convert state_dict of GatheredTensor to torch tensor + """ + torch_state_dict = {} + converted_tensors = {} + for name, tensor in state_dict.items(): + tensor_id = id(tensor) + if tensor_id in converted_tensors: # shared tensors + shared_tensor = torch_state_dict[converted_tensors[tensor_id]] + torch_state_dict[name] = shared_tensor + else: + converted_tensors[tensor_id] = name + if return_empty_tensor: + torch_state_dict[name] = torch.empty(tensor.shape, dtype=tensor.dtype) + else: + torch_state_dict[name] = tensor.contiguous() + return torch_state_dict + + +def get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir, + tag=None, + exclude_frozen_parameters=False, + lazy_mode=False): + """ + Convert ZeRO 2 or 3 checkpoint into a single fp32 consolidated state_dict that can be loaded with + ``load_state_dict()`` and used for training without DeepSpeed or shared with others, for example + via a model hub. + + Args: + - ``checkpoint_dir``: path to the desired checkpoint folder + - ``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`` + - ``exclude_frozen_parameters``: exclude frozen parameters + - ``lazy_mode``: get state_dict in lazy mode. It returns a dict of pesduo tensor instead of torch tensor, which is more memory efficient. + Convert the pesduo tensor to torch tensor by ``.contiguous()`` + + Returns: + - pytorch ``state_dict`` + + A typical usage might be :: + + from deepspeed.utils.zero_to_fp32 import get_fp32_state_dict_from_zero_checkpoint + # do the training and checkpoint saving + state_dict = get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir) # already on cpu + model = model.cpu() # move to cpu + model.load_state_dict(state_dict) + # submit to model hub or save the model to share with others + + In this example the ``model`` will no longer be usable in the deepspeed context of the same + application. i.e. you will need to re-initialize the deepspeed engine, since + ``model.load_state_dict(state_dict)`` will remove all the deepspeed magic from it. + + If you want it all done for you, use ``load_state_dict_from_zero_checkpoint`` instead. + + Note: the above usage may not work if your application doesn't have sufficient free CPU memory. + You may need to use the offline approach using the ``zero_to_fp32.py`` script that is saved with + the checkpoint. Or you can load state_dict in lazy mode :: + + from deepspeed.utils.zero_to_fp32 import get_fp32_state_dict_from_zero_checkpoint + state_dict = get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir, lazy_mode=True) # not on cpu + for name, lazy_tensor in state_dict.item(): + tensor = lazy_tensor.contiguous() # to cpu + print(name, tensor) + # del tensor to release memory if it no longer in use + """ + if tag is None: + latest_path = os.path.join(checkpoint_dir, 'latest') + if os.path.isfile(latest_path): + with open(latest_path, 'r') as fd: + tag = fd.read().strip() + else: + raise ValueError(f"Unable to find 'latest' file at {latest_path}") + + ds_checkpoint_dir = os.path.join(checkpoint_dir, tag) + + if not os.path.isdir(ds_checkpoint_dir): + raise FileNotFoundError(f"Directory '{ds_checkpoint_dir}' doesn't exist") + + state_dict = _get_fp32_state_dict_from_zero_checkpoint(ds_checkpoint_dir, exclude_frozen_parameters) + if lazy_mode: + return state_dict + else: + return to_torch_tensor(state_dict) + + +def convert_zero_checkpoint_to_fp32_state_dict(checkpoint_dir, + output_dir, + max_shard_size="5GB", + safe_serialization=False, + tag=None, + exclude_frozen_parameters=False): + """ + Convert ZeRO 2 or 3 checkpoint into a single fp32 consolidated ``state_dict`` file that can be + loaded with ``torch.load(file)`` + ``load_state_dict()`` and used for training without DeepSpeed. + + Args: + - ``checkpoint_dir``: path to the desired checkpoint folder. (one that contains the tag-folder, like ``global_step14``) + - ``output_dir``: directory to the pytorch fp32 state_dict output files + - ``max_shard_size``: the maximum size for a checkpoint before being sharded, default value is 5GB + - ``safe_serialization``: whether to save the model using `safetensors` or the traditional PyTorch way (that uses `pickle`). + - ``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`` + - ``exclude_frozen_parameters``: exclude frozen parameters + """ + + # Dependency pre-check + if safe_serialization: + try: + from safetensors.torch import save_file + except ImportError: + print('If you want to use `safe_serialization`, please `pip install safetensors`') + raise + if max_shard_size is not None: + try: + from huggingface_hub import split_torch_state_dict_into_shards + except ImportError: + print('If you want to use `max_shard_size`, please `pip install huggingface_hub`') + raise + + # Convert zero checkpoint to state_dict + state_dict = get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir, + tag, + exclude_frozen_parameters, + lazy_mode=True) + + # Shard the model if it is too big. + weights_name = "model.safetensors" if safe_serialization else "pytorch_model.bin" + if max_shard_size is not None: + filename_pattern = weights_name.replace(".bin", "{suffix}.bin").replace(".safetensors", "{suffix}.safetensors") + # an memory-efficient approach for sharding + empty_state_dict = to_torch_tensor(state_dict, return_empty_tensor=True) + state_dict_split = split_torch_state_dict_into_shards(empty_state_dict, + filename_pattern=filename_pattern, + max_shard_size=max_shard_size) + else: + from collections import namedtuple + StateDictSplit = namedtuple("StateDictSplit", ["is_sharded", "filename_to_tensors"]) + state_dict_split = StateDictSplit(is_sharded=False, + filename_to_tensors={weights_name: list(state_dict.keys())}) + + # Save the model by shard + os.makedirs(output_dir, exist_ok=True) + filename_to_tensors = state_dict_split.filename_to_tensors.items() + for shard_file, tensors in tqdm(filename_to_tensors, desc="Saving checkpoint shards"): + shard_state_dict = {tensor_name: state_dict[tensor_name] for tensor_name in tensors} + shard_state_dict = to_torch_tensor(shard_state_dict) + output_path = os.path.join(output_dir, shard_file) + if safe_serialization: + save_file(shard_state_dict, output_path, metadata={"format": "pt"}) + else: + torch.save(shard_state_dict, output_path) + # release the memory of current shard + for tensor_name in list(shard_state_dict.keys()): + del state_dict[tensor_name] + del shard_state_dict[tensor_name] + del shard_state_dict + gc.collect() + + # Save index if sharded + if state_dict_split.is_sharded: + index = { + "metadata": state_dict_split.metadata, + "weight_map": state_dict_split.tensor_to_filename, + } + save_index_file = "model.safetensors.index.json" if safe_serialization else "pytorch_model.bin.index.json" + save_index_file = os.path.join(output_dir, save_index_file) + with open(save_index_file, "w", encoding="utf-8") as f: + content = json.dumps(index, indent=2, sort_keys=True) + "\n" + f.write(content) + + +def load_state_dict_from_zero_checkpoint(model, checkpoint_dir, tag=None): + """ + 1. Put the provided model to cpu + 2. Convert ZeRO 2 or 3 checkpoint into a single fp32 consolidated ``state_dict`` + 3. Load it into the provided model + + Args: + - ``model``: the model object to update + - ``checkpoint_dir``: path to the desired checkpoint folder. (one that contains the tag-folder, like ``global_step14``) + - ``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`` + + Returns: + - ``model`: modified model + + Make sure you have plenty of CPU memory available before you call this function. If you don't + have enough use the ``zero_to_fp32.py`` utility to do the conversion. You will find it + conveniently placed for you in the checkpoint folder. + + A typical usage might be :: + + from deepspeed.utils.zero_to_fp32 import load_state_dict_from_zero_checkpoint + model = load_state_dict_from_zero_checkpoint(trainer.model, checkpoint_dir) + # submit to model hub or save the model to share with others + + Note, that once this was run, the ``model`` will no longer be usable in the deepspeed context + of the same application. i.e. you will need to re-initialize the deepspeed engine, since + ``model.load_state_dict(state_dict)`` will remove all the deepspeed magic from it. + + """ + logger.info("Extracting fp32 weights") + state_dict = get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir, tag) + + logger.info("Overwriting model with fp32 weights") + model = model.cpu() + model.load_state_dict(state_dict, strict=False) + + return model + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument("checkpoint_dir", + type=str, + help="path to the desired checkpoint folder, e.g., path/checkpoint-12") + parser.add_argument("output_dir", + type=str, + help="directory to the pytorch fp32 state_dict output files" + "(e.g. path/checkpoint-12-output/)") + parser.add_argument( + "--max_shard_size", + type=str, + default="5GB", + help="The maximum size for a checkpoint before being sharded. Checkpoints shard will then be each of size" + "lower than this size. If expressed as a string, needs to be digits followed by a unit (like `5MB`" + "We default it to 5GB in order for models to be able to run easily on free-tier google colab instances" + "without CPU OOM issues.") + parser.add_argument( + "--safe_serialization", + default=False, + action='store_true', + help="Whether to save the model using `safetensors` or the traditional PyTorch way (that uses `pickle`).") + parser.add_argument("-t", + "--tag", + type=str, + default=None, + help="checkpoint tag used as a unique identifier for checkpoint. e.g., global_step1") + parser.add_argument("--exclude_frozen_parameters", action='store_true', help="exclude frozen parameters") + parser.add_argument("-d", "--debug", action='store_true', help="enable debug") + args = parser.parse_args() + + debug = args.debug + + convert_zero_checkpoint_to_fp32_state_dict(args.checkpoint_dir, + args.output_dir, + max_shard_size=args.max_shard_size, + safe_serialization=args.safe_serialization, + tag=args.tag, + exclude_frozen_parameters=args.exclude_frozen_parameters) diff --git a/qwen3/amid/eval_results.json b/qwen3/amid/eval_results.json new file mode 100644 index 0000000000000000000000000000000000000000..000c38aea42d8d2cd1a4372ff0a248dbdcdfdb29 --- /dev/null +++ b/qwen3/amid/eval_results.json @@ -0,0 +1,14 @@ +{ + "epoch": 5.0, + "eval_generator_count": 1712.0, + "eval_generator_exact_match": 96.028, + "eval_generator_rouge1": 99.8671, + "eval_generator_rouge2": 99.8011, + "eval_generator_rougeL": 99.6739, + "eval_loss": 0.004025007598102093, + "eval_runtime": 579.6459, + "eval_samples_per_second": 5.89, + "eval_selector_accuracy": 98.6565, + "eval_selector_count": 1712.0, + "eval_steps_per_second": 0.185 +} \ No newline at end of file diff --git a/qwen3/amid/tokenizer.json b/qwen3/amid/tokenizer.json new file mode 100644 index 0000000000000000000000000000000000000000..c7afbed2efcdf019f88ab0572ec29d3bf595dfe2 --- /dev/null +++ b/qwen3/amid/tokenizer.json @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:be75606093db2094d7cd20f3c2f385c212750648bd6ea4fb2bf507a6a4c55506 +size 11422650 diff --git a/qwen3/amid/tokenizer_config.json b/qwen3/amid/tokenizer_config.json new file mode 100644 index 0000000000000000000000000000000000000000..6623da03457d79d2cd4af9557e9f31407cdb835c --- /dev/null +++ b/qwen3/amid/tokenizer_config.json @@ -0,0 +1,31 @@ +{ + "add_prefix_space": false, + "backend": "tokenizers", + "bos_token": null, + "clean_up_tokenization_spaces": false, + "eos_token": "<|im_end|>", + "errors": "replace", + "extra_special_tokens": [ + "<|im_start|>", + "<|im_end|>", + "<|object_ref_start|>", + "<|object_ref_end|>", + "<|box_start|>", + "<|box_end|>", + "<|quad_start|>", + "<|quad_end|>", + "<|vision_start|>", + "<|vision_end|>", + "<|vision_pad|>", + "<|image_pad|>", + "<|video_pad|>" + ], + "is_local": false, + "local_files_only": false, + "model_max_length": 131072, + "pad_token": "<|endoftext|>", + "padding_side": "right", + "split_special_tokens": false, + "tokenizer_class": "Qwen2Tokenizer", + "unk_token": null +} diff --git a/qwen3/amid/train_results.json b/qwen3/amid/train_results.json new file mode 100644 index 0000000000000000000000000000000000000000..cb24c11958e8a5666c3d9051ba3435bc54cc5d4b --- /dev/null +++ b/qwen3/amid/train_results.json @@ -0,0 +1,8 @@ +{ + "epoch": 5.0, + "total_flos": 5.871444840310374e+16, + "train_loss": 0.01864182253792336, + "train_runtime": 7621.8556, + "train_samples_per_second": 6.578, + "train_steps_per_second": 0.206 +} \ No newline at end of file diff --git a/qwen3/amid/trainer_state.json b/qwen3/amid/trainer_state.json new file mode 100644 index 0000000000000000000000000000000000000000..2cca169a60a34350c1c45267e33165ea7b674a70 --- /dev/null +++ b/qwen3/amid/trainer_state.json @@ -0,0 +1,664 @@ +{ + "best_global_step": null, + "best_metric": null, + "best_model_checkpoint": null, + "epoch": 5.0, + "eval_steps": 500, + "global_step": 1570, + "is_hyper_param_search": false, + "is_local_process_zero": true, + "is_world_process_zero": true, + "log_history": [ + { + "epoch": 0.06382130035899482, + "grad_norm": 0.38384687900543213, + "learning_rate": 9.996390385474569e-05, + "loss": 0.27438180446624755, + "step": 20 + }, + { + "epoch": 0.12764260071798963, + "grad_norm": 0.38263317942619324, + "learning_rate": 9.984797509888031e-05, + "loss": 0.13717052936553956, + "step": 40 + }, + { + "epoch": 0.19146390107698444, + "grad_norm": 0.08620006591081619, + "learning_rate": 9.965229938050925e-05, + "loss": 0.13135391473770142, + "step": 60 + }, + { + "epoch": 0.25528520143597927, + "grad_norm": 0.15773959457874298, + "learning_rate": 9.937719005663432e-05, + "loss": 0.1076702356338501, + "step": 80 + }, + { + "epoch": 0.3191065017949741, + "grad_norm": 0.22962816059589386, + "learning_rate": 9.902308769000724e-05, + "loss": 0.08698999881744385, + "step": 100 + }, + { + "epoch": 0.3829278021539689, + "grad_norm": 0.12232966721057892, + "learning_rate": 9.859055934360789e-05, + "loss": 0.1128507375717163, + "step": 120 + }, + { + "epoch": 0.4467491025129637, + "grad_norm": 0.15597161650657654, + "learning_rate": 9.808029767254437e-05, + "loss": 0.1277535080909729, + "step": 140 + }, + { + "epoch": 0.5105704028719585, + "grad_norm": 0.7329031825065613, + "learning_rate": 9.749311981482817e-05, + "loss": 0.08885469436645507, + "step": 160 + }, + { + "epoch": 0.5743917032309533, + "grad_norm": 0.45483648777008057, + "learning_rate": 9.682996608280154e-05, + "loss": 0.07881734371185303, + "step": 180 + }, + { + "epoch": 0.6382130035899481, + "grad_norm": 0.16407009959220886, + "learning_rate": 9.609189845731207e-05, + "loss": 0.06113555431365967, + "step": 200 + }, + { + "epoch": 0.702034303948943, + "grad_norm": 0.07238732278347015, + "learning_rate": 9.52800988870462e-05, + "loss": 0.06768973469734192, + "step": 220 + }, + { + "epoch": 0.7658556043079378, + "grad_norm": 0.4741341471672058, + "learning_rate": 9.439586739574513e-05, + "loss": 0.04917148947715759, + "step": 240 + }, + { + "epoch": 0.8296769046669326, + "grad_norm": 0.36410900950431824, + "learning_rate": 9.344062000033414e-05, + "loss": 0.010153122991323472, + "step": 260 + }, + { + "epoch": 0.8934982050259274, + "grad_norm": 0.11222824454307556, + "learning_rate": 9.241588644329919e-05, + "loss": 0.00552816241979599, + "step": 280 + }, + { + "epoch": 0.9573195053849222, + "grad_norm": 0.47910866141319275, + "learning_rate": 9.132330774294252e-05, + "loss": 0.006760746240615845, + "step": 300 + }, + { + "epoch": 1.0, + "eval_generator_count": 1712.0, + "eval_generator_exact_match": 87.3832, + "eval_generator_rouge1": 99.2069, + "eval_generator_rouge2": 98.8793, + "eval_generator_rougeL": 98.7553, + "eval_loss": 0.012839075177907944, + "eval_runtime": 592.0147, + "eval_samples_per_second": 5.767, + "eval_selector_accuracy": 90.1869, + "eval_selector_count": 1712.0, + "eval_steps_per_second": 0.181, + "step": 314 + }, + { + "epoch": 1.0191463901076985, + "grad_norm": 0.27295932173728943, + "learning_rate": 9.01646335654399e-05, + "loss": 0.009849193692207336, + "step": 320 + }, + { + "epoch": 1.0829676904666932, + "grad_norm": 0.060826949775218964, + "learning_rate": 8.894171942290817e-05, + "loss": 0.005673223733901977, + "step": 340 + }, + { + "epoch": 1.146788990825688, + "grad_norm": 0.04862668365240097, + "learning_rate": 8.765652370197003e-05, + "loss": 0.005297792330384255, + "step": 360 + }, + { + "epoch": 1.210610291184683, + "grad_norm": 0.05064748600125313, + "learning_rate": 8.631110452757467e-05, + "loss": 0.0021365636959671972, + "step": 380 + }, + { + "epoch": 1.2744315915436777, + "grad_norm": 0.05359279736876488, + "learning_rate": 8.490761646709642e-05, + "loss": 0.00429258793592453, + "step": 400 + }, + { + "epoch": 1.3382528919026724, + "grad_norm": 0.11369121074676514, + "learning_rate": 8.344830707998953e-05, + "loss": 0.0034508116543292998, + "step": 420 + }, + { + "epoch": 1.4020741922616673, + "grad_norm": 0.01604766771197319, + "learning_rate": 8.193551331852458e-05, + "loss": 0.0028350137174129484, + "step": 440 + }, + { + "epoch": 1.4658954926206622, + "grad_norm": 0.15401995182037354, + "learning_rate": 8.037165778537033e-05, + "loss": 0.005546276643872261, + "step": 460 + }, + { + "epoch": 1.5297167929796571, + "grad_norm": 0.5877118706703186, + "learning_rate": 7.875924485401427e-05, + "loss": 0.0044526983052492145, + "step": 480 + }, + { + "epoch": 1.5935380933386518, + "grad_norm": 0.10250785946846008, + "learning_rate": 7.710085665823444e-05, + "loss": 0.0056363165378570555, + "step": 500 + }, + { + "epoch": 1.6573593936976465, + "grad_norm": 0.043251167982816696, + "learning_rate": 7.539914895704521e-05, + "loss": 0.0032581716775894167, + "step": 520 + }, + { + "epoch": 1.7211806940566414, + "grad_norm": 0.2089434117078781, + "learning_rate": 7.365684688173908e-05, + "loss": 0.004207362234592438, + "step": 540 + }, + { + "epoch": 1.7850019944156363, + "grad_norm": 0.14037534594535828, + "learning_rate": 7.18767405718347e-05, + "loss": 0.0019151581451296805, + "step": 560 + }, + { + "epoch": 1.848823294774631, + "grad_norm": 0.22862067818641663, + "learning_rate": 7.006168070692036e-05, + "loss": 0.004427855834364891, + "step": 580 + }, + { + "epoch": 1.9126445951336257, + "grad_norm": 0.03684071823954582, + "learning_rate": 6.821457394154786e-05, + "loss": 0.0017833203077316285, + "step": 600 + }, + { + "epoch": 1.9764658954926206, + "grad_norm": 0.0672929510474205, + "learning_rate": 6.633837825048768e-05, + "loss": 0.0035866759717464447, + "step": 620 + }, + { + "epoch": 2.0, + "eval_generator_count": 1712.0, + "eval_generator_exact_match": 93.5164, + "eval_generator_rouge1": 99.7294, + "eval_generator_rouge2": 99.5697, + "eval_generator_rougeL": 99.5152, + "eval_loss": 0.006910035386681557, + "eval_runtime": 591.6591, + "eval_samples_per_second": 5.77, + "eval_selector_accuracy": 96.9042, + "eval_selector_count": 1712.0, + "eval_steps_per_second": 0.181, + "step": 628 + }, + { + "epoch": 2.038292780215397, + "grad_norm": 0.029134005308151245, + "learning_rate": 6.443609819179926e-05, + "loss": 0.0020816387608647347, + "step": 640 + }, + { + "epoch": 2.102114080574392, + "grad_norm": 0.17367292940616608, + "learning_rate": 6.251078009530256e-05, + "loss": 0.0019141122698783874, + "step": 660 + }, + { + "epoch": 2.1659353809333863, + "grad_norm": 0.016447540372610092, + "learning_rate": 6.0565507184155677e-05, + "loss": 0.0009251200594007969, + "step": 680 + }, + { + "epoch": 2.2297566812923812, + "grad_norm": 0.015570643357932568, + "learning_rate": 5.860339463735136e-05, + "loss": 0.0017806822434067726, + "step": 700 + }, + { + "epoch": 2.293577981651376, + "grad_norm": 0.010291235521435738, + "learning_rate": 5.662758460103895e-05, + "loss": 0.0010542120784521104, + "step": 720 + }, + { + "epoch": 2.357399282010371, + "grad_norm": 0.012873738072812557, + "learning_rate": 5.464124115666095e-05, + "loss": 0.0009571929462254047, + "step": 740 + }, + { + "epoch": 2.421220582369366, + "grad_norm": 0.009928264655172825, + "learning_rate": 5.264754525396212e-05, + "loss": 0.0007098949514329434, + "step": 760 + }, + { + "epoch": 2.4850418827283605, + "grad_norm": 0.014300181530416012, + "learning_rate": 5.06496896169857e-05, + "loss": 0.0007610605098307133, + "step": 780 + }, + { + "epoch": 2.5488631830873554, + "grad_norm": 0.03284010663628578, + "learning_rate": 4.865087363121384e-05, + "loss": 0.002758556976914406, + "step": 800 + }, + { + "epoch": 2.6126844834463503, + "grad_norm": 0.19087237119674683, + "learning_rate": 4.6654298220040673e-05, + "loss": 0.0011194748803973198, + "step": 820 + }, + { + "epoch": 2.6765057838053448, + "grad_norm": 0.02937050722539425, + "learning_rate": 4.466316071878229e-05, + "loss": 0.0014943076297640801, + "step": 840 + }, + { + "epoch": 2.74032708416434, + "grad_norm": 0.031206471845507622, + "learning_rate": 4.2680649754432913e-05, + "loss": 0.0027773819863796236, + "step": 860 + }, + { + "epoch": 2.8041483845233346, + "grad_norm": 0.019134322181344032, + "learning_rate": 4.070994013936646e-05, + "loss": 0.0018997505307197572, + "step": 880 + }, + { + "epoch": 2.8679696848823295, + "grad_norm": 0.2537505030632019, + "learning_rate": 3.8754187787161155e-05, + "loss": 0.0010082274675369263, + "step": 900 + }, + { + "epoch": 2.9317909852413244, + "grad_norm": 0.0017131563508883119, + "learning_rate": 3.681652465868875e-05, + "loss": 0.0012075364589691161, + "step": 920 + }, + { + "epoch": 2.995612285600319, + "grad_norm": 0.03925931081175804, + "learning_rate": 3.490005374656184e-05, + "loss": 0.000642749946564436, + "step": 940 + }, + { + "epoch": 3.0, + "eval_generator_count": 1712.0, + "eval_generator_exact_match": 95.3855, + "eval_generator_rouge1": 99.8982, + "eval_generator_rouge2": 99.8084, + "eval_generator_rougeL": 99.6633, + "eval_loss": 0.0056763943284749985, + "eval_runtime": 590.3317, + "eval_samples_per_second": 5.783, + "eval_selector_accuracy": 96.5537, + "eval_selector_count": 1712.0, + "eval_steps_per_second": 0.181, + "step": 942 + }, + { + "epoch": 3.057439170323095, + "grad_norm": 0.0036900911945849657, + "learning_rate": 3.3007844105971336e-05, + "loss": 0.0012762822210788728, + "step": 960 + }, + { + "epoch": 3.12126047068209, + "grad_norm": 0.028549807146191597, + "learning_rate": 3.114292593987149e-05, + "loss": 0.0006767791230231524, + "step": 980 + }, + { + "epoch": 3.185081771041085, + "grad_norm": 0.007299487479031086, + "learning_rate": 2.9308285746383408e-05, + "loss": 0.0012082518078386784, + "step": 1000 + }, + { + "epoch": 3.24890307140008, + "grad_norm": 0.03702578693628311, + "learning_rate": 2.7506861536187867e-05, + "loss": 0.0014168912544846534, + "step": 1020 + }, + { + "epoch": 3.3127243717590744, + "grad_norm": 0.21273940801620483, + "learning_rate": 2.5741538127566396e-05, + "loss": 0.0012415657751262189, + "step": 1040 + }, + { + "epoch": 3.3765456721180693, + "grad_norm": 0.0033840558025985956, + "learning_rate": 2.4015142526625115e-05, + "loss": 0.0009985800832509994, + "step": 1060 + }, + { + "epoch": 3.4403669724770642, + "grad_norm": 0.020664699375629425, + "learning_rate": 2.233043940009967e-05, + "loss": 0.0011398554779589176, + "step": 1080 + }, + { + "epoch": 3.504188272836059, + "grad_norm": 0.0015457016415894032, + "learning_rate": 2.0690126647990974e-05, + "loss": 0.0016313906759023666, + "step": 1100 + }, + { + "epoch": 3.568009573195054, + "grad_norm": 0.011757194995880127, + "learning_rate": 1.9096831083121828e-05, + "loss": 0.0010684640146791935, + "step": 1120 + }, + { + "epoch": 3.6318308735540485, + "grad_norm": 0.007703748065978289, + "learning_rate": 1.7553104224533324e-05, + "loss": 0.0006688186898827553, + "step": 1140 + }, + { + "epoch": 3.6956521739130435, + "grad_norm": 0.04895896837115288, + "learning_rate": 1.606141821145735e-05, + "loss": 0.0016563836485147475, + "step": 1160 + }, + { + "epoch": 3.7594734742720384, + "grad_norm": 0.04278242960572243, + "learning_rate": 1.4624161844408763e-05, + "loss": 0.0006196124479174614, + "step": 1180 + }, + { + "epoch": 3.823294774631033, + "grad_norm": 0.004100222606211901, + "learning_rate": 1.324363675973698e-05, + "loss": 0.0009099396876990796, + "step": 1200 + }, + { + "epoch": 3.8871160749900278, + "grad_norm": 0.06636715680360794, + "learning_rate": 1.1922053743763052e-05, + "loss": 0.0012004765681922435, + "step": 1220 + }, + { + "epoch": 3.9509373753490227, + "grad_norm": 0.005992025602608919, + "learning_rate": 1.0661529192404973e-05, + "loss": 0.0003460923908278346, + "step": 1240 + }, + { + "epoch": 4.0, + "eval_generator_count": 1712.0, + "eval_generator_exact_match": 95.8528, + "eval_generator_rouge1": 99.9186, + "eval_generator_rouge2": 99.8428, + "eval_generator_rougeL": 99.7108, + "eval_loss": 0.004311855416744947, + "eval_runtime": 587.5171, + "eval_samples_per_second": 5.811, + "eval_selector_accuracy": 98.1893, + "eval_selector_count": 1712.0, + "eval_steps_per_second": 0.182, + "step": 1256 + }, + { + "epoch": 4.0127642600717985, + "grad_norm": 0.12402024120092392, + "learning_rate": 9.464081721960592e-06, + "loss": 0.0005224554799497128, + "step": 1260 + }, + { + "epoch": 4.076585560430794, + "grad_norm": 0.032988350838422775, + "learning_rate": 8.331628936475818e-06, + "loss": 0.00022895974107086658, + "step": 1280 + }, + { + "epoch": 4.140406860789788, + "grad_norm": 0.002514337655156851, + "learning_rate": 7.2659843568748385e-06, + "loss": 0.00028093236032873393, + "step": 1300 + }, + { + "epoch": 4.204228161148784, + "grad_norm": 0.013952493667602539, + "learning_rate": 6.268854516770008e-06, + "loss": 0.0007838346064090729, + "step": 1320 + }, + { + "epoch": 4.268049461507778, + "grad_norm": 0.00595195172354579, + "learning_rate": 5.341836229602331e-06, + "loss": 0.0010836148634552956, + "step": 1340 + }, + { + "epoch": 4.331870761866773, + "grad_norm": 0.24550670385360718, + "learning_rate": 4.4864140314888216e-06, + "loss": 0.001040823757648468, + "step": 1360 + }, + { + "epoch": 4.395692062225768, + "grad_norm": 0.009249023161828518, + "learning_rate": 3.703957803871932e-06, + "loss": 0.0006210384890437126, + "step": 1380 + }, + { + "epoch": 4.4595133625847625, + "grad_norm": 0.010251481086015701, + "learning_rate": 2.9957205797780495e-06, + "loss": 0.0005129187367856503, + "step": 1400 + }, + { + "epoch": 4.523334662943758, + "grad_norm": 0.024013608694076538, + "learning_rate": 2.362836537198199e-06, + "loss": 0.0004933405201882124, + "step": 1420 + }, + { + "epoch": 4.587155963302752, + "grad_norm": 0.028239818289875984, + "learning_rate": 1.8063191828043703e-06, + "loss": 0.0005304558202624321, + "step": 1440 + }, + { + "epoch": 4.650977263661747, + "grad_norm": 0.01863635517656803, + "learning_rate": 1.3270597289100437e-06, + "loss": 0.00033774527255445717, + "step": 1460 + }, + { + "epoch": 4.714798564020742, + "grad_norm": 0.0036166764330118895, + "learning_rate": 9.258256662741205e-07, + "loss": 0.0002381577854976058, + "step": 1480 + }, + { + "epoch": 4.778619864379737, + "grad_norm": 0.016647396609187126, + "learning_rate": 6.032595350337341e-07, + "loss": 0.0005346011370420456, + "step": 1500 + }, + { + "epoch": 4.842441164738732, + "grad_norm": 0.14798367023468018, + "learning_rate": 3.5987789573421356e-07, + "loss": 0.0015266412869095803, + "step": 1520 + }, + { + "epoch": 4.9062624650977265, + "grad_norm": 0.1593816727399826, + "learning_rate": 1.9607050210401192e-07, + "loss": 0.0003545734565705061, + "step": 1540 + }, + { + "epoch": 4.970083765456721, + "grad_norm": 0.01692381501197815, + "learning_rate": 1.1209967689925832e-07, + "loss": 0.0004393013659864664, + "step": 1560 + }, + { + "epoch": 5.0, + "eval_generator_count": 1712.0, + "eval_generator_exact_match": 95.736, + "eval_generator_rouge1": 99.9082, + "eval_generator_rouge2": 99.8294, + "eval_generator_rougeL": 99.7068, + "eval_loss": 0.004025007598102093, + "eval_runtime": 591.5846, + "eval_samples_per_second": 5.771, + "eval_selector_accuracy": 98.6565, + "eval_selector_count": 1712.0, + "eval_steps_per_second": 0.181, + "step": 1570 + }, + { + "epoch": 5.0, + "step": 1570, + "total_flos": 5.871444840310374e+16, + "train_loss": 0.01864182253792336, + "train_runtime": 7621.8556, + "train_samples_per_second": 6.578, + "train_steps_per_second": 0.206 + } + ], + "logging_steps": 20, + "max_steps": 1570, + "num_input_tokens_seen": 0, + "num_train_epochs": 5, + "save_steps": 500, + "stateful_callbacks": { + "TrainerControl": { + "args": { + "should_epoch_stop": false, + "should_evaluate": false, + "should_log": false, + "should_save": true, + "should_training_stop": true + }, + "attributes": {} + } + }, + "total_flos": 5.871444840310374e+16, + "train_batch_size": 2, + "trial_name": null, + "trial_params": null +} diff --git a/qwen3/amid/training_args.bin b/qwen3/amid/training_args.bin new file mode 100644 index 0000000000000000000000000000000000000000..571568fd8ab61d629f2a731739ee4c9e1309cca4 --- /dev/null +++ b/qwen3/amid/training_args.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e67133ff7a80f6f166c03bd5f62d9c580548b0f6840a1ce3891dee623991e47a +size 7185 diff --git a/qwen3/csd/README.md b/qwen3/csd/README.md new file mode 100644 index 0000000000000000000000000000000000000000..aecfa20e01ac21ca72d6d48d31f51cc23fde71fe --- /dev/null +++ b/qwen3/csd/README.md @@ -0,0 +1,79 @@ +--- +library_name: peft +license: other +base_model: Qwen/Qwen3-0.6B +tags: +- base_model:adapter:Qwen/Qwen3-0.6B +- llama-factory +- lora +- transformers +pipeline_tag: text-generation +model-index: +- name: csd + results: [] +--- + + + +# csd + +This model is a fine-tuned version of [Qwen/Qwen3-0.6B](https://huggingface.co/Qwen/Qwen3-0.6B) on the cypher_prepared_train dataset. +It achieves the following results on the evaluation set: +- Loss: 0.0041 +- Selector Count: 1712.0 +- Generator Count: 1712.0 +- Selector Accuracy: 98.5981 +- Generator Exact Match: 96.6121 +- Generator Rouge1: 99.9371 +- Generator Rouge2: 99.8891 +- Generator Rougel: 99.7571 + +## Model description + +More information needed + +## Intended uses & limitations + +More information needed + +## Training and evaluation data + +More information needed + +## Training procedure + +### Training hyperparameters + +The following hyperparameters were used during training: +- learning_rate: 0.0001 +- train_batch_size: 2 +- eval_batch_size: 16 +- seed: 42 +- distributed_type: multi-GPU +- num_devices: 2 +- gradient_accumulation_steps: 8 +- total_train_batch_size: 32 +- total_eval_batch_size: 32 +- optimizer: Use OptimizerNames.ADAMW_TORCH with betas=(0.9,0.999) and epsilon=1e-08 and optimizer_args=No additional optimizer arguments +- lr_scheduler_type: cosine_with_min_lr +- num_epochs: 5 + +### Training results + +| Training Loss | Epoch | Step | Validation Loss | Selector Count | Generator Count | Selector Accuracy | Generator Exact Match | Generator Rouge1 | Generator Rouge2 | Generator Rougel | +|:-------------:|:-----:|:----:|:---------------:|:--------------:|:---------------:|:-----------------:|:---------------------:|:----------------:|:----------------:|:----------------:| +| 0.0050 | 1.0 | 314 | 0.0192 | 1712.0 | 1712.0 | 93.3995 | 86.2734 | 99.1343 | 98.8297 | 98.6074 | +| -0.0061 | 2.0 | 628 | 0.0068 | 1712.0 | 1712.0 | 97.8388 | 94.6846 | 99.7652 | 99.667 | 99.5471 | +| -0.0188 | 3.0 | 942 | 0.0053 | 1712.0 | 1712.0 | 97.722 | 95.736 | 99.9465 | 99.8866 | 99.7132 | +| -0.0361 | 4.0 | 1256 | 0.0042 | 1712.0 | 1712.0 | 98.3645 | 96.2617 | 99.8812 | 99.8259 | 99.6849 | +| -0.0416 | 5.0 | 1570 | 0.0041 | 1712.0 | 1712.0 | 98.6565 | 96.6706 | 99.9491 | 99.8942 | 99.7857 | + + +### Framework versions + +- PEFT 0.18.1 +- Transformers 5.8.0 +- Pytorch 2.9.1+cu128 +- Datasets 4.0.0 +- Tokenizers 0.22.2 \ No newline at end of file diff --git a/qwen3/csd/adapter_config.json b/qwen3/csd/adapter_config.json new file mode 100644 index 0000000000000000000000000000000000000000..9959003652c9aaae4cece005b46aaf87e6d0f224 --- /dev/null +++ b/qwen3/csd/adapter_config.json @@ -0,0 +1,46 @@ +{ + "alora_invocation_tokens": null, + "alpha_pattern": {}, + "arrow_config": null, + "auto_mapping": null, + "base_model_name_or_path": "Qwen/Qwen3-0.6B", + "bias": "none", + "corda_config": null, + "ensure_weight_tying": false, + "eva_config": null, + "exclude_modules": null, + "fan_in_fan_out": false, + "inference_mode": true, + "init_lora_weights": true, + "layer_replication": null, + "layers_pattern": null, + "layers_to_transform": null, + "loftq_config": {}, + "lora_alpha": 64, + "lora_bias": false, + "lora_dropout": 0.1, + "megatron_config": null, + "megatron_core": "megatron.core", + "modules_to_save": null, + "peft_type": "LORA", + "peft_version": "0.18.1", + "qalora_group_size": 16, + "r": 32, + "rank_pattern": {}, + "revision": null, + "target_modules": [ + "down_proj", + "up_proj", + "v_proj", + "q_proj", + "gate_proj", + "o_proj", + "k_proj" + ], + "target_parameters": null, + "task_type": "CAUSAL_LM", + "trainable_token_indices": null, + "use_dora": false, + "use_qalora": false, + "use_rslora": false +} \ No newline at end of file diff --git a/qwen3/csd/adapter_model.safetensors b/qwen3/csd/adapter_model.safetensors new file mode 100644 index 0000000000000000000000000000000000000000..57ad3d3cb4fe71a4d7f36999029d2b5e7ba925c6 --- /dev/null +++ b/qwen3/csd/adapter_model.safetensors @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d4406b594fb337274c887bfad3ad274f42413413cfb01fb17f61a907e23a5aca +size 40422560 diff --git a/qwen3/csd/all_results.json b/qwen3/csd/all_results.json new file mode 100644 index 0000000000000000000000000000000000000000..908a5e1203e65961ea2e79bf98da56f598aafe74 --- /dev/null +++ b/qwen3/csd/all_results.json @@ -0,0 +1,19 @@ +{ + "epoch": 5.0, + "eval_generator_count": 1712.0, + "eval_generator_exact_match": 96.6121, + "eval_generator_rouge1": 99.9371, + "eval_generator_rouge2": 99.8891, + "eval_generator_rougeL": 99.7571, + "eval_loss": 0.00408697547391057, + "eval_runtime": 585.4618, + "eval_samples_per_second": 5.831, + "eval_selector_accuracy": 98.5981, + "eval_selector_count": 1712.0, + "eval_steps_per_second": 0.183, + "total_flos": 5.871444840310374e+16, + "train_loss": -0.013058029026516779, + "train_runtime": 7965.6329, + "train_samples_per_second": 6.294, + "train_steps_per_second": 0.197 +} \ No newline at end of file diff --git a/qwen3/csd/chat_template.jinja b/qwen3/csd/chat_template.jinja new file mode 100644 index 0000000000000000000000000000000000000000..01be9b307daa2d425f7c168c9fb145a286e0afb4 --- /dev/null +++ b/qwen3/csd/chat_template.jinja @@ -0,0 +1,89 @@ +{%- if tools %} + {{- '<|im_start|>system\n' }} + {%- if messages[0].role == 'system' %} + {{- messages[0].content + '\n\n' }} + {%- endif %} + {{- "# Tools\n\nYou may call one or more functions to assist with the user query.\n\nYou are provided with function signatures within XML tags:\n" }} + {%- for tool in tools %} + {{- "\n" }} + {{- tool | tojson }} + {%- endfor %} + {{- "\n\n\nFor each function call, return a json object with function name and arguments within XML tags:\n\n{\"name\": , \"arguments\": }\n<|im_end|>\n" }} +{%- else %} + {%- if messages[0].role == 'system' %} + {{- '<|im_start|>system\n' + messages[0].content + '<|im_end|>\n' }} + {%- endif %} +{%- endif %} +{%- set ns = namespace(multi_step_tool=true, last_query_index=messages|length - 1) %} +{%- for message in messages[::-1] %} + {%- set index = (messages|length - 1) - loop.index0 %} + {%- if ns.multi_step_tool and message.role == "user" and message.content is string and not(message.content.startswith('') and message.content.endswith('')) %} + {%- set ns.multi_step_tool = false %} + {%- set ns.last_query_index = index %} + {%- endif %} +{%- endfor %} +{%- for message in messages %} + {%- if message.content is string %} + {%- set content = message.content %} + {%- else %} + {%- set content = '' %} + {%- endif %} + {%- if (message.role == "user") or (message.role == "system" and not loop.first) %} + {{- '<|im_start|>' + message.role + '\n' + content + '<|im_end|>' + '\n' }} + {%- elif message.role == "assistant" %} + {%- set reasoning_content = '' %} + {%- if message.reasoning_content is string %} + {%- set reasoning_content = message.reasoning_content %} + {%- else %} + {%- if '' in content %} + {%- set reasoning_content = content.split('')[0].rstrip('\n').split('')[-1].lstrip('\n') %} + {%- set content = content.split('')[-1].lstrip('\n') %} + {%- endif %} + {%- endif %} + {%- if loop.index0 > ns.last_query_index %} + {%- if loop.last or (not loop.last and reasoning_content) %} + {{- '<|im_start|>' + message.role + '\n\n' + reasoning_content.strip('\n') + '\n\n\n' + content.lstrip('\n') }} + {%- else %} + {{- '<|im_start|>' + message.role + '\n' + content }} + {%- endif %} + {%- else %} + {{- '<|im_start|>' + message.role + '\n' + content }} + {%- endif %} + {%- if message.tool_calls %} + {%- for tool_call in message.tool_calls %} + {%- if (loop.first and content) or (not loop.first) %} + {{- '\n' }} + {%- endif %} + {%- if tool_call.function %} + {%- set tool_call = tool_call.function %} + {%- endif %} + {{- '\n{"name": "' }} + {{- tool_call.name }} + {{- '", "arguments": ' }} + {%- if tool_call.arguments is string %} + {{- tool_call.arguments }} + {%- else %} + {{- tool_call.arguments | tojson }} + {%- endif %} + {{- '}\n' }} + {%- endfor %} + {%- endif %} + {{- '<|im_end|>\n' }} + {%- elif message.role == "tool" %} + {%- if loop.first or (messages[loop.index0 - 1].role != "tool") %} + {{- '<|im_start|>user' }} + {%- endif %} + {{- '\n\n' }} + {{- content }} + {{- '\n' }} + {%- if loop.last or (messages[loop.index0 + 1].role != "tool") %} + {{- '<|im_end|>\n' }} + {%- endif %} + {%- endif %} +{%- endfor %} +{%- if add_generation_prompt %} + {{- '<|im_start|>assistant\n' }} + {%- if enable_thinking is defined and enable_thinking is false %} + {{- '\n\n\n\n' }} + {%- endif %} +{%- endif %} \ No newline at end of file diff --git a/qwen3/csd/checkpoint-1256/README.md b/qwen3/csd/checkpoint-1256/README.md new file mode 100644 index 0000000000000000000000000000000000000000..776f98d43659dd923b8c3e5649c5ae66d1f99f3e --- /dev/null +++ b/qwen3/csd/checkpoint-1256/README.md @@ -0,0 +1,208 @@ +--- +base_model: Qwen/Qwen3-0.6B +library_name: peft +pipeline_tag: text-generation +tags: +- base_model:adapter:Qwen/Qwen3-0.6B +- llama-factory +- lora +- transformers +--- + +# Model Card for Model ID + + + + + +## Model Details + +### Model Description + + + + + +- **Developed by:** [More Information Needed] +- **Funded by [optional]:** [More Information Needed] +- **Shared by [optional]:** [More Information Needed] +- **Model type:** [More Information Needed] +- **Language(s) (NLP):** [More Information Needed] +- **License:** [More Information Needed] +- **Finetuned from model [optional]:** [More Information Needed] + +### Model Sources [optional] + + + +- **Repository:** [More Information Needed] +- **Paper [optional]:** [More Information Needed] +- **Demo [optional]:** [More Information Needed] + +## Uses + + + +### Direct Use + + + +[More Information Needed] + +### Downstream Use [optional] + + + +[More Information Needed] + +### Out-of-Scope Use + + + +[More Information Needed] + +## Bias, Risks, and Limitations + + + +[More Information Needed] + +### Recommendations + + + +Users (both direct and downstream) should be made aware of the risks, biases and limitations of the model. More information needed for further recommendations. + +## How to Get Started with the Model + +Use the code below to get started with the model. + +[More Information Needed] + +## Training Details + +### Training Data + + + +[More Information Needed] + +### Training Procedure + + + +#### Preprocessing [optional] + +[More Information Needed] + + +#### Training Hyperparameters + +- **Training regime:** [More Information Needed] + +#### Speeds, Sizes, Times [optional] + + + +[More Information Needed] + +## Evaluation + + + +### Testing Data, Factors & Metrics + +#### Testing Data + + + +[More Information Needed] + +#### Factors + + + +[More Information Needed] + +#### Metrics + + + +[More Information Needed] + +### Results + +[More Information Needed] + +#### Summary + + + +## Model Examination [optional] + + + +[More Information Needed] + +## Environmental Impact + + + +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). + +- **Hardware Type:** [More Information Needed] +- **Hours used:** [More Information Needed] +- **Cloud Provider:** [More Information Needed] +- **Compute Region:** [More Information Needed] +- **Carbon Emitted:** [More Information Needed] + +## Technical Specifications [optional] + +### Model Architecture and Objective + +[More Information Needed] + +### Compute Infrastructure + +[More Information Needed] + +#### Hardware + +[More Information Needed] + +#### Software + +[More Information Needed] + +## Citation [optional] + + + +**BibTeX:** + +[More Information Needed] + +**APA:** + +[More Information Needed] + +## Glossary [optional] + + + +[More Information Needed] + +## More Information [optional] + +[More Information Needed] + +## Model Card Authors [optional] + +[More Information Needed] + +## Model Card Contact + +[More Information Needed] +### Framework versions + +- PEFT 0.18.1 \ No newline at end of file diff --git a/qwen3/csd/checkpoint-1256/adapter_config.json b/qwen3/csd/checkpoint-1256/adapter_config.json new file mode 100644 index 0000000000000000000000000000000000000000..9959003652c9aaae4cece005b46aaf87e6d0f224 --- /dev/null +++ b/qwen3/csd/checkpoint-1256/adapter_config.json @@ -0,0 +1,46 @@ +{ + "alora_invocation_tokens": null, + "alpha_pattern": {}, + "arrow_config": null, + "auto_mapping": null, + "base_model_name_or_path": "Qwen/Qwen3-0.6B", + "bias": "none", + "corda_config": null, + "ensure_weight_tying": false, + "eva_config": null, + "exclude_modules": null, + "fan_in_fan_out": false, + "inference_mode": true, + "init_lora_weights": true, + "layer_replication": null, + "layers_pattern": null, + "layers_to_transform": null, + "loftq_config": {}, + "lora_alpha": 64, + "lora_bias": false, + "lora_dropout": 0.1, + "megatron_config": null, + "megatron_core": "megatron.core", + "modules_to_save": null, + "peft_type": "LORA", + "peft_version": "0.18.1", + "qalora_group_size": 16, + "r": 32, + "rank_pattern": {}, + "revision": null, + "target_modules": [ + "down_proj", + "up_proj", + "v_proj", + "q_proj", + "gate_proj", + "o_proj", + "k_proj" + ], + "target_parameters": null, + "task_type": "CAUSAL_LM", + "trainable_token_indices": null, + "use_dora": false, + "use_qalora": false, + "use_rslora": false +} \ No newline at end of file diff --git a/qwen3/csd/checkpoint-1256/adapter_model.safetensors b/qwen3/csd/checkpoint-1256/adapter_model.safetensors new file mode 100644 index 0000000000000000000000000000000000000000..b85b79f15631bffb3a36568946231c30f5ae1ed7 --- /dev/null +++ b/qwen3/csd/checkpoint-1256/adapter_model.safetensors @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a383f12c8d4db1e02f37692723d39177089a0b1b09d598ae61ae9426efbd636d +size 40422560 diff --git a/qwen3/csd/checkpoint-1256/chat_template.jinja b/qwen3/csd/checkpoint-1256/chat_template.jinja new file mode 100644 index 0000000000000000000000000000000000000000..01be9b307daa2d425f7c168c9fb145a286e0afb4 --- /dev/null +++ b/qwen3/csd/checkpoint-1256/chat_template.jinja @@ -0,0 +1,89 @@ +{%- if tools %} + {{- '<|im_start|>system\n' }} + {%- if messages[0].role == 'system' %} + {{- messages[0].content + '\n\n' }} + {%- endif %} + {{- "# Tools\n\nYou may call one or more functions to assist with the user query.\n\nYou are provided with function signatures within XML tags:\n" }} + {%- for tool in tools %} + {{- "\n" }} + {{- tool | tojson }} + {%- endfor %} + {{- "\n\n\nFor each function call, return a json object with function name and arguments within XML tags:\n\n{\"name\": , \"arguments\": }\n<|im_end|>\n" }} +{%- else %} + {%- if messages[0].role == 'system' %} + {{- '<|im_start|>system\n' + messages[0].content + '<|im_end|>\n' }} + {%- endif %} +{%- endif %} +{%- set ns = namespace(multi_step_tool=true, last_query_index=messages|length - 1) %} +{%- for message in messages[::-1] %} + {%- set index = (messages|length - 1) - loop.index0 %} + {%- if ns.multi_step_tool and message.role == "user" and message.content is string and not(message.content.startswith('') and message.content.endswith('')) %} + {%- set ns.multi_step_tool = false %} + {%- set ns.last_query_index = index %} + {%- endif %} +{%- endfor %} +{%- for message in messages %} + {%- if message.content is string %} + {%- set content = message.content %} + {%- else %} + {%- set content = '' %} + {%- endif %} + {%- if (message.role == "user") or (message.role == "system" and not loop.first) %} + {{- '<|im_start|>' + message.role + '\n' + content + '<|im_end|>' + '\n' }} + {%- elif message.role == "assistant" %} + {%- set reasoning_content = '' %} + {%- if message.reasoning_content is string %} + {%- set reasoning_content = message.reasoning_content %} + {%- else %} + {%- if '' in content %} + {%- set reasoning_content = content.split('')[0].rstrip('\n').split('')[-1].lstrip('\n') %} + {%- set content = content.split('')[-1].lstrip('\n') %} + {%- endif %} + {%- endif %} + {%- if loop.index0 > ns.last_query_index %} + {%- if loop.last or (not loop.last and reasoning_content) %} + {{- '<|im_start|>' + message.role + '\n\n' + reasoning_content.strip('\n') + '\n\n\n' + content.lstrip('\n') }} + {%- else %} + {{- '<|im_start|>' + message.role + '\n' + content }} + {%- endif %} + {%- else %} + {{- '<|im_start|>' + message.role + '\n' + content }} + {%- endif %} + {%- if message.tool_calls %} + {%- for tool_call in message.tool_calls %} + {%- if (loop.first and content) or (not loop.first) %} + {{- '\n' }} + {%- endif %} + {%- if tool_call.function %} + {%- set tool_call = tool_call.function %} + {%- endif %} + {{- '\n{"name": "' }} + {{- tool_call.name }} + {{- '", "arguments": ' }} + {%- if tool_call.arguments is string %} + {{- tool_call.arguments }} + {%- else %} + {{- tool_call.arguments | tojson }} + {%- endif %} + {{- '}\n' }} + {%- endfor %} + {%- endif %} + {{- '<|im_end|>\n' }} + {%- elif message.role == "tool" %} + {%- if loop.first or (messages[loop.index0 - 1].role != "tool") %} + {{- '<|im_start|>user' }} + {%- endif %} + {{- '\n\n' }} + {{- content }} + {{- '\n' }} + {%- if loop.last or (messages[loop.index0 + 1].role != "tool") %} + {{- '<|im_end|>\n' }} + {%- endif %} + {%- endif %} +{%- endfor %} +{%- if add_generation_prompt %} + {{- '<|im_start|>assistant\n' }} + {%- if enable_thinking is defined and enable_thinking is false %} + {{- '\n\n\n\n' }} + {%- endif %} +{%- endif %} \ No newline at end of file diff --git a/qwen3/csd/checkpoint-1256/global_step1256/bf16_zero_pp_rank_0_mp_rank_00_optim_states.pt b/qwen3/csd/checkpoint-1256/global_step1256/bf16_zero_pp_rank_0_mp_rank_00_optim_states.pt new file mode 100644 index 0000000000000000000000000000000000000000..6b188dc8c0d02140d1df35c04a75c2d9216379da --- /dev/null +++ b/qwen3/csd/checkpoint-1256/global_step1256/bf16_zero_pp_rank_0_mp_rank_00_optim_states.pt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:227e3b62ef4c65d8e242a7eeb6ddd96c65729363487d6a9c33822628441b6536 +size 121135557 diff --git a/qwen3/csd/checkpoint-1256/global_step1256/bf16_zero_pp_rank_1_mp_rank_00_optim_states.pt b/qwen3/csd/checkpoint-1256/global_step1256/bf16_zero_pp_rank_1_mp_rank_00_optim_states.pt new file mode 100644 index 0000000000000000000000000000000000000000..637ca16f174ab2ad45ac986d6fd8ae4e28883b86 --- /dev/null +++ b/qwen3/csd/checkpoint-1256/global_step1256/bf16_zero_pp_rank_1_mp_rank_00_optim_states.pt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d301a9eb5a44c64fb9dea101f07e48b82c5fa08985e9d57e1e2bfd2c25c951a4 +size 121135749 diff --git a/qwen3/csd/checkpoint-1256/global_step1256/mp_rank_00_model_states.pt b/qwen3/csd/checkpoint-1256/global_step1256/mp_rank_00_model_states.pt new file mode 100644 index 0000000000000000000000000000000000000000..e8ee839ba70ea1beff0a62ccab838366bd7a35c2 --- /dev/null +++ b/qwen3/csd/checkpoint-1256/global_step1256/mp_rank_00_model_states.pt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b75ae1ee7c799972ebedcb20fb08609db04762d45a3030f24f465c8605eeb8a9 +size 351841765 diff --git a/qwen3/csd/checkpoint-1256/latest b/qwen3/csd/checkpoint-1256/latest new file mode 100644 index 0000000000000000000000000000000000000000..74abb3d23ea83ebdac59918752db5d1782834ca7 --- /dev/null +++ b/qwen3/csd/checkpoint-1256/latest @@ -0,0 +1 @@ +global_step1256 \ No newline at end of file diff --git a/qwen3/csd/checkpoint-1256/rng_state_0.pth b/qwen3/csd/checkpoint-1256/rng_state_0.pth new file mode 100644 index 0000000000000000000000000000000000000000..f71a7dc0719c09b17fc6c626e62684f6ce78877f --- /dev/null +++ b/qwen3/csd/checkpoint-1256/rng_state_0.pth @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:53905562edd591f558a2d5e21b3ce7bcf87bff6ea468e990980a48731ed07327 +size 14917 diff --git a/qwen3/csd/checkpoint-1256/rng_state_1.pth b/qwen3/csd/checkpoint-1256/rng_state_1.pth new file mode 100644 index 0000000000000000000000000000000000000000..2f8498e702b57f175b94b9411aacb88c870385bf --- /dev/null +++ b/qwen3/csd/checkpoint-1256/rng_state_1.pth @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f73798ef6ab5a59b84975e3c8385db7b9dde1508715924c2c18cba2d5c8ac9c2 +size 14917 diff --git a/qwen3/csd/checkpoint-1256/scheduler.pt b/qwen3/csd/checkpoint-1256/scheduler.pt new file mode 100644 index 0000000000000000000000000000000000000000..40e863d07cfed22cd912014eb3ba3fd2b16b173f --- /dev/null +++ b/qwen3/csd/checkpoint-1256/scheduler.pt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1775297f14e75f7463ae51983a66296f81f4b2e2e5d7234f1a6d295abfa4cf23 +size 1465 diff --git a/qwen3/csd/checkpoint-1256/tokenizer.json b/qwen3/csd/checkpoint-1256/tokenizer.json new file mode 100644 index 0000000000000000000000000000000000000000..c7afbed2efcdf019f88ab0572ec29d3bf595dfe2 --- /dev/null +++ b/qwen3/csd/checkpoint-1256/tokenizer.json @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:be75606093db2094d7cd20f3c2f385c212750648bd6ea4fb2bf507a6a4c55506 +size 11422650 diff --git a/qwen3/csd/checkpoint-1256/tokenizer_config.json b/qwen3/csd/checkpoint-1256/tokenizer_config.json new file mode 100644 index 0000000000000000000000000000000000000000..6623da03457d79d2cd4af9557e9f31407cdb835c --- /dev/null +++ b/qwen3/csd/checkpoint-1256/tokenizer_config.json @@ -0,0 +1,31 @@ +{ + "add_prefix_space": false, + "backend": "tokenizers", + "bos_token": null, + "clean_up_tokenization_spaces": false, + "eos_token": "<|im_end|>", + "errors": "replace", + "extra_special_tokens": [ + "<|im_start|>", + "<|im_end|>", + "<|object_ref_start|>", + "<|object_ref_end|>", + "<|box_start|>", + "<|box_end|>", + "<|quad_start|>", + "<|quad_end|>", + "<|vision_start|>", + "<|vision_end|>", + "<|vision_pad|>", + "<|image_pad|>", + "<|video_pad|>" + ], + "is_local": false, + "local_files_only": false, + "model_max_length": 131072, + "pad_token": "<|endoftext|>", + "padding_side": "right", + "split_special_tokens": false, + "tokenizer_class": "Qwen2Tokenizer", + "unk_token": null +} diff --git a/qwen3/csd/checkpoint-1256/trainer_state.json b/qwen3/csd/checkpoint-1256/trainer_state.json new file mode 100644 index 0000000000000000000000000000000000000000..9f637fb733126d725c0abe0e8f2bd2ac8b8cc7ab --- /dev/null +++ b/qwen3/csd/checkpoint-1256/trainer_state.json @@ -0,0 +1,528 @@ +{ + "best_global_step": null, + "best_metric": null, + "best_model_checkpoint": null, + "epoch": 4.0, + "eval_steps": 500, + "global_step": 1256, + "is_hyper_param_search": false, + "is_local_process_zero": true, + "is_world_process_zero": true, + "log_history": [ + { + "epoch": 0.06382130035899482, + "grad_norm": 6.0161848068237305, + "learning_rate": 9.996390385474569e-05, + "loss": 0.11036398410797119, + "step": 20 + }, + { + "epoch": 0.12764260071798963, + "grad_norm": 4.099686622619629, + "learning_rate": 9.984797509888031e-05, + "loss": 0.01695394217967987, + "step": 40 + }, + { + "epoch": 0.19146390107698444, + "grad_norm": 3.3755345344543457, + "learning_rate": 9.965229938050925e-05, + "loss": 0.03482693731784821, + "step": 60 + }, + { + "epoch": 0.25528520143597927, + "grad_norm": 1.194334864616394, + "learning_rate": 9.937719005663432e-05, + "loss": 0.027955988049507143, + "step": 80 + }, + { + "epoch": 0.3191065017949741, + "grad_norm": 6.6159281730651855, + "learning_rate": 9.902308769000724e-05, + "loss": 0.005286623537540436, + "step": 100 + }, + { + "epoch": 0.3829278021539689, + "grad_norm": 2.851339817047119, + "learning_rate": 9.859055934360789e-05, + "loss": 0.01179061084985733, + "step": 120 + }, + { + "epoch": 0.4467491025129637, + "grad_norm": 0.989425539970398, + "learning_rate": 9.808029767254437e-05, + "loss": 0.006131124496459961, + "step": 140 + }, + { + "epoch": 0.5105704028719585, + "grad_norm": 1.3493149280548096, + "learning_rate": 9.749311981482817e-05, + "loss": 0.007052437216043472, + "step": 160 + }, + { + "epoch": 0.5743917032309533, + "grad_norm": 0.9337753057479858, + "learning_rate": 9.682996608280154e-05, + "loss": -0.002346178889274597, + "step": 180 + }, + { + "epoch": 0.6382130035899481, + "grad_norm": 1.5435981750488281, + "learning_rate": 9.609189845731207e-05, + "loss": 0.013309524953365326, + "step": 200 + }, + { + "epoch": 0.702034303948943, + "grad_norm": 0.7995954155921936, + "learning_rate": 9.52800988870462e-05, + "loss": 0.008521870523691178, + "step": 220 + }, + { + "epoch": 0.7658556043079378, + "grad_norm": 1.6571325063705444, + "learning_rate": 9.439586739574513e-05, + "loss": 0.008653326332569123, + "step": 240 + }, + { + "epoch": 0.8296769046669326, + "grad_norm": 0.519936203956604, + "learning_rate": 9.344062000033414e-05, + "loss": 0.004485934227705002, + "step": 260 + }, + { + "epoch": 0.8934982050259274, + "grad_norm": 0.31598174571990967, + "learning_rate": 9.241588644329919e-05, + "loss": 0.003059915825724602, + "step": 280 + }, + { + "epoch": 0.9573195053849222, + "grad_norm": 0.48084524273872375, + "learning_rate": 9.132330774294252e-05, + "loss": 0.005025627836585045, + "step": 300 + }, + { + "epoch": 1.0, + "eval_generator_count": 1712.0, + "eval_generator_exact_match": 86.2734, + "eval_generator_rouge1": 99.1343, + "eval_generator_rouge2": 98.8297, + "eval_generator_rougeL": 98.6074, + "eval_loss": 0.019235465675592422, + "eval_runtime": 603.0951, + "eval_samples_per_second": 5.661, + "eval_selector_accuracy": 93.3995, + "eval_selector_count": 1712.0, + "eval_steps_per_second": 0.177, + "step": 314 + }, + { + "epoch": 1.0191463901076985, + "grad_norm": 0.34810933470726013, + "learning_rate": 9.01646335654399e-05, + "loss": 0.008805014193058014, + "step": 320 + }, + { + "epoch": 1.0829676904666932, + "grad_norm": 0.19888198375701904, + "learning_rate": 8.894171942290817e-05, + "loss": 0.0013909661211073399, + "step": 340 + }, + { + "epoch": 1.146788990825688, + "grad_norm": 1.0506941080093384, + "learning_rate": 8.765652370197003e-05, + "loss": 0.0005901294760406017, + "step": 360 + }, + { + "epoch": 1.210610291184683, + "grad_norm": 2.363455057144165, + "learning_rate": 8.631110452757467e-05, + "loss": -0.0003092627972364426, + "step": 380 + }, + { + "epoch": 1.2744315915436777, + "grad_norm": 0.0766368880867958, + "learning_rate": 8.490761646709642e-05, + "loss": -0.002663038857281208, + "step": 400 + }, + { + "epoch": 1.3382528919026724, + "grad_norm": 0.1551397442817688, + "learning_rate": 8.344830707998953e-05, + "loss": 0.0026730677112936974, + "step": 420 + }, + { + "epoch": 1.4020741922616673, + "grad_norm": 0.7773767113685608, + "learning_rate": 8.193551331852458e-05, + "loss": -0.0011709232814610005, + "step": 440 + }, + { + "epoch": 1.4658954926206622, + "grad_norm": 0.42017874121665955, + "learning_rate": 8.037165778537033e-05, + "loss": -0.0019059792160987855, + "step": 460 + }, + { + "epoch": 1.5297167929796571, + "grad_norm": 1.0544211864471436, + "learning_rate": 7.875924485401427e-05, + "loss": -0.004772515594959259, + "step": 480 + }, + { + "epoch": 1.5935380933386518, + "grad_norm": 0.4706478416919708, + "learning_rate": 7.710085665823444e-05, + "loss": -0.0002438830444589257, + "step": 500 + }, + { + "epoch": 1.6573593936976465, + "grad_norm": 0.22088219225406647, + "learning_rate": 7.539914895704521e-05, + "loss": -0.004391691088676453, + "step": 520 + }, + { + "epoch": 1.7211806940566414, + "grad_norm": 0.5972660183906555, + "learning_rate": 7.365684688173908e-05, + "loss": -0.007541544735431671, + "step": 540 + }, + { + "epoch": 1.7850019944156363, + "grad_norm": 0.19400978088378906, + "learning_rate": 7.18767405718347e-05, + "loss": -0.004146666824817657, + "step": 560 + }, + { + "epoch": 1.848823294774631, + "grad_norm": 1.2469046115875244, + "learning_rate": 7.006168070692036e-05, + "loss": -0.0019529350101947784, + "step": 580 + }, + { + "epoch": 1.9126445951336257, + "grad_norm": 0.14316241443157196, + "learning_rate": 6.821457394154786e-05, + "loss": -0.008291246742010117, + "step": 600 + }, + { + "epoch": 1.9764658954926206, + "grad_norm": 0.4657886326313019, + "learning_rate": 6.633837825048768e-05, + "loss": -0.006107022240757942, + "step": 620 + }, + { + "epoch": 2.0, + "eval_generator_count": 1712.0, + "eval_generator_exact_match": 94.6846, + "eval_generator_rouge1": 99.7652, + "eval_generator_rouge2": 99.667, + "eval_generator_rougeL": 99.5471, + "eval_loss": 0.006834100466221571, + "eval_runtime": 601.0294, + "eval_samples_per_second": 5.68, + "eval_selector_accuracy": 97.8388, + "eval_selector_count": 1712.0, + "eval_steps_per_second": 0.178, + "step": 628 + }, + { + "epoch": 2.038292780215397, + "grad_norm": 0.22094473242759705, + "learning_rate": 6.443609819179926e-05, + "loss": -0.005953450500965118, + "step": 640 + }, + { + "epoch": 2.102114080574392, + "grad_norm": 0.5406356453895569, + "learning_rate": 6.251078009530256e-05, + "loss": -0.0025423141196370125, + "step": 660 + }, + { + "epoch": 2.1659353809333863, + "grad_norm": 0.09373176842927933, + "learning_rate": 6.0565507184155677e-05, + "loss": -0.0044939789921045305, + "step": 680 + }, + { + "epoch": 2.2297566812923812, + "grad_norm": 0.1080167219042778, + "learning_rate": 5.860339463735136e-05, + "loss": -0.00820673182606697, + "step": 700 + }, + { + "epoch": 2.293577981651376, + "grad_norm": 0.05399267002940178, + "learning_rate": 5.662758460103895e-05, + "loss": -0.009635555744171142, + "step": 720 + }, + { + "epoch": 2.357399282010371, + "grad_norm": 0.2048628032207489, + "learning_rate": 5.464124115666095e-05, + "loss": -0.010086850821971893, + "step": 740 + }, + { + "epoch": 2.421220582369366, + "grad_norm": 0.08765007555484772, + "learning_rate": 5.264754525396212e-05, + "loss": -0.008542184531688691, + "step": 760 + }, + { + "epoch": 2.4850418827283605, + "grad_norm": 0.2229253351688385, + "learning_rate": 5.06496896169857e-05, + "loss": -0.011658547818660736, + "step": 780 + }, + { + "epoch": 2.5488631830873554, + "grad_norm": 0.18513049185276031, + "learning_rate": 4.865087363121384e-05, + "loss": -0.00930779054760933, + "step": 800 + }, + { + "epoch": 2.6126844834463503, + "grad_norm": 0.3498702347278595, + "learning_rate": 4.6654298220040673e-05, + "loss": -0.014870831370353698, + "step": 820 + }, + { + "epoch": 2.6765057838053448, + "grad_norm": 0.16160713136196136, + "learning_rate": 4.466316071878229e-05, + "loss": -0.020250825583934783, + "step": 840 + }, + { + "epoch": 2.74032708416434, + "grad_norm": 0.16046860814094543, + "learning_rate": 4.2680649754432913e-05, + "loss": -0.018617722392082214, + "step": 860 + }, + { + "epoch": 2.8041483845233346, + "grad_norm": 0.17135752737522125, + "learning_rate": 4.070994013936646e-05, + "loss": -0.020963044464588167, + "step": 880 + }, + { + "epoch": 2.8679696848823295, + "grad_norm": 0.24867695569992065, + "learning_rate": 3.8754187787161155e-05, + "loss": -0.020418259501457214, + "step": 900 + }, + { + "epoch": 2.9317909852413244, + "grad_norm": 0.12315966188907623, + "learning_rate": 3.681652465868875e-05, + "loss": -0.018548570573329926, + "step": 920 + }, + { + "epoch": 2.995612285600319, + "grad_norm": 0.14333273470401764, + "learning_rate": 3.490005374656184e-05, + "loss": -0.018815448880195616, + "step": 940 + }, + { + "epoch": 3.0, + "eval_generator_count": 1712.0, + "eval_generator_exact_match": 95.736, + "eval_generator_rouge1": 99.9465, + "eval_generator_rouge2": 99.8866, + "eval_generator_rougeL": 99.7132, + "eval_loss": 0.005336109548807144, + "eval_runtime": 608.1178, + "eval_samples_per_second": 5.614, + "eval_selector_accuracy": 97.722, + "eval_selector_count": 1712.0, + "eval_steps_per_second": 0.176, + "step": 942 + }, + { + "epoch": 3.057439170323095, + "grad_norm": 0.1492357701063156, + "learning_rate": 3.3007844105971336e-05, + "loss": -0.02238200604915619, + "step": 960 + }, + { + "epoch": 3.12126047068209, + "grad_norm": 0.0778684988617897, + "learning_rate": 3.114292593987149e-05, + "loss": -0.02527567744255066, + "step": 980 + }, + { + "epoch": 3.185081771041085, + "grad_norm": 0.07070758193731308, + "learning_rate": 2.9308285746383408e-05, + "loss": -0.02356054335832596, + "step": 1000 + }, + { + "epoch": 3.24890307140008, + "grad_norm": 0.10038785636425018, + "learning_rate": 2.7506861536187867e-05, + "loss": -0.019069214165210725, + "step": 1020 + }, + { + "epoch": 3.3127243717590744, + "grad_norm": 0.33050113916397095, + "learning_rate": 2.5741538127566396e-05, + "loss": -0.022282478213310242, + "step": 1040 + }, + { + "epoch": 3.3765456721180693, + "grad_norm": 0.12148360908031464, + "learning_rate": 2.4015142526625115e-05, + "loss": -0.02368807643651962, + "step": 1060 + }, + { + "epoch": 3.4403669724770642, + "grad_norm": 0.16367903351783752, + "learning_rate": 2.233043940009967e-05, + "loss": -0.02528309226036072, + "step": 1080 + }, + { + "epoch": 3.504188272836059, + "grad_norm": 0.0877315029501915, + "learning_rate": 2.0690126647990974e-05, + "loss": -0.026697894930839537, + "step": 1100 + }, + { + "epoch": 3.568009573195054, + "grad_norm": 0.06676916033029556, + "learning_rate": 1.9096831083121828e-05, + "loss": -0.028009063005447386, + "step": 1120 + }, + { + "epoch": 3.6318308735540485, + "grad_norm": 0.09503277391195297, + "learning_rate": 1.7553104224533324e-05, + "loss": -0.0323164701461792, + "step": 1140 + }, + { + "epoch": 3.6956521739130435, + "grad_norm": 0.08010950684547424, + "learning_rate": 1.606141821145735e-05, + "loss": -0.03129267990589142, + "step": 1160 + }, + { + "epoch": 3.7594734742720384, + "grad_norm": 0.15882308781147003, + "learning_rate": 1.4624161844408763e-05, + "loss": -0.03188144564628601, + "step": 1180 + }, + { + "epoch": 3.823294774631033, + "grad_norm": 0.07064881920814514, + "learning_rate": 1.324363675973698e-05, + "loss": -0.03279578983783722, + "step": 1200 + }, + { + "epoch": 3.8871160749900278, + "grad_norm": 0.24478258192539215, + "learning_rate": 1.1922053743763052e-05, + "loss": -0.03418469429016113, + "step": 1220 + }, + { + "epoch": 3.9509373753490227, + "grad_norm": 0.09533516317605972, + "learning_rate": 1.0661529192404973e-05, + "loss": -0.036141425371170044, + "step": 1240 + }, + { + "epoch": 4.0, + "eval_generator_count": 1712.0, + "eval_generator_exact_match": 96.2617, + "eval_generator_rouge1": 99.8812, + "eval_generator_rouge2": 99.8259, + "eval_generator_rougeL": 99.6849, + "eval_loss": 0.0041860658675432205, + "eval_runtime": 606.5994, + "eval_samples_per_second": 5.628, + "eval_selector_accuracy": 98.3645, + "eval_selector_count": 1712.0, + "eval_steps_per_second": 0.176, + "step": 1256 + } + ], + "logging_steps": 20, + "max_steps": 1570, + "num_input_tokens_seen": 0, + "num_train_epochs": 5, + "save_steps": 500, + "stateful_callbacks": { + "TrainerControl": { + "args": { + "should_epoch_stop": false, + "should_evaluate": false, + "should_log": false, + "should_save": true, + "should_training_stop": false + }, + "attributes": {} + } + }, + "total_flos": 4.697643190059008e+16, + "train_batch_size": 2, + "trial_name": null, + "trial_params": null +} diff --git a/qwen3/csd/checkpoint-1256/training_args.bin b/qwen3/csd/checkpoint-1256/training_args.bin new file mode 100644 index 0000000000000000000000000000000000000000..4b4d426a661bf64c99e9ff7730557b24ebf0e60c --- /dev/null +++ b/qwen3/csd/checkpoint-1256/training_args.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:83e0687327fbf0a1cbac0cde783b20e396ed970bb1eed13dcf33e672089c5f44 +size 7185 diff --git a/qwen3/csd/checkpoint-1256/zero_to_fp32.py b/qwen3/csd/checkpoint-1256/zero_to_fp32.py new file mode 100644 index 0000000000000000000000000000000000000000..f40f1f0acbbff30e8e8d29906b56aae4e8b8a138 --- /dev/null +++ b/qwen3/csd/checkpoint-1256/zero_to_fp32.py @@ -0,0 +1,790 @@ +#!/usr/bin/env python + +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: Apache-2.0 + +# DeepSpeed Team + +# This script extracts fp32 consolidated weights from a zero 1, 2 and 3 DeepSpeed checkpoints. It gets +# copied into the top level checkpoint dir, so the user can easily do the conversion at any point in +# the future. Once extracted, the weights don't require DeepSpeed and can be used in any +# application. +# +# example: +# python zero_to_fp32.py . output_dir/ +# or +# python zero_to_fp32.py . output_dir/ --safe_serialization + +import argparse +import torch +import glob +import math +import os +import re +import gc +import json +import numpy as np +from tqdm import tqdm +from collections import OrderedDict +from dataclasses import dataclass + +# while this script doesn't use deepspeed to recover data, since the checkpoints are pickled with +# DeepSpeed data structures it has to be available in the current python environment. +from deepspeed.utils import logger +from deepspeed.checkpoint.constants import (DS_VERSION, OPTIMIZER_STATE_DICT, SINGLE_PARTITION_OF_FP32_GROUPS, + FP32_FLAT_GROUPS, ZERO_STAGE, PARTITION_COUNT, PARAM_SHAPES, BUFFER_NAMES, + FROZEN_PARAM_SHAPES, FROZEN_PARAM_FRAGMENTS, AUTOEP_LAYERS_KEY, + AUTOEP_LAYERS_KEY_LEGACY, AUTOEP_ZERO3_EXPERT_STATE_FORMAT_KEY, + AUTOEP_ZERO3_PARTITIONED_EXPERT_STATE_FORMAT) + + +@dataclass +class zero_model_state: + buffers: dict() + param_shapes: dict() + shared_params: list + ds_version: int + frozen_param_shapes: dict() + frozen_param_fragments: dict() + + +debug = 0 + +# load to cpu +device = torch.device('cpu') + + +def atoi(text): + return int(text) if text.isdigit() else text + + +def natural_keys(text): + ''' + alist.sort(key=natural_keys) sorts in human order + http://nedbatchelder.com/blog/200712/human_sorting.html + (See Toothy's implementation in the comments) + ''' + return [atoi(c) for c in re.split(r'(\d+)', text)] + + +def get_model_state_file(checkpoint_dir, zero_stage): + if not os.path.isdir(checkpoint_dir): + raise FileNotFoundError(f"Directory '{checkpoint_dir}' doesn't exist") + + # there should be only one file + if zero_stage <= 2: + file = os.path.join(checkpoint_dir, "mp_rank_00_model_states.pt") + elif zero_stage == 3: + file = os.path.join(checkpoint_dir, "zero_pp_rank_0_mp_rank_00_model_states.pt") + + if not os.path.exists(file): + raise FileNotFoundError(f"can't find model states file at '{file}'") + + return file + + +def get_checkpoint_files(checkpoint_dir, glob_pattern): + # XXX: need to test that this simple glob rule works for multi-node setup too + ckpt_files = sorted(glob.glob(os.path.join(checkpoint_dir, glob_pattern)), key=natural_keys) + + if len(ckpt_files) == 0: + raise FileNotFoundError(f"can't find {glob_pattern} files in directory '{checkpoint_dir}'") + + return ckpt_files + + +def get_optim_files(checkpoint_dir): + return get_checkpoint_files(checkpoint_dir, "*_optim_states.pt") + + +def get_model_state_files(checkpoint_dir): + return get_checkpoint_files(checkpoint_dir, "*_model_states.pt") + + +def _has_autoep_zero3_partitioned_metadata(state_dict): + autoep_layers = state_dict.get(AUTOEP_LAYERS_KEY) + if autoep_layers is None: + autoep_layers = state_dict.get(AUTOEP_LAYERS_KEY_LEGACY) + if not isinstance(autoep_layers, list): + return False + return any( + isinstance(entry, dict) + and entry.get(AUTOEP_ZERO3_EXPERT_STATE_FORMAT_KEY) == AUTOEP_ZERO3_PARTITIONED_EXPERT_STATE_FORMAT + for entry in autoep_layers) + + +def _raise_if_autoep_zero3_partitioned_state(state_dict): + if _has_autoep_zero3_partitioned_metadata(state_dict): + raise NotImplementedError("zero_to_fp32 does not support AutoEP ZeRO-3 partition-native checkpoints. " + "AutoEP expert parameters are partitioned over expert replica groups, so " + "global data-parallel consolidation would produce incomplete expert tensors. " + "Use ds_to_universal.py for expert-aware conversion.") + + +def _raise_if_autoep_zero3_partitioned_checkpoint(model_files): + for file in model_files: + state_dict = torch.load(file, map_location=device, weights_only=False) + _raise_if_autoep_zero3_partitioned_state(state_dict) + + +def parse_model_states(files): + zero_model_states = [] + for file in files: + state_dict = torch.load(file, map_location=device, weights_only=False) + _raise_if_autoep_zero3_partitioned_state(state_dict) + + if BUFFER_NAMES not in state_dict: + raise ValueError(f"{file} is not a model state checkpoint") + buffer_names = state_dict[BUFFER_NAMES] + if debug: + print("Found buffers:", buffer_names) + + # recover just the buffers while restoring them to fp32 if they were saved in fp16 + buffers = {k: v.float() for k, v in state_dict["module"].items() if k in buffer_names} + param_shapes = state_dict[PARAM_SHAPES] + + # collect parameters that are included in param_shapes + param_names = [] + for s in param_shapes: + for name in s.keys(): + param_names.append(name) + + # update with frozen parameters + frozen_param_shapes = state_dict.get(FROZEN_PARAM_SHAPES, None) + if frozen_param_shapes is not None: + if debug: + print(f"Found frozen_param_shapes: {frozen_param_shapes}") + param_names += list(frozen_param_shapes.keys()) + + # handle shared params + shared_params = [[k, v] for k, v in state_dict["shared_params"].items()] + + ds_version = state_dict.get(DS_VERSION, None) + + frozen_param_fragments = state_dict.get(FROZEN_PARAM_FRAGMENTS, None) + + z_model_state = zero_model_state(buffers=buffers, + param_shapes=param_shapes, + shared_params=shared_params, + ds_version=ds_version, + frozen_param_shapes=frozen_param_shapes, + frozen_param_fragments=frozen_param_fragments) + zero_model_states.append(z_model_state) + + return zero_model_states + + +def parse_optim_states(files, ds_checkpoint_dir): + total_files = len(files) + state_dicts = [] + for f in tqdm(files, desc='Loading checkpoint shards'): + state_dict = torch.load(f, map_location=device, mmap=True, weights_only=False) + # immediately discard the potentially huge 2 optimizer states as we only care for fp32 master weights + # and also handle the case where it was already removed by another helper script + state_dict["optimizer_state_dict"].pop("optimizer_state_dict", None) + state_dicts.append(state_dict) + + if ZERO_STAGE not in state_dicts[0][OPTIMIZER_STATE_DICT]: + raise ValueError(f"{files[0]} is not a zero checkpoint") + zero_stage = state_dicts[0][OPTIMIZER_STATE_DICT][ZERO_STAGE] + world_size = state_dicts[0][OPTIMIZER_STATE_DICT][PARTITION_COUNT] + + # For ZeRO-2 each param group can have different partition_count as data parallelism for expert + # parameters can be different from data parallelism for non-expert parameters. So we can just + # use the max of the partition_count to get the dp world_size. + + if type(world_size) is list: + world_size = max(world_size) + + if world_size != total_files: + raise ValueError( + f"Expected {world_size} of '*_optim_states.pt' under '{ds_checkpoint_dir}' but found {total_files} files. " + "Possibly due to an overwrite of an old checkpoint, or a checkpoint didn't get saved by one or more processes." + ) + + # the groups are named differently in each stage + if zero_stage <= 2: + fp32_groups_key = SINGLE_PARTITION_OF_FP32_GROUPS + elif zero_stage == 3: + fp32_groups_key = FP32_FLAT_GROUPS + else: + raise ValueError(f"unknown zero stage {zero_stage}") + + fp32_flat_groups = [state_dicts[i][OPTIMIZER_STATE_DICT][fp32_groups_key] for i in range(len(state_dicts))] + return zero_stage, world_size, fp32_flat_groups + + +def _get_fp32_state_dict_from_zero_checkpoint(ds_checkpoint_dir, exclude_frozen_parameters): + """ + Returns fp32 state_dict reconstructed from ds checkpoint + + Args: + - ``ds_checkpoint_dir``: path to the deepspeed checkpoint folder (where the optimizer files are) + + """ + print(f"Processing zero checkpoint '{ds_checkpoint_dir}'") + + # parse_model_states rejects AutoEP ZeRO-3 partition-native checkpoints + # before the expensive optimizer-shard load below. + model_files = get_model_state_files(ds_checkpoint_dir) + zero_model_states = parse_model_states(model_files) + print(f'Parsing checkpoint created by deepspeed=={zero_model_states[0].ds_version}') + + optim_files = get_optim_files(ds_checkpoint_dir) + zero_stage, world_size, fp32_flat_groups = parse_optim_states(optim_files, ds_checkpoint_dir) + print(f"Detected checkpoint of type zero stage {zero_stage}, world_size: {world_size}") + + if zero_stage <= 2: + return _get_fp32_state_dict_from_zero2_checkpoint(world_size, fp32_flat_groups, zero_model_states, + exclude_frozen_parameters) + elif zero_stage == 3: + return _get_fp32_state_dict_from_zero3_checkpoint(world_size, fp32_flat_groups, zero_model_states, + exclude_frozen_parameters) + + +def _zero2_merge_frozen_params(state_dict, zero_model_states): + if zero_model_states[0].frozen_param_shapes is None or len(zero_model_states[0].frozen_param_shapes) == 0: + return + + frozen_param_shapes = zero_model_states[0].frozen_param_shapes + frozen_param_fragments = zero_model_states[0].frozen_param_fragments + + if debug: + num_elem = sum(s.numel() for s in frozen_param_shapes.values()) + print(f'rank 0: {FROZEN_PARAM_SHAPES}.numel = {num_elem}') + + wanted_params = len(frozen_param_shapes) + wanted_numel = sum(s.numel() for s in frozen_param_shapes.values()) + avail_numel = sum([p.numel() for p in frozen_param_fragments.values()]) + print(f'Frozen params: Have {avail_numel} numels to process.') + print(f'Frozen params: Need {wanted_numel} numels in {wanted_params} params') + + total_params = 0 + total_numel = 0 + for name, shape in frozen_param_shapes.items(): + total_params += 1 + unpartitioned_numel = shape.numel() + total_numel += unpartitioned_numel + + state_dict[name] = frozen_param_fragments[name] + + if debug: + print(f"{name} full shape: {shape} unpartitioned numel {unpartitioned_numel} ") + + print(f"Reconstructed Frozen fp32 state dict with {total_params} params {total_numel} elements") + + +def _has_callable(obj, fn): + attr = getattr(obj, fn, None) + return callable(attr) + + +def _zero2_merge_trainable_params(state_dict, world_size, fp32_flat_groups, zero_model_states): + param_shapes = zero_model_states[0].param_shapes + + # Reconstruction protocol: + # + # XXX: document this + + if debug: + for i in range(world_size): + for j in range(len(fp32_flat_groups[0])): + print(f"{FP32_FLAT_GROUPS}[{i}][{j}].shape={fp32_flat_groups[i][j].shape}") + + # XXX: memory usage doubles here (zero2) + num_param_groups = len(fp32_flat_groups[0]) + merged_single_partition_of_fp32_groups = [] + for i in range(num_param_groups): + merged_partitions = [sd[i] for sd in fp32_flat_groups] + full_single_fp32_vector = torch.cat(merged_partitions, 0) + merged_single_partition_of_fp32_groups.append(full_single_fp32_vector) + avail_numel = sum( + [full_single_fp32_vector.numel() for full_single_fp32_vector in merged_single_partition_of_fp32_groups]) + + if debug: + wanted_params = sum([len(shapes) for shapes in param_shapes]) + wanted_numel = sum([sum(shape.numel() for shape in shapes.values()) for shapes in param_shapes]) + # not asserting if there is a mismatch due to possible padding + print(f"Have {avail_numel} numels to process.") + print(f"Need {wanted_numel} numels in {wanted_params} params.") + + # params + # XXX: for huge models that can't fit into the host's RAM we will have to recode this to support + # out-of-core computing solution + total_numel = 0 + total_params = 0 + for shapes, full_single_fp32_vector in zip(param_shapes, merged_single_partition_of_fp32_groups): + offset = 0 + avail_numel = full_single_fp32_vector.numel() + for name, shape in shapes.items(): + + unpartitioned_numel = shape.numel() if _has_callable(shape, 'numel') else math.prod(shape) + total_numel += unpartitioned_numel + total_params += 1 + + if debug: + print(f"{name} full shape: {shape} unpartitioned numel {unpartitioned_numel} ") + state_dict[name] = full_single_fp32_vector.narrow(0, offset, unpartitioned_numel).view(shape) + offset += unpartitioned_numel + + # Z2 started to align to 2*world_size to improve nccl performance. Therefore both offset and + # avail_numel can differ by anywhere between 0..2*world_size. Due to two unrelated complex + # paddings performed in the code it's almost impossible to predict the exact numbers w/o the + # live optimizer object, so we are checking that the numbers are within the right range + align_to = 2 * world_size + + def zero2_align(x): + return align_to * math.ceil(x / align_to) + + if debug: + print(f"original offset={offset}, avail_numel={avail_numel}") + + offset = zero2_align(offset) + avail_numel = zero2_align(avail_numel) + + if debug: + print(f"aligned offset={offset}, avail_numel={avail_numel}") + + # Sanity check + if offset != avail_numel: + raise ValueError(f"consumed {offset} numels out of {avail_numel} - something is wrong") + + print(f"Reconstructed fp32 state dict with {total_params} params {total_numel} elements") + + +def _get_fp32_state_dict_from_zero2_checkpoint(world_size, fp32_flat_groups, zero_model_states, + exclude_frozen_parameters): + state_dict = OrderedDict() + + # buffers + buffers = zero_model_states[0].buffers + state_dict.update(buffers) + if debug: + print(f"added {len(buffers)} buffers") + + if not exclude_frozen_parameters: + _zero2_merge_frozen_params(state_dict, zero_model_states) + + _zero2_merge_trainable_params(state_dict, world_size, fp32_flat_groups, zero_model_states) + + # recover shared parameters + for pair in zero_model_states[0].shared_params: + if pair[1] in state_dict: + state_dict[pair[0]] = state_dict[pair[1]] + + return state_dict + + +def zero3_partitioned_param_info(unpartitioned_numel, world_size): + remainder = unpartitioned_numel % world_size + padding_numel = (world_size - remainder) if remainder else 0 + partitioned_numel = math.ceil(unpartitioned_numel / world_size) + return partitioned_numel, padding_numel + + +def _zero3_merge_frozen_params(state_dict, world_size, zero_model_states): + if zero_model_states[0].frozen_param_shapes is None or len(zero_model_states[0].frozen_param_shapes) == 0: + return + + if debug: + for i in range(world_size): + num_elem = sum(s.numel() for s in zero_model_states[i].frozen_param_fragments.values()) + print(f'rank {i}: {FROZEN_PARAM_SHAPES}.numel = {num_elem}') + + frozen_param_shapes = zero_model_states[0].frozen_param_shapes + wanted_params = len(frozen_param_shapes) + wanted_numel = sum(s.numel() for s in frozen_param_shapes.values()) + avail_numel = sum([p.numel() for p in zero_model_states[0].frozen_param_fragments.values()]) * world_size + print(f'Frozen params: Have {avail_numel} numels to process.') + print(f'Frozen params: Need {wanted_numel} numels in {wanted_params} params') + + total_params = 0 + total_numel = 0 + for name, shape in zero_model_states[0].frozen_param_shapes.items(): + total_params += 1 + unpartitioned_numel = shape.numel() + total_numel += unpartitioned_numel + + param_frags = tuple(model_state.frozen_param_fragments[name] for model_state in zero_model_states) + state_dict[name] = torch.cat(param_frags, 0).narrow(0, 0, unpartitioned_numel).view(shape) + + partitioned_numel, partitioned_padding_numel = zero3_partitioned_param_info(unpartitioned_numel, world_size) + + if debug: + print( + f"Frozen params: {total_params} {name} full shape: {shape} partition0 numel={partitioned_numel} partitioned_padding_numel={partitioned_padding_numel}" + ) + + print(f"Reconstructed Frozen fp32 state dict with {total_params} params {total_numel} elements") + + +class GatheredTensor: + """ + A pseudo tensor that collects partitioned weights. + It is more memory efficient when there are multiple groups. + """ + + def __init__(self, flat_groups, flat_groups_offset, offset, partitioned_numel, shape): + self.flat_groups = flat_groups + self.flat_groups_offset = flat_groups_offset + self.offset = offset + self.partitioned_numel = partitioned_numel + self.shape = shape + self.dtype = self.flat_groups[0][0].dtype + + def contiguous(self): + """ + Merge partitioned weights from flat_groups into a single tensor. + """ + end_idx = self.offset + self.partitioned_numel + world_size = len(self.flat_groups) + pad_flat_param_chunks = [] + + for rank_i in range(world_size): + # for each rank, we need to collect weights from related group/groups + flat_groups_at_rank_i = self.flat_groups[rank_i] + start_group_id = None + end_group_id = None + for group_id in range(len(self.flat_groups_offset)): + if self.flat_groups_offset[group_id] <= self.offset < self.flat_groups_offset[group_id + 1]: + start_group_id = group_id + if self.flat_groups_offset[group_id] < end_idx <= self.flat_groups_offset[group_id + 1]: + end_group_id = group_id + break + # collect weights from related group/groups + for group_id in range(start_group_id, end_group_id + 1): + flat_tensor = flat_groups_at_rank_i[group_id] + start_offset = self.offset - self.flat_groups_offset[group_id] + end_offset = min(end_idx, self.flat_groups_offset[group_id + 1]) - self.flat_groups_offset[group_id] + pad_flat_param_chunks.append(flat_tensor[start_offset:end_offset]) + + # collect weights from all ranks + pad_flat_param = torch.cat(pad_flat_param_chunks, dim=0) + param = pad_flat_param[:self.shape.numel()].view(self.shape).contiguous() + return param + + +def _zero3_merge_trainable_params(state_dict, world_size, fp32_flat_groups, zero_model_states): + param_shapes = zero_model_states[0].param_shapes + avail_numel = sum([flat_group.numel() for flat_group in fp32_flat_groups[0]]) * world_size + + # Reconstruction protocol: For zero3 we need to zip the partitions together at boundary of each + # param, re-consolidating each param, while dealing with padding if any + + # merge list of dicts, preserving order + param_shapes = {k: v for d in param_shapes for k, v in d.items()} + + if debug: + for i in range(world_size): + print(f"{FP32_FLAT_GROUPS}[{i}].shape={fp32_flat_groups[i].shape}") + + wanted_params = len(param_shapes) + wanted_numel = sum(shape.numel() for shape in param_shapes.values()) + # not asserting if there is a mismatch due to possible padding + avail_numel = fp32_flat_groups[0].numel() * world_size + print(f"Trainable params: Have {avail_numel} numels to process.") + print(f"Trainable params: Need {wanted_numel} numels in {wanted_params} params.") + + # params + # XXX: for huge models that can't fit into the host's RAM we will have to recode this to support + # out-of-core computing solution + offset = 0 + total_numel = 0 + total_params = 0 + flat_groups_offset = [0] + list(np.cumsum([flat_tensor.numel() for flat_tensor in fp32_flat_groups[0]])) + for name, shape in tqdm(param_shapes.items(), desc='Gathering sharded weights'): + unpartitioned_numel = shape.numel() + total_numel += unpartitioned_numel + total_params += 1 + partitioned_numel, partitioned_padding_numel = zero3_partitioned_param_info(unpartitioned_numel, world_size) + + if debug: + print( + f"Trainable params: {total_params} {name} full shape: {shape} partition0 numel={partitioned_numel} partitioned_padding_numel={partitioned_padding_numel}" + ) + + # memory efficient tensor + tensor = GatheredTensor(fp32_flat_groups, flat_groups_offset, offset, partitioned_numel, shape) + state_dict[name] = tensor + offset += partitioned_numel + + offset *= world_size + + # Sanity check + if offset != avail_numel: + raise ValueError(f"consumed {offset} numels out of {avail_numel} - something is wrong") + + print(f"Reconstructed Trainable fp32 state dict with {total_params} params {total_numel} elements") + + +def _get_fp32_state_dict_from_zero3_checkpoint(world_size, fp32_flat_groups, zero_model_states, + exclude_frozen_parameters): + state_dict = OrderedDict() + + # buffers + buffers = zero_model_states[0].buffers + state_dict.update(buffers) + if debug: + print(f"added {len(buffers)} buffers") + + if not exclude_frozen_parameters: + _zero3_merge_frozen_params(state_dict, world_size, zero_model_states) + + _zero3_merge_trainable_params(state_dict, world_size, fp32_flat_groups, zero_model_states) + + # recover shared parameters + for pair in zero_model_states[0].shared_params: + if pair[1] in state_dict: + state_dict[pair[0]] = state_dict[pair[1]] + + return state_dict + + +def to_torch_tensor(state_dict, return_empty_tensor=False): + """ + Convert state_dict of GatheredTensor to torch tensor + """ + torch_state_dict = {} + converted_tensors = {} + for name, tensor in state_dict.items(): + tensor_id = id(tensor) + if tensor_id in converted_tensors: # shared tensors + shared_tensor = torch_state_dict[converted_tensors[tensor_id]] + torch_state_dict[name] = shared_tensor + else: + converted_tensors[tensor_id] = name + if return_empty_tensor: + torch_state_dict[name] = torch.empty(tensor.shape, dtype=tensor.dtype) + else: + torch_state_dict[name] = tensor.contiguous() + return torch_state_dict + + +def get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir, + tag=None, + exclude_frozen_parameters=False, + lazy_mode=False): + """ + Convert ZeRO 2 or 3 checkpoint into a single fp32 consolidated state_dict that can be loaded with + ``load_state_dict()`` and used for training without DeepSpeed or shared with others, for example + via a model hub. + + Args: + - ``checkpoint_dir``: path to the desired checkpoint folder + - ``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`` + - ``exclude_frozen_parameters``: exclude frozen parameters + - ``lazy_mode``: get state_dict in lazy mode. It returns a dict of pesduo tensor instead of torch tensor, which is more memory efficient. + Convert the pesduo tensor to torch tensor by ``.contiguous()`` + + Returns: + - pytorch ``state_dict`` + + A typical usage might be :: + + from deepspeed.utils.zero_to_fp32 import get_fp32_state_dict_from_zero_checkpoint + # do the training and checkpoint saving + state_dict = get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir) # already on cpu + model = model.cpu() # move to cpu + model.load_state_dict(state_dict) + # submit to model hub or save the model to share with others + + In this example the ``model`` will no longer be usable in the deepspeed context of the same + application. i.e. you will need to re-initialize the deepspeed engine, since + ``model.load_state_dict(state_dict)`` will remove all the deepspeed magic from it. + + If you want it all done for you, use ``load_state_dict_from_zero_checkpoint`` instead. + + Note: the above usage may not work if your application doesn't have sufficient free CPU memory. + You may need to use the offline approach using the ``zero_to_fp32.py`` script that is saved with + the checkpoint. Or you can load state_dict in lazy mode :: + + from deepspeed.utils.zero_to_fp32 import get_fp32_state_dict_from_zero_checkpoint + state_dict = get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir, lazy_mode=True) # not on cpu + for name, lazy_tensor in state_dict.item(): + tensor = lazy_tensor.contiguous() # to cpu + print(name, tensor) + # del tensor to release memory if it no longer in use + """ + if tag is None: + latest_path = os.path.join(checkpoint_dir, 'latest') + if os.path.isfile(latest_path): + with open(latest_path, 'r') as fd: + tag = fd.read().strip() + else: + raise ValueError(f"Unable to find 'latest' file at {latest_path}") + + ds_checkpoint_dir = os.path.join(checkpoint_dir, tag) + + if not os.path.isdir(ds_checkpoint_dir): + raise FileNotFoundError(f"Directory '{ds_checkpoint_dir}' doesn't exist") + + state_dict = _get_fp32_state_dict_from_zero_checkpoint(ds_checkpoint_dir, exclude_frozen_parameters) + if lazy_mode: + return state_dict + else: + return to_torch_tensor(state_dict) + + +def convert_zero_checkpoint_to_fp32_state_dict(checkpoint_dir, + output_dir, + max_shard_size="5GB", + safe_serialization=False, + tag=None, + exclude_frozen_parameters=False): + """ + Convert ZeRO 2 or 3 checkpoint into a single fp32 consolidated ``state_dict`` file that can be + loaded with ``torch.load(file)`` + ``load_state_dict()`` and used for training without DeepSpeed. + + Args: + - ``checkpoint_dir``: path to the desired checkpoint folder. (one that contains the tag-folder, like ``global_step14``) + - ``output_dir``: directory to the pytorch fp32 state_dict output files + - ``max_shard_size``: the maximum size for a checkpoint before being sharded, default value is 5GB + - ``safe_serialization``: whether to save the model using `safetensors` or the traditional PyTorch way (that uses `pickle`). + - ``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`` + - ``exclude_frozen_parameters``: exclude frozen parameters + """ + + # Dependency pre-check + if safe_serialization: + try: + from safetensors.torch import save_file + except ImportError: + print('If you want to use `safe_serialization`, please `pip install safetensors`') + raise + if max_shard_size is not None: + try: + from huggingface_hub import split_torch_state_dict_into_shards + except ImportError: + print('If you want to use `max_shard_size`, please `pip install huggingface_hub`') + raise + + # Convert zero checkpoint to state_dict + state_dict = get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir, + tag, + exclude_frozen_parameters, + lazy_mode=True) + + # Shard the model if it is too big. + weights_name = "model.safetensors" if safe_serialization else "pytorch_model.bin" + if max_shard_size is not None: + filename_pattern = weights_name.replace(".bin", "{suffix}.bin").replace(".safetensors", "{suffix}.safetensors") + # an memory-efficient approach for sharding + empty_state_dict = to_torch_tensor(state_dict, return_empty_tensor=True) + state_dict_split = split_torch_state_dict_into_shards(empty_state_dict, + filename_pattern=filename_pattern, + max_shard_size=max_shard_size) + else: + from collections import namedtuple + StateDictSplit = namedtuple("StateDictSplit", ["is_sharded", "filename_to_tensors"]) + state_dict_split = StateDictSplit(is_sharded=False, + filename_to_tensors={weights_name: list(state_dict.keys())}) + + # Save the model by shard + os.makedirs(output_dir, exist_ok=True) + filename_to_tensors = state_dict_split.filename_to_tensors.items() + for shard_file, tensors in tqdm(filename_to_tensors, desc="Saving checkpoint shards"): + shard_state_dict = {tensor_name: state_dict[tensor_name] for tensor_name in tensors} + shard_state_dict = to_torch_tensor(shard_state_dict) + output_path = os.path.join(output_dir, shard_file) + if safe_serialization: + save_file(shard_state_dict, output_path, metadata={"format": "pt"}) + else: + torch.save(shard_state_dict, output_path) + # release the memory of current shard + for tensor_name in list(shard_state_dict.keys()): + del state_dict[tensor_name] + del shard_state_dict[tensor_name] + del shard_state_dict + gc.collect() + + # Save index if sharded + if state_dict_split.is_sharded: + index = { + "metadata": state_dict_split.metadata, + "weight_map": state_dict_split.tensor_to_filename, + } + save_index_file = "model.safetensors.index.json" if safe_serialization else "pytorch_model.bin.index.json" + save_index_file = os.path.join(output_dir, save_index_file) + with open(save_index_file, "w", encoding="utf-8") as f: + content = json.dumps(index, indent=2, sort_keys=True) + "\n" + f.write(content) + + +def load_state_dict_from_zero_checkpoint(model, checkpoint_dir, tag=None): + """ + 1. Put the provided model to cpu + 2. Convert ZeRO 2 or 3 checkpoint into a single fp32 consolidated ``state_dict`` + 3. Load it into the provided model + + Args: + - ``model``: the model object to update + - ``checkpoint_dir``: path to the desired checkpoint folder. (one that contains the tag-folder, like ``global_step14``) + - ``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`` + + Returns: + - ``model`: modified model + + Make sure you have plenty of CPU memory available before you call this function. If you don't + have enough use the ``zero_to_fp32.py`` utility to do the conversion. You will find it + conveniently placed for you in the checkpoint folder. + + A typical usage might be :: + + from deepspeed.utils.zero_to_fp32 import load_state_dict_from_zero_checkpoint + model = load_state_dict_from_zero_checkpoint(trainer.model, checkpoint_dir) + # submit to model hub or save the model to share with others + + Note, that once this was run, the ``model`` will no longer be usable in the deepspeed context + of the same application. i.e. you will need to re-initialize the deepspeed engine, since + ``model.load_state_dict(state_dict)`` will remove all the deepspeed magic from it. + + """ + logger.info("Extracting fp32 weights") + state_dict = get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir, tag) + + logger.info("Overwriting model with fp32 weights") + model = model.cpu() + model.load_state_dict(state_dict, strict=False) + + return model + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument("checkpoint_dir", + type=str, + help="path to the desired checkpoint folder, e.g., path/checkpoint-12") + parser.add_argument("output_dir", + type=str, + help="directory to the pytorch fp32 state_dict output files" + "(e.g. path/checkpoint-12-output/)") + parser.add_argument( + "--max_shard_size", + type=str, + default="5GB", + help="The maximum size for a checkpoint before being sharded. Checkpoints shard will then be each of size" + "lower than this size. If expressed as a string, needs to be digits followed by a unit (like `5MB`" + "We default it to 5GB in order for models to be able to run easily on free-tier google colab instances" + "without CPU OOM issues.") + parser.add_argument( + "--safe_serialization", + default=False, + action='store_true', + help="Whether to save the model using `safetensors` or the traditional PyTorch way (that uses `pickle`).") + parser.add_argument("-t", + "--tag", + type=str, + default=None, + help="checkpoint tag used as a unique identifier for checkpoint. e.g., global_step1") + parser.add_argument("--exclude_frozen_parameters", action='store_true', help="exclude frozen parameters") + parser.add_argument("-d", "--debug", action='store_true', help="enable debug") + args = parser.parse_args() + + debug = args.debug + + convert_zero_checkpoint_to_fp32_state_dict(args.checkpoint_dir, + args.output_dir, + max_shard_size=args.max_shard_size, + safe_serialization=args.safe_serialization, + tag=args.tag, + exclude_frozen_parameters=args.exclude_frozen_parameters) diff --git a/qwen3/csd/checkpoint-1570/README.md b/qwen3/csd/checkpoint-1570/README.md new file mode 100644 index 0000000000000000000000000000000000000000..776f98d43659dd923b8c3e5649c5ae66d1f99f3e --- /dev/null +++ b/qwen3/csd/checkpoint-1570/README.md @@ -0,0 +1,208 @@ +--- +base_model: Qwen/Qwen3-0.6B +library_name: peft +pipeline_tag: text-generation +tags: +- base_model:adapter:Qwen/Qwen3-0.6B +- llama-factory +- lora +- transformers +--- + +# Model Card for Model ID + + + + + +## Model Details + +### Model Description + + + + + +- **Developed by:** [More Information Needed] +- **Funded by [optional]:** [More Information Needed] +- **Shared by [optional]:** [More Information Needed] +- **Model type:** [More Information Needed] +- **Language(s) (NLP):** [More Information Needed] +- **License:** [More Information Needed] +- **Finetuned from model [optional]:** [More Information Needed] + +### Model Sources [optional] + + + +- **Repository:** [More Information Needed] +- **Paper [optional]:** [More Information Needed] +- **Demo [optional]:** [More Information Needed] + +## Uses + + + +### Direct Use + + + +[More Information Needed] + +### Downstream Use [optional] + + + +[More Information Needed] + +### Out-of-Scope Use + + + +[More Information Needed] + +## Bias, Risks, and Limitations + + + +[More Information Needed] + +### Recommendations + + + +Users (both direct and downstream) should be made aware of the risks, biases and limitations of the model. More information needed for further recommendations. + +## How to Get Started with the Model + +Use the code below to get started with the model. + +[More Information Needed] + +## Training Details + +### Training Data + + + +[More Information Needed] + +### Training Procedure + + + +#### Preprocessing [optional] + +[More Information Needed] + + +#### Training Hyperparameters + +- **Training regime:** [More Information Needed] + +#### Speeds, Sizes, Times [optional] + + + +[More Information Needed] + +## Evaluation + + + +### Testing Data, Factors & Metrics + +#### Testing Data + + + +[More Information Needed] + +#### Factors + + + +[More Information Needed] + +#### Metrics + + + +[More Information Needed] + +### Results + +[More Information Needed] + +#### Summary + + + +## Model Examination [optional] + + + +[More Information Needed] + +## Environmental Impact + + + +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). + +- **Hardware Type:** [More Information Needed] +- **Hours used:** [More Information Needed] +- **Cloud Provider:** [More Information Needed] +- **Compute Region:** [More Information Needed] +- **Carbon Emitted:** [More Information Needed] + +## Technical Specifications [optional] + +### Model Architecture and Objective + +[More Information Needed] + +### Compute Infrastructure + +[More Information Needed] + +#### Hardware + +[More Information Needed] + +#### Software + +[More Information Needed] + +## Citation [optional] + + + +**BibTeX:** + +[More Information Needed] + +**APA:** + +[More Information Needed] + +## Glossary [optional] + + + +[More Information Needed] + +## More Information [optional] + +[More Information Needed] + +## Model Card Authors [optional] + +[More Information Needed] + +## Model Card Contact + +[More Information Needed] +### Framework versions + +- PEFT 0.18.1 \ No newline at end of file diff --git a/qwen3/csd/checkpoint-1570/adapter_config.json b/qwen3/csd/checkpoint-1570/adapter_config.json new file mode 100644 index 0000000000000000000000000000000000000000..9959003652c9aaae4cece005b46aaf87e6d0f224 --- /dev/null +++ b/qwen3/csd/checkpoint-1570/adapter_config.json @@ -0,0 +1,46 @@ +{ + "alora_invocation_tokens": null, + "alpha_pattern": {}, + "arrow_config": null, + "auto_mapping": null, + "base_model_name_or_path": "Qwen/Qwen3-0.6B", + "bias": "none", + "corda_config": null, + "ensure_weight_tying": false, + "eva_config": null, + "exclude_modules": null, + "fan_in_fan_out": false, + "inference_mode": true, + "init_lora_weights": true, + "layer_replication": null, + "layers_pattern": null, + "layers_to_transform": null, + "loftq_config": {}, + "lora_alpha": 64, + "lora_bias": false, + "lora_dropout": 0.1, + "megatron_config": null, + "megatron_core": "megatron.core", + "modules_to_save": null, + "peft_type": "LORA", + "peft_version": "0.18.1", + "qalora_group_size": 16, + "r": 32, + "rank_pattern": {}, + "revision": null, + "target_modules": [ + "down_proj", + "up_proj", + "v_proj", + "q_proj", + "gate_proj", + "o_proj", + "k_proj" + ], + "target_parameters": null, + "task_type": "CAUSAL_LM", + "trainable_token_indices": null, + "use_dora": false, + "use_qalora": false, + "use_rslora": false +} \ No newline at end of file diff --git a/qwen3/csd/checkpoint-1570/adapter_model.safetensors b/qwen3/csd/checkpoint-1570/adapter_model.safetensors new file mode 100644 index 0000000000000000000000000000000000000000..57ad3d3cb4fe71a4d7f36999029d2b5e7ba925c6 --- /dev/null +++ b/qwen3/csd/checkpoint-1570/adapter_model.safetensors @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d4406b594fb337274c887bfad3ad274f42413413cfb01fb17f61a907e23a5aca +size 40422560 diff --git a/qwen3/csd/checkpoint-1570/chat_template.jinja b/qwen3/csd/checkpoint-1570/chat_template.jinja new file mode 100644 index 0000000000000000000000000000000000000000..01be9b307daa2d425f7c168c9fb145a286e0afb4 --- /dev/null +++ b/qwen3/csd/checkpoint-1570/chat_template.jinja @@ -0,0 +1,89 @@ +{%- if tools %} + {{- '<|im_start|>system\n' }} + {%- if messages[0].role == 'system' %} + {{- messages[0].content + '\n\n' }} + {%- endif %} + {{- "# Tools\n\nYou may call one or more functions to assist with the user query.\n\nYou are provided with function signatures within XML tags:\n" }} + {%- for tool in tools %} + {{- "\n" }} + {{- tool | tojson }} + {%- endfor %} + {{- "\n\n\nFor each function call, return a json object with function name and arguments within XML tags:\n\n{\"name\": , \"arguments\": }\n<|im_end|>\n" }} +{%- else %} + {%- if messages[0].role == 'system' %} + {{- '<|im_start|>system\n' + messages[0].content + '<|im_end|>\n' }} + {%- endif %} +{%- endif %} +{%- set ns = namespace(multi_step_tool=true, last_query_index=messages|length - 1) %} +{%- for message in messages[::-1] %} + {%- set index = (messages|length - 1) - loop.index0 %} + {%- if ns.multi_step_tool and message.role == "user" and message.content is string and not(message.content.startswith('') and message.content.endswith('')) %} + {%- set ns.multi_step_tool = false %} + {%- set ns.last_query_index = index %} + {%- endif %} +{%- endfor %} +{%- for message in messages %} + {%- if message.content is string %} + {%- set content = message.content %} + {%- else %} + {%- set content = '' %} + {%- endif %} + {%- if (message.role == "user") or (message.role == "system" and not loop.first) %} + {{- '<|im_start|>' + message.role + '\n' + content + '<|im_end|>' + '\n' }} + {%- elif message.role == "assistant" %} + {%- set reasoning_content = '' %} + {%- if message.reasoning_content is string %} + {%- set reasoning_content = message.reasoning_content %} + {%- else %} + {%- if '' in content %} + {%- set reasoning_content = content.split('')[0].rstrip('\n').split('')[-1].lstrip('\n') %} + {%- set content = content.split('')[-1].lstrip('\n') %} + {%- endif %} + {%- endif %} + {%- if loop.index0 > ns.last_query_index %} + {%- if loop.last or (not loop.last and reasoning_content) %} + {{- '<|im_start|>' + message.role + '\n\n' + reasoning_content.strip('\n') + '\n\n\n' + content.lstrip('\n') }} + {%- else %} + {{- '<|im_start|>' + message.role + '\n' + content }} + {%- endif %} + {%- else %} + {{- '<|im_start|>' + message.role + '\n' + content }} + {%- endif %} + {%- if message.tool_calls %} + {%- for tool_call in message.tool_calls %} + {%- if (loop.first and content) or (not loop.first) %} + {{- '\n' }} + {%- endif %} + {%- if tool_call.function %} + {%- set tool_call = tool_call.function %} + {%- endif %} + {{- '\n{"name": "' }} + {{- tool_call.name }} + {{- '", "arguments": ' }} + {%- if tool_call.arguments is string %} + {{- tool_call.arguments }} + {%- else %} + {{- tool_call.arguments | tojson }} + {%- endif %} + {{- '}\n' }} + {%- endfor %} + {%- endif %} + {{- '<|im_end|>\n' }} + {%- elif message.role == "tool" %} + {%- if loop.first or (messages[loop.index0 - 1].role != "tool") %} + {{- '<|im_start|>user' }} + {%- endif %} + {{- '\n\n' }} + {{- content }} + {{- '\n' }} + {%- if loop.last or (messages[loop.index0 + 1].role != "tool") %} + {{- '<|im_end|>\n' }} + {%- endif %} + {%- endif %} +{%- endfor %} +{%- if add_generation_prompt %} + {{- '<|im_start|>assistant\n' }} + {%- if enable_thinking is defined and enable_thinking is false %} + {{- '\n\n\n\n' }} + {%- endif %} +{%- endif %} \ No newline at end of file diff --git a/qwen3/csd/checkpoint-1570/global_step1570/bf16_zero_pp_rank_0_mp_rank_00_optim_states.pt b/qwen3/csd/checkpoint-1570/global_step1570/bf16_zero_pp_rank_0_mp_rank_00_optim_states.pt new file mode 100644 index 0000000000000000000000000000000000000000..fd9527739658e30908693b44d17300d100d06c78 --- /dev/null +++ b/qwen3/csd/checkpoint-1570/global_step1570/bf16_zero_pp_rank_0_mp_rank_00_optim_states.pt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f526c3c23ccaa39490051bd670107dfeaff6c30303d8ef087b0d3c4445db877b +size 121135557 diff --git a/qwen3/csd/checkpoint-1570/global_step1570/bf16_zero_pp_rank_1_mp_rank_00_optim_states.pt b/qwen3/csd/checkpoint-1570/global_step1570/bf16_zero_pp_rank_1_mp_rank_00_optim_states.pt new file mode 100644 index 0000000000000000000000000000000000000000..e5988f596beaba9f11b34f411b9203f01b45d79a --- /dev/null +++ b/qwen3/csd/checkpoint-1570/global_step1570/bf16_zero_pp_rank_1_mp_rank_00_optim_states.pt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8f06c88d8898c46f359073bab03b26000345de6d57b6df8cc7253c0fc3ce00c1 +size 121135749 diff --git a/qwen3/csd/checkpoint-1570/global_step1570/mp_rank_00_model_states.pt b/qwen3/csd/checkpoint-1570/global_step1570/mp_rank_00_model_states.pt new file mode 100644 index 0000000000000000000000000000000000000000..2edd69cc73af7ebbb3495460dfbd834aa27970b3 --- /dev/null +++ b/qwen3/csd/checkpoint-1570/global_step1570/mp_rank_00_model_states.pt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:27dc4b35b498bb01ea52e73c324084875d55b19be49beb4afe8c9de2329148bf +size 351841765 diff --git a/qwen3/csd/checkpoint-1570/latest b/qwen3/csd/checkpoint-1570/latest new file mode 100644 index 0000000000000000000000000000000000000000..18c2fcff58fa6daa0a2e7c3a015552a69085778b --- /dev/null +++ b/qwen3/csd/checkpoint-1570/latest @@ -0,0 +1 @@ +global_step1570 \ No newline at end of file diff --git a/qwen3/csd/checkpoint-1570/rng_state_0.pth b/qwen3/csd/checkpoint-1570/rng_state_0.pth new file mode 100644 index 0000000000000000000000000000000000000000..082dc13ddd57b832c2b8b2ef156ed202eb5ff879 --- /dev/null +++ b/qwen3/csd/checkpoint-1570/rng_state_0.pth @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3e473b79bd0bf657ca035b0fcf6dccc1812c2cd6097dfcd0e7d6b7c3eca4e823 +size 14917 diff --git a/qwen3/csd/checkpoint-1570/rng_state_1.pth b/qwen3/csd/checkpoint-1570/rng_state_1.pth new file mode 100644 index 0000000000000000000000000000000000000000..8e2f5a7cefae455902b8f7d01023194cd292e775 --- /dev/null +++ b/qwen3/csd/checkpoint-1570/rng_state_1.pth @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:97d16f50612975ec353b47b7227fe03226cb18ce7ed72b85448e93b7059d5f45 +size 14917 diff --git a/qwen3/csd/checkpoint-1570/scheduler.pt b/qwen3/csd/checkpoint-1570/scheduler.pt new file mode 100644 index 0000000000000000000000000000000000000000..e22954463492d8a070ae427c95418df61893c54c --- /dev/null +++ b/qwen3/csd/checkpoint-1570/scheduler.pt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e6332fac17ae99a07597512c705658da2fd8429d1c39bb776b30e107c2cb7aae +size 1465 diff --git a/qwen3/csd/checkpoint-1570/tokenizer.json b/qwen3/csd/checkpoint-1570/tokenizer.json new file mode 100644 index 0000000000000000000000000000000000000000..c7afbed2efcdf019f88ab0572ec29d3bf595dfe2 --- /dev/null +++ b/qwen3/csd/checkpoint-1570/tokenizer.json @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:be75606093db2094d7cd20f3c2f385c212750648bd6ea4fb2bf507a6a4c55506 +size 11422650 diff --git a/qwen3/csd/checkpoint-1570/tokenizer_config.json b/qwen3/csd/checkpoint-1570/tokenizer_config.json new file mode 100644 index 0000000000000000000000000000000000000000..6623da03457d79d2cd4af9557e9f31407cdb835c --- /dev/null +++ b/qwen3/csd/checkpoint-1570/tokenizer_config.json @@ -0,0 +1,31 @@ +{ + "add_prefix_space": false, + "backend": "tokenizers", + "bos_token": null, + "clean_up_tokenization_spaces": false, + "eos_token": "<|im_end|>", + "errors": "replace", + "extra_special_tokens": [ + "<|im_start|>", + "<|im_end|>", + "<|object_ref_start|>", + "<|object_ref_end|>", + "<|box_start|>", + "<|box_end|>", + "<|quad_start|>", + "<|quad_end|>", + "<|vision_start|>", + "<|vision_end|>", + "<|vision_pad|>", + "<|image_pad|>", + "<|video_pad|>" + ], + "is_local": false, + "local_files_only": false, + "model_max_length": 131072, + "pad_token": "<|endoftext|>", + "padding_side": "right", + "split_special_tokens": false, + "tokenizer_class": "Qwen2Tokenizer", + "unk_token": null +} diff --git a/qwen3/csd/checkpoint-1570/trainer_state.json b/qwen3/csd/checkpoint-1570/trainer_state.json new file mode 100644 index 0000000000000000000000000000000000000000..b233a2ea933f8c557d54743d3eee5cb00ec7191d --- /dev/null +++ b/qwen3/csd/checkpoint-1570/trainer_state.json @@ -0,0 +1,655 @@ +{ + "best_global_step": null, + "best_metric": null, + "best_model_checkpoint": null, + "epoch": 5.0, + "eval_steps": 500, + "global_step": 1570, + "is_hyper_param_search": false, + "is_local_process_zero": true, + "is_world_process_zero": true, + "log_history": [ + { + "epoch": 0.06382130035899482, + "grad_norm": 6.0161848068237305, + "learning_rate": 9.996390385474569e-05, + "loss": 0.11036398410797119, + "step": 20 + }, + { + "epoch": 0.12764260071798963, + "grad_norm": 4.099686622619629, + "learning_rate": 9.984797509888031e-05, + "loss": 0.01695394217967987, + "step": 40 + }, + { + "epoch": 0.19146390107698444, + "grad_norm": 3.3755345344543457, + "learning_rate": 9.965229938050925e-05, + "loss": 0.03482693731784821, + "step": 60 + }, + { + "epoch": 0.25528520143597927, + "grad_norm": 1.194334864616394, + "learning_rate": 9.937719005663432e-05, + "loss": 0.027955988049507143, + "step": 80 + }, + { + "epoch": 0.3191065017949741, + "grad_norm": 6.6159281730651855, + "learning_rate": 9.902308769000724e-05, + "loss": 0.005286623537540436, + "step": 100 + }, + { + "epoch": 0.3829278021539689, + "grad_norm": 2.851339817047119, + "learning_rate": 9.859055934360789e-05, + "loss": 0.01179061084985733, + "step": 120 + }, + { + "epoch": 0.4467491025129637, + "grad_norm": 0.989425539970398, + "learning_rate": 9.808029767254437e-05, + "loss": 0.006131124496459961, + "step": 140 + }, + { + "epoch": 0.5105704028719585, + "grad_norm": 1.3493149280548096, + "learning_rate": 9.749311981482817e-05, + "loss": 0.007052437216043472, + "step": 160 + }, + { + "epoch": 0.5743917032309533, + "grad_norm": 0.9337753057479858, + "learning_rate": 9.682996608280154e-05, + "loss": -0.002346178889274597, + "step": 180 + }, + { + "epoch": 0.6382130035899481, + "grad_norm": 1.5435981750488281, + "learning_rate": 9.609189845731207e-05, + "loss": 0.013309524953365326, + "step": 200 + }, + { + "epoch": 0.702034303948943, + "grad_norm": 0.7995954155921936, + "learning_rate": 9.52800988870462e-05, + "loss": 0.008521870523691178, + "step": 220 + }, + { + "epoch": 0.7658556043079378, + "grad_norm": 1.6571325063705444, + "learning_rate": 9.439586739574513e-05, + "loss": 0.008653326332569123, + "step": 240 + }, + { + "epoch": 0.8296769046669326, + "grad_norm": 0.519936203956604, + "learning_rate": 9.344062000033414e-05, + "loss": 0.004485934227705002, + "step": 260 + }, + { + "epoch": 0.8934982050259274, + "grad_norm": 0.31598174571990967, + "learning_rate": 9.241588644329919e-05, + "loss": 0.003059915825724602, + "step": 280 + }, + { + "epoch": 0.9573195053849222, + "grad_norm": 0.48084524273872375, + "learning_rate": 9.132330774294252e-05, + "loss": 0.005025627836585045, + "step": 300 + }, + { + "epoch": 1.0, + "eval_generator_count": 1712.0, + "eval_generator_exact_match": 86.2734, + "eval_generator_rouge1": 99.1343, + "eval_generator_rouge2": 98.8297, + "eval_generator_rougeL": 98.6074, + "eval_loss": 0.019235465675592422, + "eval_runtime": 603.0951, + "eval_samples_per_second": 5.661, + "eval_selector_accuracy": 93.3995, + "eval_selector_count": 1712.0, + "eval_steps_per_second": 0.177, + "step": 314 + }, + { + "epoch": 1.0191463901076985, + "grad_norm": 0.34810933470726013, + "learning_rate": 9.01646335654399e-05, + "loss": 0.008805014193058014, + "step": 320 + }, + { + "epoch": 1.0829676904666932, + "grad_norm": 0.19888198375701904, + "learning_rate": 8.894171942290817e-05, + "loss": 0.0013909661211073399, + "step": 340 + }, + { + "epoch": 1.146788990825688, + "grad_norm": 1.0506941080093384, + "learning_rate": 8.765652370197003e-05, + "loss": 0.0005901294760406017, + "step": 360 + }, + { + "epoch": 1.210610291184683, + "grad_norm": 2.363455057144165, + "learning_rate": 8.631110452757467e-05, + "loss": -0.0003092627972364426, + "step": 380 + }, + { + "epoch": 1.2744315915436777, + "grad_norm": 0.0766368880867958, + "learning_rate": 8.490761646709642e-05, + "loss": -0.002663038857281208, + "step": 400 + }, + { + "epoch": 1.3382528919026724, + "grad_norm": 0.1551397442817688, + "learning_rate": 8.344830707998953e-05, + "loss": 0.0026730677112936974, + "step": 420 + }, + { + "epoch": 1.4020741922616673, + "grad_norm": 0.7773767113685608, + "learning_rate": 8.193551331852458e-05, + "loss": -0.0011709232814610005, + "step": 440 + }, + { + "epoch": 1.4658954926206622, + "grad_norm": 0.42017874121665955, + "learning_rate": 8.037165778537033e-05, + "loss": -0.0019059792160987855, + "step": 460 + }, + { + "epoch": 1.5297167929796571, + "grad_norm": 1.0544211864471436, + "learning_rate": 7.875924485401427e-05, + "loss": -0.004772515594959259, + "step": 480 + }, + { + "epoch": 1.5935380933386518, + "grad_norm": 0.4706478416919708, + "learning_rate": 7.710085665823444e-05, + "loss": -0.0002438830444589257, + "step": 500 + }, + { + "epoch": 1.6573593936976465, + "grad_norm": 0.22088219225406647, + "learning_rate": 7.539914895704521e-05, + "loss": -0.004391691088676453, + "step": 520 + }, + { + "epoch": 1.7211806940566414, + "grad_norm": 0.5972660183906555, + "learning_rate": 7.365684688173908e-05, + "loss": -0.007541544735431671, + "step": 540 + }, + { + "epoch": 1.7850019944156363, + "grad_norm": 0.19400978088378906, + "learning_rate": 7.18767405718347e-05, + "loss": -0.004146666824817657, + "step": 560 + }, + { + "epoch": 1.848823294774631, + "grad_norm": 1.2469046115875244, + "learning_rate": 7.006168070692036e-05, + "loss": -0.0019529350101947784, + "step": 580 + }, + { + "epoch": 1.9126445951336257, + "grad_norm": 0.14316241443157196, + "learning_rate": 6.821457394154786e-05, + "loss": -0.008291246742010117, + "step": 600 + }, + { + "epoch": 1.9764658954926206, + "grad_norm": 0.4657886326313019, + "learning_rate": 6.633837825048768e-05, + "loss": -0.006107022240757942, + "step": 620 + }, + { + "epoch": 2.0, + "eval_generator_count": 1712.0, + "eval_generator_exact_match": 94.6846, + "eval_generator_rouge1": 99.7652, + "eval_generator_rouge2": 99.667, + "eval_generator_rougeL": 99.5471, + "eval_loss": 0.006834100466221571, + "eval_runtime": 601.0294, + "eval_samples_per_second": 5.68, + "eval_selector_accuracy": 97.8388, + "eval_selector_count": 1712.0, + "eval_steps_per_second": 0.178, + "step": 628 + }, + { + "epoch": 2.038292780215397, + "grad_norm": 0.22094473242759705, + "learning_rate": 6.443609819179926e-05, + "loss": -0.005953450500965118, + "step": 640 + }, + { + "epoch": 2.102114080574392, + "grad_norm": 0.5406356453895569, + "learning_rate": 6.251078009530256e-05, + "loss": -0.0025423141196370125, + "step": 660 + }, + { + "epoch": 2.1659353809333863, + "grad_norm": 0.09373176842927933, + "learning_rate": 6.0565507184155677e-05, + "loss": -0.0044939789921045305, + "step": 680 + }, + { + "epoch": 2.2297566812923812, + "grad_norm": 0.1080167219042778, + "learning_rate": 5.860339463735136e-05, + "loss": -0.00820673182606697, + "step": 700 + }, + { + "epoch": 2.293577981651376, + "grad_norm": 0.05399267002940178, + "learning_rate": 5.662758460103895e-05, + "loss": -0.009635555744171142, + "step": 720 + }, + { + "epoch": 2.357399282010371, + "grad_norm": 0.2048628032207489, + "learning_rate": 5.464124115666095e-05, + "loss": -0.010086850821971893, + "step": 740 + }, + { + "epoch": 2.421220582369366, + "grad_norm": 0.08765007555484772, + "learning_rate": 5.264754525396212e-05, + "loss": -0.008542184531688691, + "step": 760 + }, + { + "epoch": 2.4850418827283605, + "grad_norm": 0.2229253351688385, + "learning_rate": 5.06496896169857e-05, + "loss": -0.011658547818660736, + "step": 780 + }, + { + "epoch": 2.5488631830873554, + "grad_norm": 0.18513049185276031, + "learning_rate": 4.865087363121384e-05, + "loss": -0.00930779054760933, + "step": 800 + }, + { + "epoch": 2.6126844834463503, + "grad_norm": 0.3498702347278595, + "learning_rate": 4.6654298220040673e-05, + "loss": -0.014870831370353698, + "step": 820 + }, + { + "epoch": 2.6765057838053448, + "grad_norm": 0.16160713136196136, + "learning_rate": 4.466316071878229e-05, + "loss": -0.020250825583934783, + "step": 840 + }, + { + "epoch": 2.74032708416434, + "grad_norm": 0.16046860814094543, + "learning_rate": 4.2680649754432913e-05, + "loss": -0.018617722392082214, + "step": 860 + }, + { + "epoch": 2.8041483845233346, + "grad_norm": 0.17135752737522125, + "learning_rate": 4.070994013936646e-05, + "loss": -0.020963044464588167, + "step": 880 + }, + { + "epoch": 2.8679696848823295, + "grad_norm": 0.24867695569992065, + "learning_rate": 3.8754187787161155e-05, + "loss": -0.020418259501457214, + "step": 900 + }, + { + "epoch": 2.9317909852413244, + "grad_norm": 0.12315966188907623, + "learning_rate": 3.681652465868875e-05, + "loss": -0.018548570573329926, + "step": 920 + }, + { + "epoch": 2.995612285600319, + "grad_norm": 0.14333273470401764, + "learning_rate": 3.490005374656184e-05, + "loss": -0.018815448880195616, + "step": 940 + }, + { + "epoch": 3.0, + "eval_generator_count": 1712.0, + "eval_generator_exact_match": 95.736, + "eval_generator_rouge1": 99.9465, + "eval_generator_rouge2": 99.8866, + "eval_generator_rougeL": 99.7132, + "eval_loss": 0.005336109548807144, + "eval_runtime": 608.1178, + "eval_samples_per_second": 5.614, + "eval_selector_accuracy": 97.722, + "eval_selector_count": 1712.0, + "eval_steps_per_second": 0.176, + "step": 942 + }, + { + "epoch": 3.057439170323095, + "grad_norm": 0.1492357701063156, + "learning_rate": 3.3007844105971336e-05, + "loss": -0.02238200604915619, + "step": 960 + }, + { + "epoch": 3.12126047068209, + "grad_norm": 0.0778684988617897, + "learning_rate": 3.114292593987149e-05, + "loss": -0.02527567744255066, + "step": 980 + }, + { + "epoch": 3.185081771041085, + "grad_norm": 0.07070758193731308, + "learning_rate": 2.9308285746383408e-05, + "loss": -0.02356054335832596, + "step": 1000 + }, + { + "epoch": 3.24890307140008, + "grad_norm": 0.10038785636425018, + "learning_rate": 2.7506861536187867e-05, + "loss": -0.019069214165210725, + "step": 1020 + }, + { + "epoch": 3.3127243717590744, + "grad_norm": 0.33050113916397095, + "learning_rate": 2.5741538127566396e-05, + "loss": -0.022282478213310242, + "step": 1040 + }, + { + "epoch": 3.3765456721180693, + "grad_norm": 0.12148360908031464, + "learning_rate": 2.4015142526625115e-05, + "loss": -0.02368807643651962, + "step": 1060 + }, + { + "epoch": 3.4403669724770642, + "grad_norm": 0.16367903351783752, + "learning_rate": 2.233043940009967e-05, + "loss": -0.02528309226036072, + "step": 1080 + }, + { + "epoch": 3.504188272836059, + "grad_norm": 0.0877315029501915, + "learning_rate": 2.0690126647990974e-05, + "loss": -0.026697894930839537, + "step": 1100 + }, + { + "epoch": 3.568009573195054, + "grad_norm": 0.06676916033029556, + "learning_rate": 1.9096831083121828e-05, + "loss": -0.028009063005447386, + "step": 1120 + }, + { + "epoch": 3.6318308735540485, + "grad_norm": 0.09503277391195297, + "learning_rate": 1.7553104224533324e-05, + "loss": -0.0323164701461792, + "step": 1140 + }, + { + "epoch": 3.6956521739130435, + "grad_norm": 0.08010950684547424, + "learning_rate": 1.606141821145735e-05, + "loss": -0.03129267990589142, + "step": 1160 + }, + { + "epoch": 3.7594734742720384, + "grad_norm": 0.15882308781147003, + "learning_rate": 1.4624161844408763e-05, + "loss": -0.03188144564628601, + "step": 1180 + }, + { + "epoch": 3.823294774631033, + "grad_norm": 0.07064881920814514, + "learning_rate": 1.324363675973698e-05, + "loss": -0.03279578983783722, + "step": 1200 + }, + { + "epoch": 3.8871160749900278, + "grad_norm": 0.24478258192539215, + "learning_rate": 1.1922053743763052e-05, + "loss": -0.03418469429016113, + "step": 1220 + }, + { + "epoch": 3.9509373753490227, + "grad_norm": 0.09533516317605972, + "learning_rate": 1.0661529192404973e-05, + "loss": -0.036141425371170044, + "step": 1240 + }, + { + "epoch": 4.0, + "eval_generator_count": 1712.0, + "eval_generator_exact_match": 96.2617, + "eval_generator_rouge1": 99.8812, + "eval_generator_rouge2": 99.8259, + "eval_generator_rougeL": 99.6849, + "eval_loss": 0.0041860658675432205, + "eval_runtime": 606.5994, + "eval_samples_per_second": 5.628, + "eval_selector_accuracy": 98.3645, + "eval_selector_count": 1712.0, + "eval_steps_per_second": 0.176, + "step": 1256 + }, + { + "epoch": 4.0127642600717985, + "grad_norm": 0.527934730052948, + "learning_rate": 9.464081721960592e-06, + "loss": -0.034009939432144164, + "step": 1260 + }, + { + "epoch": 4.076585560430794, + "grad_norm": 0.09058220684528351, + "learning_rate": 8.331628936475818e-06, + "loss": -0.037159329652786253, + "step": 1280 + }, + { + "epoch": 4.140406860789788, + "grad_norm": 0.05895598232746124, + "learning_rate": 7.2659843568748385e-06, + "loss": -0.0379990428686142, + "step": 1300 + }, + { + "epoch": 4.204228161148784, + "grad_norm": 0.0801444798707962, + "learning_rate": 6.268854516770008e-06, + "loss": -0.03669540882110596, + "step": 1320 + }, + { + "epoch": 4.268049461507778, + "grad_norm": 0.08857632428407669, + "learning_rate": 5.341836229602331e-06, + "loss": -0.03779337704181671, + "step": 1340 + }, + { + "epoch": 4.331870761866773, + "grad_norm": 0.07376661151647568, + "learning_rate": 4.4864140314888216e-06, + "loss": -0.03757229745388031, + "step": 1360 + }, + { + "epoch": 4.395692062225768, + "grad_norm": 0.08888167142868042, + "learning_rate": 3.703957803871932e-06, + "loss": -0.03948601186275482, + "step": 1380 + }, + { + "epoch": 4.4595133625847625, + "grad_norm": 0.12080858647823334, + "learning_rate": 2.9957205797780495e-06, + "loss": -0.039844200015068054, + "step": 1400 + }, + { + "epoch": 4.523334662943758, + "grad_norm": 0.16051147878170013, + "learning_rate": 2.362836537198199e-06, + "loss": -0.0381706565618515, + "step": 1420 + }, + { + "epoch": 4.587155963302752, + "grad_norm": 0.06491488963365555, + "learning_rate": 1.8063191828043703e-06, + "loss": -0.04070441722869873, + "step": 1440 + }, + { + "epoch": 4.650977263661747, + "grad_norm": 0.10599425435066223, + "learning_rate": 1.3270597289100437e-06, + "loss": -0.03966156244277954, + "step": 1460 + }, + { + "epoch": 4.714798564020742, + "grad_norm": 0.07826361805200577, + "learning_rate": 9.258256662741205e-07, + "loss": -0.040459868311882016, + "step": 1480 + }, + { + "epoch": 4.778619864379737, + "grad_norm": 0.1433020979166031, + "learning_rate": 6.032595350337341e-07, + "loss": -0.04145862460136414, + "step": 1500 + }, + { + "epoch": 4.842441164738732, + "grad_norm": 0.1149950921535492, + "learning_rate": 3.5987789573421356e-07, + "loss": -0.03695116639137268, + "step": 1520 + }, + { + "epoch": 4.9062624650977265, + "grad_norm": 0.15655829012393951, + "learning_rate": 1.9607050210401192e-07, + "loss": -0.03868899643421173, + "step": 1540 + }, + { + "epoch": 4.970083765456721, + "grad_norm": 0.1153496727347374, + "learning_rate": 1.1209967689925832e-07, + "loss": -0.04158148169517517, + "step": 1560 + }, + { + "epoch": 5.0, + "eval_generator_count": 1712.0, + "eval_generator_exact_match": 96.6706, + "eval_generator_rouge1": 99.9491, + "eval_generator_rouge2": 99.8942, + "eval_generator_rougeL": 99.7857, + "eval_loss": 0.00408697547391057, + "eval_runtime": 602.4809, + "eval_samples_per_second": 5.667, + "eval_selector_accuracy": 98.6565, + "eval_selector_count": 1712.0, + "eval_steps_per_second": 0.178, + "step": 1570 + } + ], + "logging_steps": 20, + "max_steps": 1570, + "num_input_tokens_seen": 0, + "num_train_epochs": 5, + "save_steps": 500, + "stateful_callbacks": { + "TrainerControl": { + "args": { + "should_epoch_stop": false, + "should_evaluate": false, + "should_log": false, + "should_save": true, + "should_training_stop": true + }, + "attributes": {} + } + }, + "total_flos": 5.871444840310374e+16, + "train_batch_size": 2, + "trial_name": null, + "trial_params": null +} diff --git a/qwen3/csd/checkpoint-1570/training_args.bin b/qwen3/csd/checkpoint-1570/training_args.bin new file mode 100644 index 0000000000000000000000000000000000000000..4b4d426a661bf64c99e9ff7730557b24ebf0e60c --- /dev/null +++ b/qwen3/csd/checkpoint-1570/training_args.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:83e0687327fbf0a1cbac0cde783b20e396ed970bb1eed13dcf33e672089c5f44 +size 7185 diff --git a/qwen3/csd/checkpoint-1570/zero_to_fp32.py b/qwen3/csd/checkpoint-1570/zero_to_fp32.py new file mode 100644 index 0000000000000000000000000000000000000000..f40f1f0acbbff30e8e8d29906b56aae4e8b8a138 --- /dev/null +++ b/qwen3/csd/checkpoint-1570/zero_to_fp32.py @@ -0,0 +1,790 @@ +#!/usr/bin/env python + +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: Apache-2.0 + +# DeepSpeed Team + +# This script extracts fp32 consolidated weights from a zero 1, 2 and 3 DeepSpeed checkpoints. It gets +# copied into the top level checkpoint dir, so the user can easily do the conversion at any point in +# the future. Once extracted, the weights don't require DeepSpeed and can be used in any +# application. +# +# example: +# python zero_to_fp32.py . output_dir/ +# or +# python zero_to_fp32.py . output_dir/ --safe_serialization + +import argparse +import torch +import glob +import math +import os +import re +import gc +import json +import numpy as np +from tqdm import tqdm +from collections import OrderedDict +from dataclasses import dataclass + +# while this script doesn't use deepspeed to recover data, since the checkpoints are pickled with +# DeepSpeed data structures it has to be available in the current python environment. +from deepspeed.utils import logger +from deepspeed.checkpoint.constants import (DS_VERSION, OPTIMIZER_STATE_DICT, SINGLE_PARTITION_OF_FP32_GROUPS, + FP32_FLAT_GROUPS, ZERO_STAGE, PARTITION_COUNT, PARAM_SHAPES, BUFFER_NAMES, + FROZEN_PARAM_SHAPES, FROZEN_PARAM_FRAGMENTS, AUTOEP_LAYERS_KEY, + AUTOEP_LAYERS_KEY_LEGACY, AUTOEP_ZERO3_EXPERT_STATE_FORMAT_KEY, + AUTOEP_ZERO3_PARTITIONED_EXPERT_STATE_FORMAT) + + +@dataclass +class zero_model_state: + buffers: dict() + param_shapes: dict() + shared_params: list + ds_version: int + frozen_param_shapes: dict() + frozen_param_fragments: dict() + + +debug = 0 + +# load to cpu +device = torch.device('cpu') + + +def atoi(text): + return int(text) if text.isdigit() else text + + +def natural_keys(text): + ''' + alist.sort(key=natural_keys) sorts in human order + http://nedbatchelder.com/blog/200712/human_sorting.html + (See Toothy's implementation in the comments) + ''' + return [atoi(c) for c in re.split(r'(\d+)', text)] + + +def get_model_state_file(checkpoint_dir, zero_stage): + if not os.path.isdir(checkpoint_dir): + raise FileNotFoundError(f"Directory '{checkpoint_dir}' doesn't exist") + + # there should be only one file + if zero_stage <= 2: + file = os.path.join(checkpoint_dir, "mp_rank_00_model_states.pt") + elif zero_stage == 3: + file = os.path.join(checkpoint_dir, "zero_pp_rank_0_mp_rank_00_model_states.pt") + + if not os.path.exists(file): + raise FileNotFoundError(f"can't find model states file at '{file}'") + + return file + + +def get_checkpoint_files(checkpoint_dir, glob_pattern): + # XXX: need to test that this simple glob rule works for multi-node setup too + ckpt_files = sorted(glob.glob(os.path.join(checkpoint_dir, glob_pattern)), key=natural_keys) + + if len(ckpt_files) == 0: + raise FileNotFoundError(f"can't find {glob_pattern} files in directory '{checkpoint_dir}'") + + return ckpt_files + + +def get_optim_files(checkpoint_dir): + return get_checkpoint_files(checkpoint_dir, "*_optim_states.pt") + + +def get_model_state_files(checkpoint_dir): + return get_checkpoint_files(checkpoint_dir, "*_model_states.pt") + + +def _has_autoep_zero3_partitioned_metadata(state_dict): + autoep_layers = state_dict.get(AUTOEP_LAYERS_KEY) + if autoep_layers is None: + autoep_layers = state_dict.get(AUTOEP_LAYERS_KEY_LEGACY) + if not isinstance(autoep_layers, list): + return False + return any( + isinstance(entry, dict) + and entry.get(AUTOEP_ZERO3_EXPERT_STATE_FORMAT_KEY) == AUTOEP_ZERO3_PARTITIONED_EXPERT_STATE_FORMAT + for entry in autoep_layers) + + +def _raise_if_autoep_zero3_partitioned_state(state_dict): + if _has_autoep_zero3_partitioned_metadata(state_dict): + raise NotImplementedError("zero_to_fp32 does not support AutoEP ZeRO-3 partition-native checkpoints. " + "AutoEP expert parameters are partitioned over expert replica groups, so " + "global data-parallel consolidation would produce incomplete expert tensors. " + "Use ds_to_universal.py for expert-aware conversion.") + + +def _raise_if_autoep_zero3_partitioned_checkpoint(model_files): + for file in model_files: + state_dict = torch.load(file, map_location=device, weights_only=False) + _raise_if_autoep_zero3_partitioned_state(state_dict) + + +def parse_model_states(files): + zero_model_states = [] + for file in files: + state_dict = torch.load(file, map_location=device, weights_only=False) + _raise_if_autoep_zero3_partitioned_state(state_dict) + + if BUFFER_NAMES not in state_dict: + raise ValueError(f"{file} is not a model state checkpoint") + buffer_names = state_dict[BUFFER_NAMES] + if debug: + print("Found buffers:", buffer_names) + + # recover just the buffers while restoring them to fp32 if they were saved in fp16 + buffers = {k: v.float() for k, v in state_dict["module"].items() if k in buffer_names} + param_shapes = state_dict[PARAM_SHAPES] + + # collect parameters that are included in param_shapes + param_names = [] + for s in param_shapes: + for name in s.keys(): + param_names.append(name) + + # update with frozen parameters + frozen_param_shapes = state_dict.get(FROZEN_PARAM_SHAPES, None) + if frozen_param_shapes is not None: + if debug: + print(f"Found frozen_param_shapes: {frozen_param_shapes}") + param_names += list(frozen_param_shapes.keys()) + + # handle shared params + shared_params = [[k, v] for k, v in state_dict["shared_params"].items()] + + ds_version = state_dict.get(DS_VERSION, None) + + frozen_param_fragments = state_dict.get(FROZEN_PARAM_FRAGMENTS, None) + + z_model_state = zero_model_state(buffers=buffers, + param_shapes=param_shapes, + shared_params=shared_params, + ds_version=ds_version, + frozen_param_shapes=frozen_param_shapes, + frozen_param_fragments=frozen_param_fragments) + zero_model_states.append(z_model_state) + + return zero_model_states + + +def parse_optim_states(files, ds_checkpoint_dir): + total_files = len(files) + state_dicts = [] + for f in tqdm(files, desc='Loading checkpoint shards'): + state_dict = torch.load(f, map_location=device, mmap=True, weights_only=False) + # immediately discard the potentially huge 2 optimizer states as we only care for fp32 master weights + # and also handle the case where it was already removed by another helper script + state_dict["optimizer_state_dict"].pop("optimizer_state_dict", None) + state_dicts.append(state_dict) + + if ZERO_STAGE not in state_dicts[0][OPTIMIZER_STATE_DICT]: + raise ValueError(f"{files[0]} is not a zero checkpoint") + zero_stage = state_dicts[0][OPTIMIZER_STATE_DICT][ZERO_STAGE] + world_size = state_dicts[0][OPTIMIZER_STATE_DICT][PARTITION_COUNT] + + # For ZeRO-2 each param group can have different partition_count as data parallelism for expert + # parameters can be different from data parallelism for non-expert parameters. So we can just + # use the max of the partition_count to get the dp world_size. + + if type(world_size) is list: + world_size = max(world_size) + + if world_size != total_files: + raise ValueError( + f"Expected {world_size} of '*_optim_states.pt' under '{ds_checkpoint_dir}' but found {total_files} files. " + "Possibly due to an overwrite of an old checkpoint, or a checkpoint didn't get saved by one or more processes." + ) + + # the groups are named differently in each stage + if zero_stage <= 2: + fp32_groups_key = SINGLE_PARTITION_OF_FP32_GROUPS + elif zero_stage == 3: + fp32_groups_key = FP32_FLAT_GROUPS + else: + raise ValueError(f"unknown zero stage {zero_stage}") + + fp32_flat_groups = [state_dicts[i][OPTIMIZER_STATE_DICT][fp32_groups_key] for i in range(len(state_dicts))] + return zero_stage, world_size, fp32_flat_groups + + +def _get_fp32_state_dict_from_zero_checkpoint(ds_checkpoint_dir, exclude_frozen_parameters): + """ + Returns fp32 state_dict reconstructed from ds checkpoint + + Args: + - ``ds_checkpoint_dir``: path to the deepspeed checkpoint folder (where the optimizer files are) + + """ + print(f"Processing zero checkpoint '{ds_checkpoint_dir}'") + + # parse_model_states rejects AutoEP ZeRO-3 partition-native checkpoints + # before the expensive optimizer-shard load below. + model_files = get_model_state_files(ds_checkpoint_dir) + zero_model_states = parse_model_states(model_files) + print(f'Parsing checkpoint created by deepspeed=={zero_model_states[0].ds_version}') + + optim_files = get_optim_files(ds_checkpoint_dir) + zero_stage, world_size, fp32_flat_groups = parse_optim_states(optim_files, ds_checkpoint_dir) + print(f"Detected checkpoint of type zero stage {zero_stage}, world_size: {world_size}") + + if zero_stage <= 2: + return _get_fp32_state_dict_from_zero2_checkpoint(world_size, fp32_flat_groups, zero_model_states, + exclude_frozen_parameters) + elif zero_stage == 3: + return _get_fp32_state_dict_from_zero3_checkpoint(world_size, fp32_flat_groups, zero_model_states, + exclude_frozen_parameters) + + +def _zero2_merge_frozen_params(state_dict, zero_model_states): + if zero_model_states[0].frozen_param_shapes is None or len(zero_model_states[0].frozen_param_shapes) == 0: + return + + frozen_param_shapes = zero_model_states[0].frozen_param_shapes + frozen_param_fragments = zero_model_states[0].frozen_param_fragments + + if debug: + num_elem = sum(s.numel() for s in frozen_param_shapes.values()) + print(f'rank 0: {FROZEN_PARAM_SHAPES}.numel = {num_elem}') + + wanted_params = len(frozen_param_shapes) + wanted_numel = sum(s.numel() for s in frozen_param_shapes.values()) + avail_numel = sum([p.numel() for p in frozen_param_fragments.values()]) + print(f'Frozen params: Have {avail_numel} numels to process.') + print(f'Frozen params: Need {wanted_numel} numels in {wanted_params} params') + + total_params = 0 + total_numel = 0 + for name, shape in frozen_param_shapes.items(): + total_params += 1 + unpartitioned_numel = shape.numel() + total_numel += unpartitioned_numel + + state_dict[name] = frozen_param_fragments[name] + + if debug: + print(f"{name} full shape: {shape} unpartitioned numel {unpartitioned_numel} ") + + print(f"Reconstructed Frozen fp32 state dict with {total_params} params {total_numel} elements") + + +def _has_callable(obj, fn): + attr = getattr(obj, fn, None) + return callable(attr) + + +def _zero2_merge_trainable_params(state_dict, world_size, fp32_flat_groups, zero_model_states): + param_shapes = zero_model_states[0].param_shapes + + # Reconstruction protocol: + # + # XXX: document this + + if debug: + for i in range(world_size): + for j in range(len(fp32_flat_groups[0])): + print(f"{FP32_FLAT_GROUPS}[{i}][{j}].shape={fp32_flat_groups[i][j].shape}") + + # XXX: memory usage doubles here (zero2) + num_param_groups = len(fp32_flat_groups[0]) + merged_single_partition_of_fp32_groups = [] + for i in range(num_param_groups): + merged_partitions = [sd[i] for sd in fp32_flat_groups] + full_single_fp32_vector = torch.cat(merged_partitions, 0) + merged_single_partition_of_fp32_groups.append(full_single_fp32_vector) + avail_numel = sum( + [full_single_fp32_vector.numel() for full_single_fp32_vector in merged_single_partition_of_fp32_groups]) + + if debug: + wanted_params = sum([len(shapes) for shapes in param_shapes]) + wanted_numel = sum([sum(shape.numel() for shape in shapes.values()) for shapes in param_shapes]) + # not asserting if there is a mismatch due to possible padding + print(f"Have {avail_numel} numels to process.") + print(f"Need {wanted_numel} numels in {wanted_params} params.") + + # params + # XXX: for huge models that can't fit into the host's RAM we will have to recode this to support + # out-of-core computing solution + total_numel = 0 + total_params = 0 + for shapes, full_single_fp32_vector in zip(param_shapes, merged_single_partition_of_fp32_groups): + offset = 0 + avail_numel = full_single_fp32_vector.numel() + for name, shape in shapes.items(): + + unpartitioned_numel = shape.numel() if _has_callable(shape, 'numel') else math.prod(shape) + total_numel += unpartitioned_numel + total_params += 1 + + if debug: + print(f"{name} full shape: {shape} unpartitioned numel {unpartitioned_numel} ") + state_dict[name] = full_single_fp32_vector.narrow(0, offset, unpartitioned_numel).view(shape) + offset += unpartitioned_numel + + # Z2 started to align to 2*world_size to improve nccl performance. Therefore both offset and + # avail_numel can differ by anywhere between 0..2*world_size. Due to two unrelated complex + # paddings performed in the code it's almost impossible to predict the exact numbers w/o the + # live optimizer object, so we are checking that the numbers are within the right range + align_to = 2 * world_size + + def zero2_align(x): + return align_to * math.ceil(x / align_to) + + if debug: + print(f"original offset={offset}, avail_numel={avail_numel}") + + offset = zero2_align(offset) + avail_numel = zero2_align(avail_numel) + + if debug: + print(f"aligned offset={offset}, avail_numel={avail_numel}") + + # Sanity check + if offset != avail_numel: + raise ValueError(f"consumed {offset} numels out of {avail_numel} - something is wrong") + + print(f"Reconstructed fp32 state dict with {total_params} params {total_numel} elements") + + +def _get_fp32_state_dict_from_zero2_checkpoint(world_size, fp32_flat_groups, zero_model_states, + exclude_frozen_parameters): + state_dict = OrderedDict() + + # buffers + buffers = zero_model_states[0].buffers + state_dict.update(buffers) + if debug: + print(f"added {len(buffers)} buffers") + + if not exclude_frozen_parameters: + _zero2_merge_frozen_params(state_dict, zero_model_states) + + _zero2_merge_trainable_params(state_dict, world_size, fp32_flat_groups, zero_model_states) + + # recover shared parameters + for pair in zero_model_states[0].shared_params: + if pair[1] in state_dict: + state_dict[pair[0]] = state_dict[pair[1]] + + return state_dict + + +def zero3_partitioned_param_info(unpartitioned_numel, world_size): + remainder = unpartitioned_numel % world_size + padding_numel = (world_size - remainder) if remainder else 0 + partitioned_numel = math.ceil(unpartitioned_numel / world_size) + return partitioned_numel, padding_numel + + +def _zero3_merge_frozen_params(state_dict, world_size, zero_model_states): + if zero_model_states[0].frozen_param_shapes is None or len(zero_model_states[0].frozen_param_shapes) == 0: + return + + if debug: + for i in range(world_size): + num_elem = sum(s.numel() for s in zero_model_states[i].frozen_param_fragments.values()) + print(f'rank {i}: {FROZEN_PARAM_SHAPES}.numel = {num_elem}') + + frozen_param_shapes = zero_model_states[0].frozen_param_shapes + wanted_params = len(frozen_param_shapes) + wanted_numel = sum(s.numel() for s in frozen_param_shapes.values()) + avail_numel = sum([p.numel() for p in zero_model_states[0].frozen_param_fragments.values()]) * world_size + print(f'Frozen params: Have {avail_numel} numels to process.') + print(f'Frozen params: Need {wanted_numel} numels in {wanted_params} params') + + total_params = 0 + total_numel = 0 + for name, shape in zero_model_states[0].frozen_param_shapes.items(): + total_params += 1 + unpartitioned_numel = shape.numel() + total_numel += unpartitioned_numel + + param_frags = tuple(model_state.frozen_param_fragments[name] for model_state in zero_model_states) + state_dict[name] = torch.cat(param_frags, 0).narrow(0, 0, unpartitioned_numel).view(shape) + + partitioned_numel, partitioned_padding_numel = zero3_partitioned_param_info(unpartitioned_numel, world_size) + + if debug: + print( + f"Frozen params: {total_params} {name} full shape: {shape} partition0 numel={partitioned_numel} partitioned_padding_numel={partitioned_padding_numel}" + ) + + print(f"Reconstructed Frozen fp32 state dict with {total_params} params {total_numel} elements") + + +class GatheredTensor: + """ + A pseudo tensor that collects partitioned weights. + It is more memory efficient when there are multiple groups. + """ + + def __init__(self, flat_groups, flat_groups_offset, offset, partitioned_numel, shape): + self.flat_groups = flat_groups + self.flat_groups_offset = flat_groups_offset + self.offset = offset + self.partitioned_numel = partitioned_numel + self.shape = shape + self.dtype = self.flat_groups[0][0].dtype + + def contiguous(self): + """ + Merge partitioned weights from flat_groups into a single tensor. + """ + end_idx = self.offset + self.partitioned_numel + world_size = len(self.flat_groups) + pad_flat_param_chunks = [] + + for rank_i in range(world_size): + # for each rank, we need to collect weights from related group/groups + flat_groups_at_rank_i = self.flat_groups[rank_i] + start_group_id = None + end_group_id = None + for group_id in range(len(self.flat_groups_offset)): + if self.flat_groups_offset[group_id] <= self.offset < self.flat_groups_offset[group_id + 1]: + start_group_id = group_id + if self.flat_groups_offset[group_id] < end_idx <= self.flat_groups_offset[group_id + 1]: + end_group_id = group_id + break + # collect weights from related group/groups + for group_id in range(start_group_id, end_group_id + 1): + flat_tensor = flat_groups_at_rank_i[group_id] + start_offset = self.offset - self.flat_groups_offset[group_id] + end_offset = min(end_idx, self.flat_groups_offset[group_id + 1]) - self.flat_groups_offset[group_id] + pad_flat_param_chunks.append(flat_tensor[start_offset:end_offset]) + + # collect weights from all ranks + pad_flat_param = torch.cat(pad_flat_param_chunks, dim=0) + param = pad_flat_param[:self.shape.numel()].view(self.shape).contiguous() + return param + + +def _zero3_merge_trainable_params(state_dict, world_size, fp32_flat_groups, zero_model_states): + param_shapes = zero_model_states[0].param_shapes + avail_numel = sum([flat_group.numel() for flat_group in fp32_flat_groups[0]]) * world_size + + # Reconstruction protocol: For zero3 we need to zip the partitions together at boundary of each + # param, re-consolidating each param, while dealing with padding if any + + # merge list of dicts, preserving order + param_shapes = {k: v for d in param_shapes for k, v in d.items()} + + if debug: + for i in range(world_size): + print(f"{FP32_FLAT_GROUPS}[{i}].shape={fp32_flat_groups[i].shape}") + + wanted_params = len(param_shapes) + wanted_numel = sum(shape.numel() for shape in param_shapes.values()) + # not asserting if there is a mismatch due to possible padding + avail_numel = fp32_flat_groups[0].numel() * world_size + print(f"Trainable params: Have {avail_numel} numels to process.") + print(f"Trainable params: Need {wanted_numel} numels in {wanted_params} params.") + + # params + # XXX: for huge models that can't fit into the host's RAM we will have to recode this to support + # out-of-core computing solution + offset = 0 + total_numel = 0 + total_params = 0 + flat_groups_offset = [0] + list(np.cumsum([flat_tensor.numel() for flat_tensor in fp32_flat_groups[0]])) + for name, shape in tqdm(param_shapes.items(), desc='Gathering sharded weights'): + unpartitioned_numel = shape.numel() + total_numel += unpartitioned_numel + total_params += 1 + partitioned_numel, partitioned_padding_numel = zero3_partitioned_param_info(unpartitioned_numel, world_size) + + if debug: + print( + f"Trainable params: {total_params} {name} full shape: {shape} partition0 numel={partitioned_numel} partitioned_padding_numel={partitioned_padding_numel}" + ) + + # memory efficient tensor + tensor = GatheredTensor(fp32_flat_groups, flat_groups_offset, offset, partitioned_numel, shape) + state_dict[name] = tensor + offset += partitioned_numel + + offset *= world_size + + # Sanity check + if offset != avail_numel: + raise ValueError(f"consumed {offset} numels out of {avail_numel} - something is wrong") + + print(f"Reconstructed Trainable fp32 state dict with {total_params} params {total_numel} elements") + + +def _get_fp32_state_dict_from_zero3_checkpoint(world_size, fp32_flat_groups, zero_model_states, + exclude_frozen_parameters): + state_dict = OrderedDict() + + # buffers + buffers = zero_model_states[0].buffers + state_dict.update(buffers) + if debug: + print(f"added {len(buffers)} buffers") + + if not exclude_frozen_parameters: + _zero3_merge_frozen_params(state_dict, world_size, zero_model_states) + + _zero3_merge_trainable_params(state_dict, world_size, fp32_flat_groups, zero_model_states) + + # recover shared parameters + for pair in zero_model_states[0].shared_params: + if pair[1] in state_dict: + state_dict[pair[0]] = state_dict[pair[1]] + + return state_dict + + +def to_torch_tensor(state_dict, return_empty_tensor=False): + """ + Convert state_dict of GatheredTensor to torch tensor + """ + torch_state_dict = {} + converted_tensors = {} + for name, tensor in state_dict.items(): + tensor_id = id(tensor) + if tensor_id in converted_tensors: # shared tensors + shared_tensor = torch_state_dict[converted_tensors[tensor_id]] + torch_state_dict[name] = shared_tensor + else: + converted_tensors[tensor_id] = name + if return_empty_tensor: + torch_state_dict[name] = torch.empty(tensor.shape, dtype=tensor.dtype) + else: + torch_state_dict[name] = tensor.contiguous() + return torch_state_dict + + +def get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir, + tag=None, + exclude_frozen_parameters=False, + lazy_mode=False): + """ + Convert ZeRO 2 or 3 checkpoint into a single fp32 consolidated state_dict that can be loaded with + ``load_state_dict()`` and used for training without DeepSpeed or shared with others, for example + via a model hub. + + Args: + - ``checkpoint_dir``: path to the desired checkpoint folder + - ``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`` + - ``exclude_frozen_parameters``: exclude frozen parameters + - ``lazy_mode``: get state_dict in lazy mode. It returns a dict of pesduo tensor instead of torch tensor, which is more memory efficient. + Convert the pesduo tensor to torch tensor by ``.contiguous()`` + + Returns: + - pytorch ``state_dict`` + + A typical usage might be :: + + from deepspeed.utils.zero_to_fp32 import get_fp32_state_dict_from_zero_checkpoint + # do the training and checkpoint saving + state_dict = get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir) # already on cpu + model = model.cpu() # move to cpu + model.load_state_dict(state_dict) + # submit to model hub or save the model to share with others + + In this example the ``model`` will no longer be usable in the deepspeed context of the same + application. i.e. you will need to re-initialize the deepspeed engine, since + ``model.load_state_dict(state_dict)`` will remove all the deepspeed magic from it. + + If you want it all done for you, use ``load_state_dict_from_zero_checkpoint`` instead. + + Note: the above usage may not work if your application doesn't have sufficient free CPU memory. + You may need to use the offline approach using the ``zero_to_fp32.py`` script that is saved with + the checkpoint. Or you can load state_dict in lazy mode :: + + from deepspeed.utils.zero_to_fp32 import get_fp32_state_dict_from_zero_checkpoint + state_dict = get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir, lazy_mode=True) # not on cpu + for name, lazy_tensor in state_dict.item(): + tensor = lazy_tensor.contiguous() # to cpu + print(name, tensor) + # del tensor to release memory if it no longer in use + """ + if tag is None: + latest_path = os.path.join(checkpoint_dir, 'latest') + if os.path.isfile(latest_path): + with open(latest_path, 'r') as fd: + tag = fd.read().strip() + else: + raise ValueError(f"Unable to find 'latest' file at {latest_path}") + + ds_checkpoint_dir = os.path.join(checkpoint_dir, tag) + + if not os.path.isdir(ds_checkpoint_dir): + raise FileNotFoundError(f"Directory '{ds_checkpoint_dir}' doesn't exist") + + state_dict = _get_fp32_state_dict_from_zero_checkpoint(ds_checkpoint_dir, exclude_frozen_parameters) + if lazy_mode: + return state_dict + else: + return to_torch_tensor(state_dict) + + +def convert_zero_checkpoint_to_fp32_state_dict(checkpoint_dir, + output_dir, + max_shard_size="5GB", + safe_serialization=False, + tag=None, + exclude_frozen_parameters=False): + """ + Convert ZeRO 2 or 3 checkpoint into a single fp32 consolidated ``state_dict`` file that can be + loaded with ``torch.load(file)`` + ``load_state_dict()`` and used for training without DeepSpeed. + + Args: + - ``checkpoint_dir``: path to the desired checkpoint folder. (one that contains the tag-folder, like ``global_step14``) + - ``output_dir``: directory to the pytorch fp32 state_dict output files + - ``max_shard_size``: the maximum size for a checkpoint before being sharded, default value is 5GB + - ``safe_serialization``: whether to save the model using `safetensors` or the traditional PyTorch way (that uses `pickle`). + - ``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`` + - ``exclude_frozen_parameters``: exclude frozen parameters + """ + + # Dependency pre-check + if safe_serialization: + try: + from safetensors.torch import save_file + except ImportError: + print('If you want to use `safe_serialization`, please `pip install safetensors`') + raise + if max_shard_size is not None: + try: + from huggingface_hub import split_torch_state_dict_into_shards + except ImportError: + print('If you want to use `max_shard_size`, please `pip install huggingface_hub`') + raise + + # Convert zero checkpoint to state_dict + state_dict = get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir, + tag, + exclude_frozen_parameters, + lazy_mode=True) + + # Shard the model if it is too big. + weights_name = "model.safetensors" if safe_serialization else "pytorch_model.bin" + if max_shard_size is not None: + filename_pattern = weights_name.replace(".bin", "{suffix}.bin").replace(".safetensors", "{suffix}.safetensors") + # an memory-efficient approach for sharding + empty_state_dict = to_torch_tensor(state_dict, return_empty_tensor=True) + state_dict_split = split_torch_state_dict_into_shards(empty_state_dict, + filename_pattern=filename_pattern, + max_shard_size=max_shard_size) + else: + from collections import namedtuple + StateDictSplit = namedtuple("StateDictSplit", ["is_sharded", "filename_to_tensors"]) + state_dict_split = StateDictSplit(is_sharded=False, + filename_to_tensors={weights_name: list(state_dict.keys())}) + + # Save the model by shard + os.makedirs(output_dir, exist_ok=True) + filename_to_tensors = state_dict_split.filename_to_tensors.items() + for shard_file, tensors in tqdm(filename_to_tensors, desc="Saving checkpoint shards"): + shard_state_dict = {tensor_name: state_dict[tensor_name] for tensor_name in tensors} + shard_state_dict = to_torch_tensor(shard_state_dict) + output_path = os.path.join(output_dir, shard_file) + if safe_serialization: + save_file(shard_state_dict, output_path, metadata={"format": "pt"}) + else: + torch.save(shard_state_dict, output_path) + # release the memory of current shard + for tensor_name in list(shard_state_dict.keys()): + del state_dict[tensor_name] + del shard_state_dict[tensor_name] + del shard_state_dict + gc.collect() + + # Save index if sharded + if state_dict_split.is_sharded: + index = { + "metadata": state_dict_split.metadata, + "weight_map": state_dict_split.tensor_to_filename, + } + save_index_file = "model.safetensors.index.json" if safe_serialization else "pytorch_model.bin.index.json" + save_index_file = os.path.join(output_dir, save_index_file) + with open(save_index_file, "w", encoding="utf-8") as f: + content = json.dumps(index, indent=2, sort_keys=True) + "\n" + f.write(content) + + +def load_state_dict_from_zero_checkpoint(model, checkpoint_dir, tag=None): + """ + 1. Put the provided model to cpu + 2. Convert ZeRO 2 or 3 checkpoint into a single fp32 consolidated ``state_dict`` + 3. Load it into the provided model + + Args: + - ``model``: the model object to update + - ``checkpoint_dir``: path to the desired checkpoint folder. (one that contains the tag-folder, like ``global_step14``) + - ``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`` + + Returns: + - ``model`: modified model + + Make sure you have plenty of CPU memory available before you call this function. If you don't + have enough use the ``zero_to_fp32.py`` utility to do the conversion. You will find it + conveniently placed for you in the checkpoint folder. + + A typical usage might be :: + + from deepspeed.utils.zero_to_fp32 import load_state_dict_from_zero_checkpoint + model = load_state_dict_from_zero_checkpoint(trainer.model, checkpoint_dir) + # submit to model hub or save the model to share with others + + Note, that once this was run, the ``model`` will no longer be usable in the deepspeed context + of the same application. i.e. you will need to re-initialize the deepspeed engine, since + ``model.load_state_dict(state_dict)`` will remove all the deepspeed magic from it. + + """ + logger.info("Extracting fp32 weights") + state_dict = get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir, tag) + + logger.info("Overwriting model with fp32 weights") + model = model.cpu() + model.load_state_dict(state_dict, strict=False) + + return model + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument("checkpoint_dir", + type=str, + help="path to the desired checkpoint folder, e.g., path/checkpoint-12") + parser.add_argument("output_dir", + type=str, + help="directory to the pytorch fp32 state_dict output files" + "(e.g. path/checkpoint-12-output/)") + parser.add_argument( + "--max_shard_size", + type=str, + default="5GB", + help="The maximum size for a checkpoint before being sharded. Checkpoints shard will then be each of size" + "lower than this size. If expressed as a string, needs to be digits followed by a unit (like `5MB`" + "We default it to 5GB in order for models to be able to run easily on free-tier google colab instances" + "without CPU OOM issues.") + parser.add_argument( + "--safe_serialization", + default=False, + action='store_true', + help="Whether to save the model using `safetensors` or the traditional PyTorch way (that uses `pickle`).") + parser.add_argument("-t", + "--tag", + type=str, + default=None, + help="checkpoint tag used as a unique identifier for checkpoint. e.g., global_step1") + parser.add_argument("--exclude_frozen_parameters", action='store_true', help="exclude frozen parameters") + parser.add_argument("-d", "--debug", action='store_true', help="enable debug") + args = parser.parse_args() + + debug = args.debug + + convert_zero_checkpoint_to_fp32_state_dict(args.checkpoint_dir, + args.output_dir, + max_shard_size=args.max_shard_size, + safe_serialization=args.safe_serialization, + tag=args.tag, + exclude_frozen_parameters=args.exclude_frozen_parameters) diff --git a/qwen3/csd/checkpoint-314/README.md b/qwen3/csd/checkpoint-314/README.md new file mode 100644 index 0000000000000000000000000000000000000000..776f98d43659dd923b8c3e5649c5ae66d1f99f3e --- /dev/null +++ b/qwen3/csd/checkpoint-314/README.md @@ -0,0 +1,208 @@ +--- +base_model: Qwen/Qwen3-0.6B +library_name: peft +pipeline_tag: text-generation +tags: +- base_model:adapter:Qwen/Qwen3-0.6B +- llama-factory +- lora +- transformers +--- + +# Model Card for Model ID + + + + + +## Model Details + +### Model Description + + + + + +- **Developed by:** [More Information Needed] +- **Funded by [optional]:** [More Information Needed] +- **Shared by [optional]:** [More Information Needed] +- **Model type:** [More Information Needed] +- **Language(s) (NLP):** [More Information Needed] +- **License:** [More Information Needed] +- **Finetuned from model [optional]:** [More Information Needed] + +### Model Sources [optional] + + + +- **Repository:** [More Information Needed] +- **Paper [optional]:** [More Information Needed] +- **Demo [optional]:** [More Information Needed] + +## Uses + + + +### Direct Use + + + +[More Information Needed] + +### Downstream Use [optional] + + + +[More Information Needed] + +### Out-of-Scope Use + + + +[More Information Needed] + +## Bias, Risks, and Limitations + + + +[More Information Needed] + +### Recommendations + + + +Users (both direct and downstream) should be made aware of the risks, biases and limitations of the model. More information needed for further recommendations. + +## How to Get Started with the Model + +Use the code below to get started with the model. + +[More Information Needed] + +## Training Details + +### Training Data + + + +[More Information Needed] + +### Training Procedure + + + +#### Preprocessing [optional] + +[More Information Needed] + + +#### Training Hyperparameters + +- **Training regime:** [More Information Needed] + +#### Speeds, Sizes, Times [optional] + + + +[More Information Needed] + +## Evaluation + + + +### Testing Data, Factors & Metrics + +#### Testing Data + + + +[More Information Needed] + +#### Factors + + + +[More Information Needed] + +#### Metrics + + + +[More Information Needed] + +### Results + +[More Information Needed] + +#### Summary + + + +## Model Examination [optional] + + + +[More Information Needed] + +## Environmental Impact + + + +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). + +- **Hardware Type:** [More Information Needed] +- **Hours used:** [More Information Needed] +- **Cloud Provider:** [More Information Needed] +- **Compute Region:** [More Information Needed] +- **Carbon Emitted:** [More Information Needed] + +## Technical Specifications [optional] + +### Model Architecture and Objective + +[More Information Needed] + +### Compute Infrastructure + +[More Information Needed] + +#### Hardware + +[More Information Needed] + +#### Software + +[More Information Needed] + +## Citation [optional] + + + +**BibTeX:** + +[More Information Needed] + +**APA:** + +[More Information Needed] + +## Glossary [optional] + + + +[More Information Needed] + +## More Information [optional] + +[More Information Needed] + +## Model Card Authors [optional] + +[More Information Needed] + +## Model Card Contact + +[More Information Needed] +### Framework versions + +- PEFT 0.18.1 \ No newline at end of file diff --git a/qwen3/csd/checkpoint-314/adapter_config.json b/qwen3/csd/checkpoint-314/adapter_config.json new file mode 100644 index 0000000000000000000000000000000000000000..9959003652c9aaae4cece005b46aaf87e6d0f224 --- /dev/null +++ b/qwen3/csd/checkpoint-314/adapter_config.json @@ -0,0 +1,46 @@ +{ + "alora_invocation_tokens": null, + "alpha_pattern": {}, + "arrow_config": null, + "auto_mapping": null, + "base_model_name_or_path": "Qwen/Qwen3-0.6B", + "bias": "none", + "corda_config": null, + "ensure_weight_tying": false, + "eva_config": null, + "exclude_modules": null, + "fan_in_fan_out": false, + "inference_mode": true, + "init_lora_weights": true, + "layer_replication": null, + "layers_pattern": null, + "layers_to_transform": null, + "loftq_config": {}, + "lora_alpha": 64, + "lora_bias": false, + "lora_dropout": 0.1, + "megatron_config": null, + "megatron_core": "megatron.core", + "modules_to_save": null, + "peft_type": "LORA", + "peft_version": "0.18.1", + "qalora_group_size": 16, + "r": 32, + "rank_pattern": {}, + "revision": null, + "target_modules": [ + "down_proj", + "up_proj", + "v_proj", + "q_proj", + "gate_proj", + "o_proj", + "k_proj" + ], + "target_parameters": null, + "task_type": "CAUSAL_LM", + "trainable_token_indices": null, + "use_dora": false, + "use_qalora": false, + "use_rslora": false +} \ No newline at end of file diff --git a/qwen3/csd/checkpoint-314/adapter_model.safetensors b/qwen3/csd/checkpoint-314/adapter_model.safetensors new file mode 100644 index 0000000000000000000000000000000000000000..9f36257165d7e784154c2d7a4d688b2ba006f2f4 --- /dev/null +++ b/qwen3/csd/checkpoint-314/adapter_model.safetensors @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ebd48a4d1bd54ec404bfba54b062fb4fa983e40c96d41af40783c5cb4aad657e +size 40422560 diff --git a/qwen3/csd/checkpoint-314/chat_template.jinja b/qwen3/csd/checkpoint-314/chat_template.jinja new file mode 100644 index 0000000000000000000000000000000000000000..01be9b307daa2d425f7c168c9fb145a286e0afb4 --- /dev/null +++ b/qwen3/csd/checkpoint-314/chat_template.jinja @@ -0,0 +1,89 @@ +{%- if tools %} + {{- '<|im_start|>system\n' }} + {%- if messages[0].role == 'system' %} + {{- messages[0].content + '\n\n' }} + {%- endif %} + {{- "# Tools\n\nYou may call one or more functions to assist with the user query.\n\nYou are provided with function signatures within XML tags:\n" }} + {%- for tool in tools %} + {{- "\n" }} + {{- tool | tojson }} + {%- endfor %} + {{- "\n\n\nFor each function call, return a json object with function name and arguments within XML tags:\n\n{\"name\": , \"arguments\": }\n<|im_end|>\n" }} +{%- else %} + {%- if messages[0].role == 'system' %} + {{- '<|im_start|>system\n' + messages[0].content + '<|im_end|>\n' }} + {%- endif %} +{%- endif %} +{%- set ns = namespace(multi_step_tool=true, last_query_index=messages|length - 1) %} +{%- for message in messages[::-1] %} + {%- set index = (messages|length - 1) - loop.index0 %} + {%- if ns.multi_step_tool and message.role == "user" and message.content is string and not(message.content.startswith('') and message.content.endswith('')) %} + {%- set ns.multi_step_tool = false %} + {%- set ns.last_query_index = index %} + {%- endif %} +{%- endfor %} +{%- for message in messages %} + {%- if message.content is string %} + {%- set content = message.content %} + {%- else %} + {%- set content = '' %} + {%- endif %} + {%- if (message.role == "user") or (message.role == "system" and not loop.first) %} + {{- '<|im_start|>' + message.role + '\n' + content + '<|im_end|>' + '\n' }} + {%- elif message.role == "assistant" %} + {%- set reasoning_content = '' %} + {%- if message.reasoning_content is string %} + {%- set reasoning_content = message.reasoning_content %} + {%- else %} + {%- if '' in content %} + {%- set reasoning_content = content.split('')[0].rstrip('\n').split('')[-1].lstrip('\n') %} + {%- set content = content.split('')[-1].lstrip('\n') %} + {%- endif %} + {%- endif %} + {%- if loop.index0 > ns.last_query_index %} + {%- if loop.last or (not loop.last and reasoning_content) %} + {{- '<|im_start|>' + message.role + '\n\n' + reasoning_content.strip('\n') + '\n\n\n' + content.lstrip('\n') }} + {%- else %} + {{- '<|im_start|>' + message.role + '\n' + content }} + {%- endif %} + {%- else %} + {{- '<|im_start|>' + message.role + '\n' + content }} + {%- endif %} + {%- if message.tool_calls %} + {%- for tool_call in message.tool_calls %} + {%- if (loop.first and content) or (not loop.first) %} + {{- '\n' }} + {%- endif %} + {%- if tool_call.function %} + {%- set tool_call = tool_call.function %} + {%- endif %} + {{- '\n{"name": "' }} + {{- tool_call.name }} + {{- '", "arguments": ' }} + {%- if tool_call.arguments is string %} + {{- tool_call.arguments }} + {%- else %} + {{- tool_call.arguments | tojson }} + {%- endif %} + {{- '}\n' }} + {%- endfor %} + {%- endif %} + {{- '<|im_end|>\n' }} + {%- elif message.role == "tool" %} + {%- if loop.first or (messages[loop.index0 - 1].role != "tool") %} + {{- '<|im_start|>user' }} + {%- endif %} + {{- '\n\n' }} + {{- content }} + {{- '\n' }} + {%- if loop.last or (messages[loop.index0 + 1].role != "tool") %} + {{- '<|im_end|>\n' }} + {%- endif %} + {%- endif %} +{%- endfor %} +{%- if add_generation_prompt %} + {{- '<|im_start|>assistant\n' }} + {%- if enable_thinking is defined and enable_thinking is false %} + {{- '\n\n\n\n' }} + {%- endif %} +{%- endif %} \ No newline at end of file diff --git a/qwen3/csd/checkpoint-314/global_step314/bf16_zero_pp_rank_0_mp_rank_00_optim_states.pt b/qwen3/csd/checkpoint-314/global_step314/bf16_zero_pp_rank_0_mp_rank_00_optim_states.pt new file mode 100644 index 0000000000000000000000000000000000000000..05cbd8920430bc10062224b8016a59aae1751a81 --- /dev/null +++ b/qwen3/csd/checkpoint-314/global_step314/bf16_zero_pp_rank_0_mp_rank_00_optim_states.pt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2ce8d1702f1514699432b046f0ef58b2f04ea1b82291ba4f0b1b546a6d1b35c3 +size 121135557 diff --git a/qwen3/csd/checkpoint-314/global_step314/bf16_zero_pp_rank_1_mp_rank_00_optim_states.pt b/qwen3/csd/checkpoint-314/global_step314/bf16_zero_pp_rank_1_mp_rank_00_optim_states.pt new file mode 100644 index 0000000000000000000000000000000000000000..78cb9c5f7bc802f3b31fffe2ad92054f9835fc71 --- /dev/null +++ b/qwen3/csd/checkpoint-314/global_step314/bf16_zero_pp_rank_1_mp_rank_00_optim_states.pt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fa07716581ebb388af7d9c9203b7394be2b7185ded218f2634e8fe00a84cd88a +size 121135749 diff --git a/qwen3/csd/checkpoint-314/global_step314/mp_rank_00_model_states.pt b/qwen3/csd/checkpoint-314/global_step314/mp_rank_00_model_states.pt new file mode 100644 index 0000000000000000000000000000000000000000..6eb375f7716d95229e922481bc9082283af06320 --- /dev/null +++ b/qwen3/csd/checkpoint-314/global_step314/mp_rank_00_model_states.pt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:59c7fa30945e5c87c2563ea4376bc682c8d6a00241fefb4e343232c29e718819 +size 351841765 diff --git a/qwen3/csd/checkpoint-314/latest b/qwen3/csd/checkpoint-314/latest new file mode 100644 index 0000000000000000000000000000000000000000..a9786513b1a514db2c3a9da7408844635663d55d --- /dev/null +++ b/qwen3/csd/checkpoint-314/latest @@ -0,0 +1 @@ +global_step314 \ No newline at end of file diff --git a/qwen3/csd/checkpoint-314/rng_state_0.pth b/qwen3/csd/checkpoint-314/rng_state_0.pth new file mode 100644 index 0000000000000000000000000000000000000000..3b6097fde6a02b320536c7bdde68856bb00040e0 --- /dev/null +++ b/qwen3/csd/checkpoint-314/rng_state_0.pth @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d03899d91988ccdf5b43b8e389e1d59f52e564bf6a9bf1856760aa48aeb981e7 +size 14917 diff --git a/qwen3/csd/checkpoint-314/rng_state_1.pth b/qwen3/csd/checkpoint-314/rng_state_1.pth new file mode 100644 index 0000000000000000000000000000000000000000..17250b5b460827c4940a09b0d33317c023323af3 --- /dev/null +++ b/qwen3/csd/checkpoint-314/rng_state_1.pth @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8934ac8fd8d0950e8dbb853693c27862f9c724e4b15f7094c963a73102efe9b1 +size 14917 diff --git a/qwen3/csd/checkpoint-314/scheduler.pt b/qwen3/csd/checkpoint-314/scheduler.pt new file mode 100644 index 0000000000000000000000000000000000000000..a3cb460802cda03bf0833a98a6f1428a3fd4f585 --- /dev/null +++ b/qwen3/csd/checkpoint-314/scheduler.pt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:17e254b5642bb75983fd5105bec79b35376cfbc99d29702287668b8767d46149 +size 1465 diff --git a/qwen3/csd/checkpoint-314/tokenizer.json b/qwen3/csd/checkpoint-314/tokenizer.json new file mode 100644 index 0000000000000000000000000000000000000000..c7afbed2efcdf019f88ab0572ec29d3bf595dfe2 --- /dev/null +++ b/qwen3/csd/checkpoint-314/tokenizer.json @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:be75606093db2094d7cd20f3c2f385c212750648bd6ea4fb2bf507a6a4c55506 +size 11422650 diff --git a/qwen3/csd/checkpoint-314/tokenizer_config.json b/qwen3/csd/checkpoint-314/tokenizer_config.json new file mode 100644 index 0000000000000000000000000000000000000000..6623da03457d79d2cd4af9557e9f31407cdb835c --- /dev/null +++ b/qwen3/csd/checkpoint-314/tokenizer_config.json @@ -0,0 +1,31 @@ +{ + "add_prefix_space": false, + "backend": "tokenizers", + "bos_token": null, + "clean_up_tokenization_spaces": false, + "eos_token": "<|im_end|>", + "errors": "replace", + "extra_special_tokens": [ + "<|im_start|>", + "<|im_end|>", + "<|object_ref_start|>", + "<|object_ref_end|>", + "<|box_start|>", + "<|box_end|>", + "<|quad_start|>", + "<|quad_end|>", + "<|vision_start|>", + "<|vision_end|>", + "<|vision_pad|>", + "<|image_pad|>", + "<|video_pad|>" + ], + "is_local": false, + "local_files_only": false, + "model_max_length": 131072, + "pad_token": "<|endoftext|>", + "padding_side": "right", + "split_special_tokens": false, + "tokenizer_class": "Qwen2Tokenizer", + "unk_token": null +} diff --git a/qwen3/csd/checkpoint-314/trainer_state.json b/qwen3/csd/checkpoint-314/trainer_state.json new file mode 100644 index 0000000000000000000000000000000000000000..8ccbed4ae3a3f19b35d60739e7985899cd7d50b1 --- /dev/null +++ b/qwen3/csd/checkpoint-314/trainer_state.json @@ -0,0 +1,154 @@ +{ + "best_global_step": null, + "best_metric": null, + "best_model_checkpoint": null, + "epoch": 1.0, + "eval_steps": 500, + "global_step": 314, + "is_hyper_param_search": false, + "is_local_process_zero": true, + "is_world_process_zero": true, + "log_history": [ + { + "epoch": 0.06382130035899482, + "grad_norm": 6.0161848068237305, + "learning_rate": 9.996390385474569e-05, + "loss": 0.11036398410797119, + "step": 20 + }, + { + "epoch": 0.12764260071798963, + "grad_norm": 4.099686622619629, + "learning_rate": 9.984797509888031e-05, + "loss": 0.01695394217967987, + "step": 40 + }, + { + "epoch": 0.19146390107698444, + "grad_norm": 3.3755345344543457, + "learning_rate": 9.965229938050925e-05, + "loss": 0.03482693731784821, + "step": 60 + }, + { + "epoch": 0.25528520143597927, + "grad_norm": 1.194334864616394, + "learning_rate": 9.937719005663432e-05, + "loss": 0.027955988049507143, + "step": 80 + }, + { + "epoch": 0.3191065017949741, + "grad_norm": 6.6159281730651855, + "learning_rate": 9.902308769000724e-05, + "loss": 0.005286623537540436, + "step": 100 + }, + { + "epoch": 0.3829278021539689, + "grad_norm": 2.851339817047119, + "learning_rate": 9.859055934360789e-05, + "loss": 0.01179061084985733, + "step": 120 + }, + { + "epoch": 0.4467491025129637, + "grad_norm": 0.989425539970398, + "learning_rate": 9.808029767254437e-05, + "loss": 0.006131124496459961, + "step": 140 + }, + { + "epoch": 0.5105704028719585, + "grad_norm": 1.3493149280548096, + "learning_rate": 9.749311981482817e-05, + "loss": 0.007052437216043472, + "step": 160 + }, + { + "epoch": 0.5743917032309533, + "grad_norm": 0.9337753057479858, + "learning_rate": 9.682996608280154e-05, + "loss": -0.002346178889274597, + "step": 180 + }, + { + "epoch": 0.6382130035899481, + "grad_norm": 1.5435981750488281, + "learning_rate": 9.609189845731207e-05, + "loss": 0.013309524953365326, + "step": 200 + }, + { + "epoch": 0.702034303948943, + "grad_norm": 0.7995954155921936, + "learning_rate": 9.52800988870462e-05, + "loss": 0.008521870523691178, + "step": 220 + }, + { + "epoch": 0.7658556043079378, + "grad_norm": 1.6571325063705444, + "learning_rate": 9.439586739574513e-05, + "loss": 0.008653326332569123, + "step": 240 + }, + { + "epoch": 0.8296769046669326, + "grad_norm": 0.519936203956604, + "learning_rate": 9.344062000033414e-05, + "loss": 0.004485934227705002, + "step": 260 + }, + { + "epoch": 0.8934982050259274, + "grad_norm": 0.31598174571990967, + "learning_rate": 9.241588644329919e-05, + "loss": 0.003059915825724602, + "step": 280 + }, + { + "epoch": 0.9573195053849222, + "grad_norm": 0.48084524273872375, + "learning_rate": 9.132330774294252e-05, + "loss": 0.005025627836585045, + "step": 300 + }, + { + "epoch": 1.0, + "eval_generator_count": 1712.0, + "eval_generator_exact_match": 86.2734, + "eval_generator_rouge1": 99.1343, + "eval_generator_rouge2": 98.8297, + "eval_generator_rougeL": 98.6074, + "eval_loss": 0.019235465675592422, + "eval_runtime": 603.0951, + "eval_samples_per_second": 5.661, + "eval_selector_accuracy": 93.3995, + "eval_selector_count": 1712.0, + "eval_steps_per_second": 0.177, + "step": 314 + } + ], + "logging_steps": 20, + "max_steps": 1570, + "num_input_tokens_seen": 0, + "num_train_epochs": 5, + "save_steps": 500, + "stateful_callbacks": { + "TrainerControl": { + "args": { + "should_epoch_stop": false, + "should_evaluate": false, + "should_log": false, + "should_save": true, + "should_training_stop": false + }, + "attributes": {} + } + }, + "total_flos": 1.172842003562496e+16, + "train_batch_size": 2, + "trial_name": null, + "trial_params": null +} diff --git a/qwen3/csd/checkpoint-314/training_args.bin b/qwen3/csd/checkpoint-314/training_args.bin new file mode 100644 index 0000000000000000000000000000000000000000..4b4d426a661bf64c99e9ff7730557b24ebf0e60c --- /dev/null +++ b/qwen3/csd/checkpoint-314/training_args.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:83e0687327fbf0a1cbac0cde783b20e396ed970bb1eed13dcf33e672089c5f44 +size 7185 diff --git a/qwen3/csd/checkpoint-314/zero_to_fp32.py b/qwen3/csd/checkpoint-314/zero_to_fp32.py new file mode 100644 index 0000000000000000000000000000000000000000..f40f1f0acbbff30e8e8d29906b56aae4e8b8a138 --- /dev/null +++ b/qwen3/csd/checkpoint-314/zero_to_fp32.py @@ -0,0 +1,790 @@ +#!/usr/bin/env python + +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: Apache-2.0 + +# DeepSpeed Team + +# This script extracts fp32 consolidated weights from a zero 1, 2 and 3 DeepSpeed checkpoints. It gets +# copied into the top level checkpoint dir, so the user can easily do the conversion at any point in +# the future. Once extracted, the weights don't require DeepSpeed and can be used in any +# application. +# +# example: +# python zero_to_fp32.py . output_dir/ +# or +# python zero_to_fp32.py . output_dir/ --safe_serialization + +import argparse +import torch +import glob +import math +import os +import re +import gc +import json +import numpy as np +from tqdm import tqdm +from collections import OrderedDict +from dataclasses import dataclass + +# while this script doesn't use deepspeed to recover data, since the checkpoints are pickled with +# DeepSpeed data structures it has to be available in the current python environment. +from deepspeed.utils import logger +from deepspeed.checkpoint.constants import (DS_VERSION, OPTIMIZER_STATE_DICT, SINGLE_PARTITION_OF_FP32_GROUPS, + FP32_FLAT_GROUPS, ZERO_STAGE, PARTITION_COUNT, PARAM_SHAPES, BUFFER_NAMES, + FROZEN_PARAM_SHAPES, FROZEN_PARAM_FRAGMENTS, AUTOEP_LAYERS_KEY, + AUTOEP_LAYERS_KEY_LEGACY, AUTOEP_ZERO3_EXPERT_STATE_FORMAT_KEY, + AUTOEP_ZERO3_PARTITIONED_EXPERT_STATE_FORMAT) + + +@dataclass +class zero_model_state: + buffers: dict() + param_shapes: dict() + shared_params: list + ds_version: int + frozen_param_shapes: dict() + frozen_param_fragments: dict() + + +debug = 0 + +# load to cpu +device = torch.device('cpu') + + +def atoi(text): + return int(text) if text.isdigit() else text + + +def natural_keys(text): + ''' + alist.sort(key=natural_keys) sorts in human order + http://nedbatchelder.com/blog/200712/human_sorting.html + (See Toothy's implementation in the comments) + ''' + return [atoi(c) for c in re.split(r'(\d+)', text)] + + +def get_model_state_file(checkpoint_dir, zero_stage): + if not os.path.isdir(checkpoint_dir): + raise FileNotFoundError(f"Directory '{checkpoint_dir}' doesn't exist") + + # there should be only one file + if zero_stage <= 2: + file = os.path.join(checkpoint_dir, "mp_rank_00_model_states.pt") + elif zero_stage == 3: + file = os.path.join(checkpoint_dir, "zero_pp_rank_0_mp_rank_00_model_states.pt") + + if not os.path.exists(file): + raise FileNotFoundError(f"can't find model states file at '{file}'") + + return file + + +def get_checkpoint_files(checkpoint_dir, glob_pattern): + # XXX: need to test that this simple glob rule works for multi-node setup too + ckpt_files = sorted(glob.glob(os.path.join(checkpoint_dir, glob_pattern)), key=natural_keys) + + if len(ckpt_files) == 0: + raise FileNotFoundError(f"can't find {glob_pattern} files in directory '{checkpoint_dir}'") + + return ckpt_files + + +def get_optim_files(checkpoint_dir): + return get_checkpoint_files(checkpoint_dir, "*_optim_states.pt") + + +def get_model_state_files(checkpoint_dir): + return get_checkpoint_files(checkpoint_dir, "*_model_states.pt") + + +def _has_autoep_zero3_partitioned_metadata(state_dict): + autoep_layers = state_dict.get(AUTOEP_LAYERS_KEY) + if autoep_layers is None: + autoep_layers = state_dict.get(AUTOEP_LAYERS_KEY_LEGACY) + if not isinstance(autoep_layers, list): + return False + return any( + isinstance(entry, dict) + and entry.get(AUTOEP_ZERO3_EXPERT_STATE_FORMAT_KEY) == AUTOEP_ZERO3_PARTITIONED_EXPERT_STATE_FORMAT + for entry in autoep_layers) + + +def _raise_if_autoep_zero3_partitioned_state(state_dict): + if _has_autoep_zero3_partitioned_metadata(state_dict): + raise NotImplementedError("zero_to_fp32 does not support AutoEP ZeRO-3 partition-native checkpoints. " + "AutoEP expert parameters are partitioned over expert replica groups, so " + "global data-parallel consolidation would produce incomplete expert tensors. " + "Use ds_to_universal.py for expert-aware conversion.") + + +def _raise_if_autoep_zero3_partitioned_checkpoint(model_files): + for file in model_files: + state_dict = torch.load(file, map_location=device, weights_only=False) + _raise_if_autoep_zero3_partitioned_state(state_dict) + + +def parse_model_states(files): + zero_model_states = [] + for file in files: + state_dict = torch.load(file, map_location=device, weights_only=False) + _raise_if_autoep_zero3_partitioned_state(state_dict) + + if BUFFER_NAMES not in state_dict: + raise ValueError(f"{file} is not a model state checkpoint") + buffer_names = state_dict[BUFFER_NAMES] + if debug: + print("Found buffers:", buffer_names) + + # recover just the buffers while restoring them to fp32 if they were saved in fp16 + buffers = {k: v.float() for k, v in state_dict["module"].items() if k in buffer_names} + param_shapes = state_dict[PARAM_SHAPES] + + # collect parameters that are included in param_shapes + param_names = [] + for s in param_shapes: + for name in s.keys(): + param_names.append(name) + + # update with frozen parameters + frozen_param_shapes = state_dict.get(FROZEN_PARAM_SHAPES, None) + if frozen_param_shapes is not None: + if debug: + print(f"Found frozen_param_shapes: {frozen_param_shapes}") + param_names += list(frozen_param_shapes.keys()) + + # handle shared params + shared_params = [[k, v] for k, v in state_dict["shared_params"].items()] + + ds_version = state_dict.get(DS_VERSION, None) + + frozen_param_fragments = state_dict.get(FROZEN_PARAM_FRAGMENTS, None) + + z_model_state = zero_model_state(buffers=buffers, + param_shapes=param_shapes, + shared_params=shared_params, + ds_version=ds_version, + frozen_param_shapes=frozen_param_shapes, + frozen_param_fragments=frozen_param_fragments) + zero_model_states.append(z_model_state) + + return zero_model_states + + +def parse_optim_states(files, ds_checkpoint_dir): + total_files = len(files) + state_dicts = [] + for f in tqdm(files, desc='Loading checkpoint shards'): + state_dict = torch.load(f, map_location=device, mmap=True, weights_only=False) + # immediately discard the potentially huge 2 optimizer states as we only care for fp32 master weights + # and also handle the case where it was already removed by another helper script + state_dict["optimizer_state_dict"].pop("optimizer_state_dict", None) + state_dicts.append(state_dict) + + if ZERO_STAGE not in state_dicts[0][OPTIMIZER_STATE_DICT]: + raise ValueError(f"{files[0]} is not a zero checkpoint") + zero_stage = state_dicts[0][OPTIMIZER_STATE_DICT][ZERO_STAGE] + world_size = state_dicts[0][OPTIMIZER_STATE_DICT][PARTITION_COUNT] + + # For ZeRO-2 each param group can have different partition_count as data parallelism for expert + # parameters can be different from data parallelism for non-expert parameters. So we can just + # use the max of the partition_count to get the dp world_size. + + if type(world_size) is list: + world_size = max(world_size) + + if world_size != total_files: + raise ValueError( + f"Expected {world_size} of '*_optim_states.pt' under '{ds_checkpoint_dir}' but found {total_files} files. " + "Possibly due to an overwrite of an old checkpoint, or a checkpoint didn't get saved by one or more processes." + ) + + # the groups are named differently in each stage + if zero_stage <= 2: + fp32_groups_key = SINGLE_PARTITION_OF_FP32_GROUPS + elif zero_stage == 3: + fp32_groups_key = FP32_FLAT_GROUPS + else: + raise ValueError(f"unknown zero stage {zero_stage}") + + fp32_flat_groups = [state_dicts[i][OPTIMIZER_STATE_DICT][fp32_groups_key] for i in range(len(state_dicts))] + return zero_stage, world_size, fp32_flat_groups + + +def _get_fp32_state_dict_from_zero_checkpoint(ds_checkpoint_dir, exclude_frozen_parameters): + """ + Returns fp32 state_dict reconstructed from ds checkpoint + + Args: + - ``ds_checkpoint_dir``: path to the deepspeed checkpoint folder (where the optimizer files are) + + """ + print(f"Processing zero checkpoint '{ds_checkpoint_dir}'") + + # parse_model_states rejects AutoEP ZeRO-3 partition-native checkpoints + # before the expensive optimizer-shard load below. + model_files = get_model_state_files(ds_checkpoint_dir) + zero_model_states = parse_model_states(model_files) + print(f'Parsing checkpoint created by deepspeed=={zero_model_states[0].ds_version}') + + optim_files = get_optim_files(ds_checkpoint_dir) + zero_stage, world_size, fp32_flat_groups = parse_optim_states(optim_files, ds_checkpoint_dir) + print(f"Detected checkpoint of type zero stage {zero_stage}, world_size: {world_size}") + + if zero_stage <= 2: + return _get_fp32_state_dict_from_zero2_checkpoint(world_size, fp32_flat_groups, zero_model_states, + exclude_frozen_parameters) + elif zero_stage == 3: + return _get_fp32_state_dict_from_zero3_checkpoint(world_size, fp32_flat_groups, zero_model_states, + exclude_frozen_parameters) + + +def _zero2_merge_frozen_params(state_dict, zero_model_states): + if zero_model_states[0].frozen_param_shapes is None or len(zero_model_states[0].frozen_param_shapes) == 0: + return + + frozen_param_shapes = zero_model_states[0].frozen_param_shapes + frozen_param_fragments = zero_model_states[0].frozen_param_fragments + + if debug: + num_elem = sum(s.numel() for s in frozen_param_shapes.values()) + print(f'rank 0: {FROZEN_PARAM_SHAPES}.numel = {num_elem}') + + wanted_params = len(frozen_param_shapes) + wanted_numel = sum(s.numel() for s in frozen_param_shapes.values()) + avail_numel = sum([p.numel() for p in frozen_param_fragments.values()]) + print(f'Frozen params: Have {avail_numel} numels to process.') + print(f'Frozen params: Need {wanted_numel} numels in {wanted_params} params') + + total_params = 0 + total_numel = 0 + for name, shape in frozen_param_shapes.items(): + total_params += 1 + unpartitioned_numel = shape.numel() + total_numel += unpartitioned_numel + + state_dict[name] = frozen_param_fragments[name] + + if debug: + print(f"{name} full shape: {shape} unpartitioned numel {unpartitioned_numel} ") + + print(f"Reconstructed Frozen fp32 state dict with {total_params} params {total_numel} elements") + + +def _has_callable(obj, fn): + attr = getattr(obj, fn, None) + return callable(attr) + + +def _zero2_merge_trainable_params(state_dict, world_size, fp32_flat_groups, zero_model_states): + param_shapes = zero_model_states[0].param_shapes + + # Reconstruction protocol: + # + # XXX: document this + + if debug: + for i in range(world_size): + for j in range(len(fp32_flat_groups[0])): + print(f"{FP32_FLAT_GROUPS}[{i}][{j}].shape={fp32_flat_groups[i][j].shape}") + + # XXX: memory usage doubles here (zero2) + num_param_groups = len(fp32_flat_groups[0]) + merged_single_partition_of_fp32_groups = [] + for i in range(num_param_groups): + merged_partitions = [sd[i] for sd in fp32_flat_groups] + full_single_fp32_vector = torch.cat(merged_partitions, 0) + merged_single_partition_of_fp32_groups.append(full_single_fp32_vector) + avail_numel = sum( + [full_single_fp32_vector.numel() for full_single_fp32_vector in merged_single_partition_of_fp32_groups]) + + if debug: + wanted_params = sum([len(shapes) for shapes in param_shapes]) + wanted_numel = sum([sum(shape.numel() for shape in shapes.values()) for shapes in param_shapes]) + # not asserting if there is a mismatch due to possible padding + print(f"Have {avail_numel} numels to process.") + print(f"Need {wanted_numel} numels in {wanted_params} params.") + + # params + # XXX: for huge models that can't fit into the host's RAM we will have to recode this to support + # out-of-core computing solution + total_numel = 0 + total_params = 0 + for shapes, full_single_fp32_vector in zip(param_shapes, merged_single_partition_of_fp32_groups): + offset = 0 + avail_numel = full_single_fp32_vector.numel() + for name, shape in shapes.items(): + + unpartitioned_numel = shape.numel() if _has_callable(shape, 'numel') else math.prod(shape) + total_numel += unpartitioned_numel + total_params += 1 + + if debug: + print(f"{name} full shape: {shape} unpartitioned numel {unpartitioned_numel} ") + state_dict[name] = full_single_fp32_vector.narrow(0, offset, unpartitioned_numel).view(shape) + offset += unpartitioned_numel + + # Z2 started to align to 2*world_size to improve nccl performance. Therefore both offset and + # avail_numel can differ by anywhere between 0..2*world_size. Due to two unrelated complex + # paddings performed in the code it's almost impossible to predict the exact numbers w/o the + # live optimizer object, so we are checking that the numbers are within the right range + align_to = 2 * world_size + + def zero2_align(x): + return align_to * math.ceil(x / align_to) + + if debug: + print(f"original offset={offset}, avail_numel={avail_numel}") + + offset = zero2_align(offset) + avail_numel = zero2_align(avail_numel) + + if debug: + print(f"aligned offset={offset}, avail_numel={avail_numel}") + + # Sanity check + if offset != avail_numel: + raise ValueError(f"consumed {offset} numels out of {avail_numel} - something is wrong") + + print(f"Reconstructed fp32 state dict with {total_params} params {total_numel} elements") + + +def _get_fp32_state_dict_from_zero2_checkpoint(world_size, fp32_flat_groups, zero_model_states, + exclude_frozen_parameters): + state_dict = OrderedDict() + + # buffers + buffers = zero_model_states[0].buffers + state_dict.update(buffers) + if debug: + print(f"added {len(buffers)} buffers") + + if not exclude_frozen_parameters: + _zero2_merge_frozen_params(state_dict, zero_model_states) + + _zero2_merge_trainable_params(state_dict, world_size, fp32_flat_groups, zero_model_states) + + # recover shared parameters + for pair in zero_model_states[0].shared_params: + if pair[1] in state_dict: + state_dict[pair[0]] = state_dict[pair[1]] + + return state_dict + + +def zero3_partitioned_param_info(unpartitioned_numel, world_size): + remainder = unpartitioned_numel % world_size + padding_numel = (world_size - remainder) if remainder else 0 + partitioned_numel = math.ceil(unpartitioned_numel / world_size) + return partitioned_numel, padding_numel + + +def _zero3_merge_frozen_params(state_dict, world_size, zero_model_states): + if zero_model_states[0].frozen_param_shapes is None or len(zero_model_states[0].frozen_param_shapes) == 0: + return + + if debug: + for i in range(world_size): + num_elem = sum(s.numel() for s in zero_model_states[i].frozen_param_fragments.values()) + print(f'rank {i}: {FROZEN_PARAM_SHAPES}.numel = {num_elem}') + + frozen_param_shapes = zero_model_states[0].frozen_param_shapes + wanted_params = len(frozen_param_shapes) + wanted_numel = sum(s.numel() for s in frozen_param_shapes.values()) + avail_numel = sum([p.numel() for p in zero_model_states[0].frozen_param_fragments.values()]) * world_size + print(f'Frozen params: Have {avail_numel} numels to process.') + print(f'Frozen params: Need {wanted_numel} numels in {wanted_params} params') + + total_params = 0 + total_numel = 0 + for name, shape in zero_model_states[0].frozen_param_shapes.items(): + total_params += 1 + unpartitioned_numel = shape.numel() + total_numel += unpartitioned_numel + + param_frags = tuple(model_state.frozen_param_fragments[name] for model_state in zero_model_states) + state_dict[name] = torch.cat(param_frags, 0).narrow(0, 0, unpartitioned_numel).view(shape) + + partitioned_numel, partitioned_padding_numel = zero3_partitioned_param_info(unpartitioned_numel, world_size) + + if debug: + print( + f"Frozen params: {total_params} {name} full shape: {shape} partition0 numel={partitioned_numel} partitioned_padding_numel={partitioned_padding_numel}" + ) + + print(f"Reconstructed Frozen fp32 state dict with {total_params} params {total_numel} elements") + + +class GatheredTensor: + """ + A pseudo tensor that collects partitioned weights. + It is more memory efficient when there are multiple groups. + """ + + def __init__(self, flat_groups, flat_groups_offset, offset, partitioned_numel, shape): + self.flat_groups = flat_groups + self.flat_groups_offset = flat_groups_offset + self.offset = offset + self.partitioned_numel = partitioned_numel + self.shape = shape + self.dtype = self.flat_groups[0][0].dtype + + def contiguous(self): + """ + Merge partitioned weights from flat_groups into a single tensor. + """ + end_idx = self.offset + self.partitioned_numel + world_size = len(self.flat_groups) + pad_flat_param_chunks = [] + + for rank_i in range(world_size): + # for each rank, we need to collect weights from related group/groups + flat_groups_at_rank_i = self.flat_groups[rank_i] + start_group_id = None + end_group_id = None + for group_id in range(len(self.flat_groups_offset)): + if self.flat_groups_offset[group_id] <= self.offset < self.flat_groups_offset[group_id + 1]: + start_group_id = group_id + if self.flat_groups_offset[group_id] < end_idx <= self.flat_groups_offset[group_id + 1]: + end_group_id = group_id + break + # collect weights from related group/groups + for group_id in range(start_group_id, end_group_id + 1): + flat_tensor = flat_groups_at_rank_i[group_id] + start_offset = self.offset - self.flat_groups_offset[group_id] + end_offset = min(end_idx, self.flat_groups_offset[group_id + 1]) - self.flat_groups_offset[group_id] + pad_flat_param_chunks.append(flat_tensor[start_offset:end_offset]) + + # collect weights from all ranks + pad_flat_param = torch.cat(pad_flat_param_chunks, dim=0) + param = pad_flat_param[:self.shape.numel()].view(self.shape).contiguous() + return param + + +def _zero3_merge_trainable_params(state_dict, world_size, fp32_flat_groups, zero_model_states): + param_shapes = zero_model_states[0].param_shapes + avail_numel = sum([flat_group.numel() for flat_group in fp32_flat_groups[0]]) * world_size + + # Reconstruction protocol: For zero3 we need to zip the partitions together at boundary of each + # param, re-consolidating each param, while dealing with padding if any + + # merge list of dicts, preserving order + param_shapes = {k: v for d in param_shapes for k, v in d.items()} + + if debug: + for i in range(world_size): + print(f"{FP32_FLAT_GROUPS}[{i}].shape={fp32_flat_groups[i].shape}") + + wanted_params = len(param_shapes) + wanted_numel = sum(shape.numel() for shape in param_shapes.values()) + # not asserting if there is a mismatch due to possible padding + avail_numel = fp32_flat_groups[0].numel() * world_size + print(f"Trainable params: Have {avail_numel} numels to process.") + print(f"Trainable params: Need {wanted_numel} numels in {wanted_params} params.") + + # params + # XXX: for huge models that can't fit into the host's RAM we will have to recode this to support + # out-of-core computing solution + offset = 0 + total_numel = 0 + total_params = 0 + flat_groups_offset = [0] + list(np.cumsum([flat_tensor.numel() for flat_tensor in fp32_flat_groups[0]])) + for name, shape in tqdm(param_shapes.items(), desc='Gathering sharded weights'): + unpartitioned_numel = shape.numel() + total_numel += unpartitioned_numel + total_params += 1 + partitioned_numel, partitioned_padding_numel = zero3_partitioned_param_info(unpartitioned_numel, world_size) + + if debug: + print( + f"Trainable params: {total_params} {name} full shape: {shape} partition0 numel={partitioned_numel} partitioned_padding_numel={partitioned_padding_numel}" + ) + + # memory efficient tensor + tensor = GatheredTensor(fp32_flat_groups, flat_groups_offset, offset, partitioned_numel, shape) + state_dict[name] = tensor + offset += partitioned_numel + + offset *= world_size + + # Sanity check + if offset != avail_numel: + raise ValueError(f"consumed {offset} numels out of {avail_numel} - something is wrong") + + print(f"Reconstructed Trainable fp32 state dict with {total_params} params {total_numel} elements") + + +def _get_fp32_state_dict_from_zero3_checkpoint(world_size, fp32_flat_groups, zero_model_states, + exclude_frozen_parameters): + state_dict = OrderedDict() + + # buffers + buffers = zero_model_states[0].buffers + state_dict.update(buffers) + if debug: + print(f"added {len(buffers)} buffers") + + if not exclude_frozen_parameters: + _zero3_merge_frozen_params(state_dict, world_size, zero_model_states) + + _zero3_merge_trainable_params(state_dict, world_size, fp32_flat_groups, zero_model_states) + + # recover shared parameters + for pair in zero_model_states[0].shared_params: + if pair[1] in state_dict: + state_dict[pair[0]] = state_dict[pair[1]] + + return state_dict + + +def to_torch_tensor(state_dict, return_empty_tensor=False): + """ + Convert state_dict of GatheredTensor to torch tensor + """ + torch_state_dict = {} + converted_tensors = {} + for name, tensor in state_dict.items(): + tensor_id = id(tensor) + if tensor_id in converted_tensors: # shared tensors + shared_tensor = torch_state_dict[converted_tensors[tensor_id]] + torch_state_dict[name] = shared_tensor + else: + converted_tensors[tensor_id] = name + if return_empty_tensor: + torch_state_dict[name] = torch.empty(tensor.shape, dtype=tensor.dtype) + else: + torch_state_dict[name] = tensor.contiguous() + return torch_state_dict + + +def get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir, + tag=None, + exclude_frozen_parameters=False, + lazy_mode=False): + """ + Convert ZeRO 2 or 3 checkpoint into a single fp32 consolidated state_dict that can be loaded with + ``load_state_dict()`` and used for training without DeepSpeed or shared with others, for example + via a model hub. + + Args: + - ``checkpoint_dir``: path to the desired checkpoint folder + - ``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`` + - ``exclude_frozen_parameters``: exclude frozen parameters + - ``lazy_mode``: get state_dict in lazy mode. It returns a dict of pesduo tensor instead of torch tensor, which is more memory efficient. + Convert the pesduo tensor to torch tensor by ``.contiguous()`` + + Returns: + - pytorch ``state_dict`` + + A typical usage might be :: + + from deepspeed.utils.zero_to_fp32 import get_fp32_state_dict_from_zero_checkpoint + # do the training and checkpoint saving + state_dict = get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir) # already on cpu + model = model.cpu() # move to cpu + model.load_state_dict(state_dict) + # submit to model hub or save the model to share with others + + In this example the ``model`` will no longer be usable in the deepspeed context of the same + application. i.e. you will need to re-initialize the deepspeed engine, since + ``model.load_state_dict(state_dict)`` will remove all the deepspeed magic from it. + + If you want it all done for you, use ``load_state_dict_from_zero_checkpoint`` instead. + + Note: the above usage may not work if your application doesn't have sufficient free CPU memory. + You may need to use the offline approach using the ``zero_to_fp32.py`` script that is saved with + the checkpoint. Or you can load state_dict in lazy mode :: + + from deepspeed.utils.zero_to_fp32 import get_fp32_state_dict_from_zero_checkpoint + state_dict = get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir, lazy_mode=True) # not on cpu + for name, lazy_tensor in state_dict.item(): + tensor = lazy_tensor.contiguous() # to cpu + print(name, tensor) + # del tensor to release memory if it no longer in use + """ + if tag is None: + latest_path = os.path.join(checkpoint_dir, 'latest') + if os.path.isfile(latest_path): + with open(latest_path, 'r') as fd: + tag = fd.read().strip() + else: + raise ValueError(f"Unable to find 'latest' file at {latest_path}") + + ds_checkpoint_dir = os.path.join(checkpoint_dir, tag) + + if not os.path.isdir(ds_checkpoint_dir): + raise FileNotFoundError(f"Directory '{ds_checkpoint_dir}' doesn't exist") + + state_dict = _get_fp32_state_dict_from_zero_checkpoint(ds_checkpoint_dir, exclude_frozen_parameters) + if lazy_mode: + return state_dict + else: + return to_torch_tensor(state_dict) + + +def convert_zero_checkpoint_to_fp32_state_dict(checkpoint_dir, + output_dir, + max_shard_size="5GB", + safe_serialization=False, + tag=None, + exclude_frozen_parameters=False): + """ + Convert ZeRO 2 or 3 checkpoint into a single fp32 consolidated ``state_dict`` file that can be + loaded with ``torch.load(file)`` + ``load_state_dict()`` and used for training without DeepSpeed. + + Args: + - ``checkpoint_dir``: path to the desired checkpoint folder. (one that contains the tag-folder, like ``global_step14``) + - ``output_dir``: directory to the pytorch fp32 state_dict output files + - ``max_shard_size``: the maximum size for a checkpoint before being sharded, default value is 5GB + - ``safe_serialization``: whether to save the model using `safetensors` or the traditional PyTorch way (that uses `pickle`). + - ``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`` + - ``exclude_frozen_parameters``: exclude frozen parameters + """ + + # Dependency pre-check + if safe_serialization: + try: + from safetensors.torch import save_file + except ImportError: + print('If you want to use `safe_serialization`, please `pip install safetensors`') + raise + if max_shard_size is not None: + try: + from huggingface_hub import split_torch_state_dict_into_shards + except ImportError: + print('If you want to use `max_shard_size`, please `pip install huggingface_hub`') + raise + + # Convert zero checkpoint to state_dict + state_dict = get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir, + tag, + exclude_frozen_parameters, + lazy_mode=True) + + # Shard the model if it is too big. + weights_name = "model.safetensors" if safe_serialization else "pytorch_model.bin" + if max_shard_size is not None: + filename_pattern = weights_name.replace(".bin", "{suffix}.bin").replace(".safetensors", "{suffix}.safetensors") + # an memory-efficient approach for sharding + empty_state_dict = to_torch_tensor(state_dict, return_empty_tensor=True) + state_dict_split = split_torch_state_dict_into_shards(empty_state_dict, + filename_pattern=filename_pattern, + max_shard_size=max_shard_size) + else: + from collections import namedtuple + StateDictSplit = namedtuple("StateDictSplit", ["is_sharded", "filename_to_tensors"]) + state_dict_split = StateDictSplit(is_sharded=False, + filename_to_tensors={weights_name: list(state_dict.keys())}) + + # Save the model by shard + os.makedirs(output_dir, exist_ok=True) + filename_to_tensors = state_dict_split.filename_to_tensors.items() + for shard_file, tensors in tqdm(filename_to_tensors, desc="Saving checkpoint shards"): + shard_state_dict = {tensor_name: state_dict[tensor_name] for tensor_name in tensors} + shard_state_dict = to_torch_tensor(shard_state_dict) + output_path = os.path.join(output_dir, shard_file) + if safe_serialization: + save_file(shard_state_dict, output_path, metadata={"format": "pt"}) + else: + torch.save(shard_state_dict, output_path) + # release the memory of current shard + for tensor_name in list(shard_state_dict.keys()): + del state_dict[tensor_name] + del shard_state_dict[tensor_name] + del shard_state_dict + gc.collect() + + # Save index if sharded + if state_dict_split.is_sharded: + index = { + "metadata": state_dict_split.metadata, + "weight_map": state_dict_split.tensor_to_filename, + } + save_index_file = "model.safetensors.index.json" if safe_serialization else "pytorch_model.bin.index.json" + save_index_file = os.path.join(output_dir, save_index_file) + with open(save_index_file, "w", encoding="utf-8") as f: + content = json.dumps(index, indent=2, sort_keys=True) + "\n" + f.write(content) + + +def load_state_dict_from_zero_checkpoint(model, checkpoint_dir, tag=None): + """ + 1. Put the provided model to cpu + 2. Convert ZeRO 2 or 3 checkpoint into a single fp32 consolidated ``state_dict`` + 3. Load it into the provided model + + Args: + - ``model``: the model object to update + - ``checkpoint_dir``: path to the desired checkpoint folder. (one that contains the tag-folder, like ``global_step14``) + - ``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`` + + Returns: + - ``model`: modified model + + Make sure you have plenty of CPU memory available before you call this function. If you don't + have enough use the ``zero_to_fp32.py`` utility to do the conversion. You will find it + conveniently placed for you in the checkpoint folder. + + A typical usage might be :: + + from deepspeed.utils.zero_to_fp32 import load_state_dict_from_zero_checkpoint + model = load_state_dict_from_zero_checkpoint(trainer.model, checkpoint_dir) + # submit to model hub or save the model to share with others + + Note, that once this was run, the ``model`` will no longer be usable in the deepspeed context + of the same application. i.e. you will need to re-initialize the deepspeed engine, since + ``model.load_state_dict(state_dict)`` will remove all the deepspeed magic from it. + + """ + logger.info("Extracting fp32 weights") + state_dict = get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir, tag) + + logger.info("Overwriting model with fp32 weights") + model = model.cpu() + model.load_state_dict(state_dict, strict=False) + + return model + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument("checkpoint_dir", + type=str, + help="path to the desired checkpoint folder, e.g., path/checkpoint-12") + parser.add_argument("output_dir", + type=str, + help="directory to the pytorch fp32 state_dict output files" + "(e.g. path/checkpoint-12-output/)") + parser.add_argument( + "--max_shard_size", + type=str, + default="5GB", + help="The maximum size for a checkpoint before being sharded. Checkpoints shard will then be each of size" + "lower than this size. If expressed as a string, needs to be digits followed by a unit (like `5MB`" + "We default it to 5GB in order for models to be able to run easily on free-tier google colab instances" + "without CPU OOM issues.") + parser.add_argument( + "--safe_serialization", + default=False, + action='store_true', + help="Whether to save the model using `safetensors` or the traditional PyTorch way (that uses `pickle`).") + parser.add_argument("-t", + "--tag", + type=str, + default=None, + help="checkpoint tag used as a unique identifier for checkpoint. e.g., global_step1") + parser.add_argument("--exclude_frozen_parameters", action='store_true', help="exclude frozen parameters") + parser.add_argument("-d", "--debug", action='store_true', help="enable debug") + args = parser.parse_args() + + debug = args.debug + + convert_zero_checkpoint_to_fp32_state_dict(args.checkpoint_dir, + args.output_dir, + max_shard_size=args.max_shard_size, + safe_serialization=args.safe_serialization, + tag=args.tag, + exclude_frozen_parameters=args.exclude_frozen_parameters) diff --git a/qwen3/csd/checkpoint-628/README.md b/qwen3/csd/checkpoint-628/README.md new file mode 100644 index 0000000000000000000000000000000000000000..776f98d43659dd923b8c3e5649c5ae66d1f99f3e --- /dev/null +++ b/qwen3/csd/checkpoint-628/README.md @@ -0,0 +1,208 @@ +--- +base_model: Qwen/Qwen3-0.6B +library_name: peft +pipeline_tag: text-generation +tags: +- base_model:adapter:Qwen/Qwen3-0.6B +- llama-factory +- lora +- transformers +--- + +# Model Card for Model ID + + + + + +## Model Details + +### Model Description + + + + + +- **Developed by:** [More Information Needed] +- **Funded by [optional]:** [More Information Needed] +- **Shared by [optional]:** [More Information Needed] +- **Model type:** [More Information Needed] +- **Language(s) (NLP):** [More Information Needed] +- **License:** [More Information Needed] +- **Finetuned from model [optional]:** [More Information Needed] + +### Model Sources [optional] + + + +- **Repository:** [More Information Needed] +- **Paper [optional]:** [More Information Needed] +- **Demo [optional]:** [More Information Needed] + +## Uses + + + +### Direct Use + + + +[More Information Needed] + +### Downstream Use [optional] + + + +[More Information Needed] + +### Out-of-Scope Use + + + +[More Information Needed] + +## Bias, Risks, and Limitations + + + +[More Information Needed] + +### Recommendations + + + +Users (both direct and downstream) should be made aware of the risks, biases and limitations of the model. More information needed for further recommendations. + +## How to Get Started with the Model + +Use the code below to get started with the model. + +[More Information Needed] + +## Training Details + +### Training Data + + + +[More Information Needed] + +### Training Procedure + + + +#### Preprocessing [optional] + +[More Information Needed] + + +#### Training Hyperparameters + +- **Training regime:** [More Information Needed] + +#### Speeds, Sizes, Times [optional] + + + +[More Information Needed] + +## Evaluation + + + +### Testing Data, Factors & Metrics + +#### Testing Data + + + +[More Information Needed] + +#### Factors + + + +[More Information Needed] + +#### Metrics + + + +[More Information Needed] + +### Results + +[More Information Needed] + +#### Summary + + + +## Model Examination [optional] + + + +[More Information Needed] + +## Environmental Impact + + + +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). + +- **Hardware Type:** [More Information Needed] +- **Hours used:** [More Information Needed] +- **Cloud Provider:** [More Information Needed] +- **Compute Region:** [More Information Needed] +- **Carbon Emitted:** [More Information Needed] + +## Technical Specifications [optional] + +### Model Architecture and Objective + +[More Information Needed] + +### Compute Infrastructure + +[More Information Needed] + +#### Hardware + +[More Information Needed] + +#### Software + +[More Information Needed] + +## Citation [optional] + + + +**BibTeX:** + +[More Information Needed] + +**APA:** + +[More Information Needed] + +## Glossary [optional] + + + +[More Information Needed] + +## More Information [optional] + +[More Information Needed] + +## Model Card Authors [optional] + +[More Information Needed] + +## Model Card Contact + +[More Information Needed] +### Framework versions + +- PEFT 0.18.1 \ No newline at end of file diff --git a/qwen3/csd/checkpoint-628/adapter_config.json b/qwen3/csd/checkpoint-628/adapter_config.json new file mode 100644 index 0000000000000000000000000000000000000000..9959003652c9aaae4cece005b46aaf87e6d0f224 --- /dev/null +++ b/qwen3/csd/checkpoint-628/adapter_config.json @@ -0,0 +1,46 @@ +{ + "alora_invocation_tokens": null, + "alpha_pattern": {}, + "arrow_config": null, + "auto_mapping": null, + "base_model_name_or_path": "Qwen/Qwen3-0.6B", + "bias": "none", + "corda_config": null, + "ensure_weight_tying": false, + "eva_config": null, + "exclude_modules": null, + "fan_in_fan_out": false, + "inference_mode": true, + "init_lora_weights": true, + "layer_replication": null, + "layers_pattern": null, + "layers_to_transform": null, + "loftq_config": {}, + "lora_alpha": 64, + "lora_bias": false, + "lora_dropout": 0.1, + "megatron_config": null, + "megatron_core": "megatron.core", + "modules_to_save": null, + "peft_type": "LORA", + "peft_version": "0.18.1", + "qalora_group_size": 16, + "r": 32, + "rank_pattern": {}, + "revision": null, + "target_modules": [ + "down_proj", + "up_proj", + "v_proj", + "q_proj", + "gate_proj", + "o_proj", + "k_proj" + ], + "target_parameters": null, + "task_type": "CAUSAL_LM", + "trainable_token_indices": null, + "use_dora": false, + "use_qalora": false, + "use_rslora": false +} \ No newline at end of file diff --git a/qwen3/csd/checkpoint-628/adapter_model.safetensors b/qwen3/csd/checkpoint-628/adapter_model.safetensors new file mode 100644 index 0000000000000000000000000000000000000000..ec3c97587cc829db63bb240f54c9a0cf52ec20c2 --- /dev/null +++ b/qwen3/csd/checkpoint-628/adapter_model.safetensors @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9609ac073c9317ba19f5183dd90b8f0715e88ecc3e43641751d94edab30627a7 +size 40422560 diff --git a/qwen3/csd/checkpoint-628/chat_template.jinja b/qwen3/csd/checkpoint-628/chat_template.jinja new file mode 100644 index 0000000000000000000000000000000000000000..01be9b307daa2d425f7c168c9fb145a286e0afb4 --- /dev/null +++ b/qwen3/csd/checkpoint-628/chat_template.jinja @@ -0,0 +1,89 @@ +{%- if tools %} + {{- '<|im_start|>system\n' }} + {%- if messages[0].role == 'system' %} + {{- messages[0].content + '\n\n' }} + {%- endif %} + {{- "# Tools\n\nYou may call one or more functions to assist with the user query.\n\nYou are provided with function signatures within XML tags:\n" }} + {%- for tool in tools %} + {{- "\n" }} + {{- tool | tojson }} + {%- endfor %} + {{- "\n\n\nFor each function call, return a json object with function name and arguments within XML tags:\n\n{\"name\": , \"arguments\": }\n<|im_end|>\n" }} +{%- else %} + {%- if messages[0].role == 'system' %} + {{- '<|im_start|>system\n' + messages[0].content + '<|im_end|>\n' }} + {%- endif %} +{%- endif %} +{%- set ns = namespace(multi_step_tool=true, last_query_index=messages|length - 1) %} +{%- for message in messages[::-1] %} + {%- set index = (messages|length - 1) - loop.index0 %} + {%- if ns.multi_step_tool and message.role == "user" and message.content is string and not(message.content.startswith('') and message.content.endswith('')) %} + {%- set ns.multi_step_tool = false %} + {%- set ns.last_query_index = index %} + {%- endif %} +{%- endfor %} +{%- for message in messages %} + {%- if message.content is string %} + {%- set content = message.content %} + {%- else %} + {%- set content = '' %} + {%- endif %} + {%- if (message.role == "user") or (message.role == "system" and not loop.first) %} + {{- '<|im_start|>' + message.role + '\n' + content + '<|im_end|>' + '\n' }} + {%- elif message.role == "assistant" %} + {%- set reasoning_content = '' %} + {%- if message.reasoning_content is string %} + {%- set reasoning_content = message.reasoning_content %} + {%- else %} + {%- if '' in content %} + {%- set reasoning_content = content.split('')[0].rstrip('\n').split('')[-1].lstrip('\n') %} + {%- set content = content.split('')[-1].lstrip('\n') %} + {%- endif %} + {%- endif %} + {%- if loop.index0 > ns.last_query_index %} + {%- if loop.last or (not loop.last and reasoning_content) %} + {{- '<|im_start|>' + message.role + '\n\n' + reasoning_content.strip('\n') + '\n\n\n' + content.lstrip('\n') }} + {%- else %} + {{- '<|im_start|>' + message.role + '\n' + content }} + {%- endif %} + {%- else %} + {{- '<|im_start|>' + message.role + '\n' + content }} + {%- endif %} + {%- if message.tool_calls %} + {%- for tool_call in message.tool_calls %} + {%- if (loop.first and content) or (not loop.first) %} + {{- '\n' }} + {%- endif %} + {%- if tool_call.function %} + {%- set tool_call = tool_call.function %} + {%- endif %} + {{- '\n{"name": "' }} + {{- tool_call.name }} + {{- '", "arguments": ' }} + {%- if tool_call.arguments is string %} + {{- tool_call.arguments }} + {%- else %} + {{- tool_call.arguments | tojson }} + {%- endif %} + {{- '}\n' }} + {%- endfor %} + {%- endif %} + {{- '<|im_end|>\n' }} + {%- elif message.role == "tool" %} + {%- if loop.first or (messages[loop.index0 - 1].role != "tool") %} + {{- '<|im_start|>user' }} + {%- endif %} + {{- '\n\n' }} + {{- content }} + {{- '\n' }} + {%- if loop.last or (messages[loop.index0 + 1].role != "tool") %} + {{- '<|im_end|>\n' }} + {%- endif %} + {%- endif %} +{%- endfor %} +{%- if add_generation_prompt %} + {{- '<|im_start|>assistant\n' }} + {%- if enable_thinking is defined and enable_thinking is false %} + {{- '\n\n\n\n' }} + {%- endif %} +{%- endif %} \ No newline at end of file diff --git a/qwen3/csd/checkpoint-628/global_step628/bf16_zero_pp_rank_0_mp_rank_00_optim_states.pt b/qwen3/csd/checkpoint-628/global_step628/bf16_zero_pp_rank_0_mp_rank_00_optim_states.pt new file mode 100644 index 0000000000000000000000000000000000000000..af65e2889606f52ccb404bc4fdcb7944d36b5e9f --- /dev/null +++ b/qwen3/csd/checkpoint-628/global_step628/bf16_zero_pp_rank_0_mp_rank_00_optim_states.pt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:08c79db1fbeb51b289aec741be1778f94f7c6acf51342178e850f20230dc8014 +size 121135557 diff --git a/qwen3/csd/checkpoint-628/global_step628/bf16_zero_pp_rank_1_mp_rank_00_optim_states.pt b/qwen3/csd/checkpoint-628/global_step628/bf16_zero_pp_rank_1_mp_rank_00_optim_states.pt new file mode 100644 index 0000000000000000000000000000000000000000..93f632bc9599d692e2b69443b86b021134493db3 --- /dev/null +++ b/qwen3/csd/checkpoint-628/global_step628/bf16_zero_pp_rank_1_mp_rank_00_optim_states.pt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7e4ad0a0f5046f675230dda0c95b0b6188dad500ad126197b27a3114fbd4ed9c +size 121135749 diff --git a/qwen3/csd/checkpoint-628/global_step628/mp_rank_00_model_states.pt b/qwen3/csd/checkpoint-628/global_step628/mp_rank_00_model_states.pt new file mode 100644 index 0000000000000000000000000000000000000000..9f6de6beaddecd21b1ec5671ce2c981729cb8527 --- /dev/null +++ b/qwen3/csd/checkpoint-628/global_step628/mp_rank_00_model_states.pt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e4fde01b7832da220a471ca8dee9501fde630f156f350360fd013c021b5a9413 +size 351841765 diff --git a/qwen3/csd/checkpoint-628/latest b/qwen3/csd/checkpoint-628/latest new file mode 100644 index 0000000000000000000000000000000000000000..af055c3db05dcb2af541005f22308dbd946aba65 --- /dev/null +++ b/qwen3/csd/checkpoint-628/latest @@ -0,0 +1 @@ +global_step628 \ No newline at end of file diff --git a/qwen3/csd/checkpoint-628/rng_state_0.pth b/qwen3/csd/checkpoint-628/rng_state_0.pth new file mode 100644 index 0000000000000000000000000000000000000000..049cafc473aaf75140ed892b0788e082252fd13b --- /dev/null +++ b/qwen3/csd/checkpoint-628/rng_state_0.pth @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4891a7ab4bb37eee26320259e8915c51843a2b2e8bdf0f9b6411c3aab0364aaf +size 14917 diff --git a/qwen3/csd/checkpoint-628/rng_state_1.pth b/qwen3/csd/checkpoint-628/rng_state_1.pth new file mode 100644 index 0000000000000000000000000000000000000000..32dc1962680376cbde07b14cc66a5c038d431239 --- /dev/null +++ b/qwen3/csd/checkpoint-628/rng_state_1.pth @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9bbf6452fd7043dc78650fd01fb93174fa7facae52d6322b9f296b20a0c8daa3 +size 14917 diff --git a/qwen3/csd/checkpoint-628/scheduler.pt b/qwen3/csd/checkpoint-628/scheduler.pt new file mode 100644 index 0000000000000000000000000000000000000000..96c0cabcd99be4945ffbd7897ecc5367ac4beb28 --- /dev/null +++ b/qwen3/csd/checkpoint-628/scheduler.pt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bb823a2c51d7fb42dfe3b693a7159784285dbf38c5a797e6e73292096123ab7a +size 1465 diff --git a/qwen3/csd/checkpoint-628/tokenizer.json b/qwen3/csd/checkpoint-628/tokenizer.json new file mode 100644 index 0000000000000000000000000000000000000000..c7afbed2efcdf019f88ab0572ec29d3bf595dfe2 --- /dev/null +++ b/qwen3/csd/checkpoint-628/tokenizer.json @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:be75606093db2094d7cd20f3c2f385c212750648bd6ea4fb2bf507a6a4c55506 +size 11422650 diff --git a/qwen3/csd/checkpoint-628/tokenizer_config.json b/qwen3/csd/checkpoint-628/tokenizer_config.json new file mode 100644 index 0000000000000000000000000000000000000000..6623da03457d79d2cd4af9557e9f31407cdb835c --- /dev/null +++ b/qwen3/csd/checkpoint-628/tokenizer_config.json @@ -0,0 +1,31 @@ +{ + "add_prefix_space": false, + "backend": "tokenizers", + "bos_token": null, + "clean_up_tokenization_spaces": false, + "eos_token": "<|im_end|>", + "errors": "replace", + "extra_special_tokens": [ + "<|im_start|>", + "<|im_end|>", + "<|object_ref_start|>", + "<|object_ref_end|>", + "<|box_start|>", + "<|box_end|>", + "<|quad_start|>", + "<|quad_end|>", + "<|vision_start|>", + "<|vision_end|>", + "<|vision_pad|>", + "<|image_pad|>", + "<|video_pad|>" + ], + "is_local": false, + "local_files_only": false, + "model_max_length": 131072, + "pad_token": "<|endoftext|>", + "padding_side": "right", + "split_special_tokens": false, + "tokenizer_class": "Qwen2Tokenizer", + "unk_token": null +} diff --git a/qwen3/csd/checkpoint-628/trainer_state.json b/qwen3/csd/checkpoint-628/trainer_state.json new file mode 100644 index 0000000000000000000000000000000000000000..44eac57dfb5a590e892fdcc04b48c04ccaf36616 --- /dev/null +++ b/qwen3/csd/checkpoint-628/trainer_state.json @@ -0,0 +1,281 @@ +{ + "best_global_step": null, + "best_metric": null, + "best_model_checkpoint": null, + "epoch": 2.0, + "eval_steps": 500, + "global_step": 628, + "is_hyper_param_search": false, + "is_local_process_zero": true, + "is_world_process_zero": true, + "log_history": [ + { + "epoch": 0.06382130035899482, + "grad_norm": 6.0161848068237305, + "learning_rate": 9.996390385474569e-05, + "loss": 0.11036398410797119, + "step": 20 + }, + { + "epoch": 0.12764260071798963, + "grad_norm": 4.099686622619629, + "learning_rate": 9.984797509888031e-05, + "loss": 0.01695394217967987, + "step": 40 + }, + { + "epoch": 0.19146390107698444, + "grad_norm": 3.3755345344543457, + "learning_rate": 9.965229938050925e-05, + "loss": 0.03482693731784821, + "step": 60 + }, + { + "epoch": 0.25528520143597927, + "grad_norm": 1.194334864616394, + "learning_rate": 9.937719005663432e-05, + "loss": 0.027955988049507143, + "step": 80 + }, + { + "epoch": 0.3191065017949741, + "grad_norm": 6.6159281730651855, + "learning_rate": 9.902308769000724e-05, + "loss": 0.005286623537540436, + "step": 100 + }, + { + "epoch": 0.3829278021539689, + "grad_norm": 2.851339817047119, + "learning_rate": 9.859055934360789e-05, + "loss": 0.01179061084985733, + "step": 120 + }, + { + "epoch": 0.4467491025129637, + "grad_norm": 0.989425539970398, + "learning_rate": 9.808029767254437e-05, + "loss": 0.006131124496459961, + "step": 140 + }, + { + "epoch": 0.5105704028719585, + "grad_norm": 1.3493149280548096, + "learning_rate": 9.749311981482817e-05, + "loss": 0.007052437216043472, + "step": 160 + }, + { + "epoch": 0.5743917032309533, + "grad_norm": 0.9337753057479858, + "learning_rate": 9.682996608280154e-05, + "loss": -0.002346178889274597, + "step": 180 + }, + { + "epoch": 0.6382130035899481, + "grad_norm": 1.5435981750488281, + "learning_rate": 9.609189845731207e-05, + "loss": 0.013309524953365326, + "step": 200 + }, + { + "epoch": 0.702034303948943, + "grad_norm": 0.7995954155921936, + "learning_rate": 9.52800988870462e-05, + "loss": 0.008521870523691178, + "step": 220 + }, + { + "epoch": 0.7658556043079378, + "grad_norm": 1.6571325063705444, + "learning_rate": 9.439586739574513e-05, + "loss": 0.008653326332569123, + "step": 240 + }, + { + "epoch": 0.8296769046669326, + "grad_norm": 0.519936203956604, + "learning_rate": 9.344062000033414e-05, + "loss": 0.004485934227705002, + "step": 260 + }, + { + "epoch": 0.8934982050259274, + "grad_norm": 0.31598174571990967, + "learning_rate": 9.241588644329919e-05, + "loss": 0.003059915825724602, + "step": 280 + }, + { + "epoch": 0.9573195053849222, + "grad_norm": 0.48084524273872375, + "learning_rate": 9.132330774294252e-05, + "loss": 0.005025627836585045, + "step": 300 + }, + { + "epoch": 1.0, + "eval_generator_count": 1712.0, + "eval_generator_exact_match": 86.2734, + "eval_generator_rouge1": 99.1343, + "eval_generator_rouge2": 98.8297, + "eval_generator_rougeL": 98.6074, + "eval_loss": 0.019235465675592422, + "eval_runtime": 603.0951, + "eval_samples_per_second": 5.661, + "eval_selector_accuracy": 93.3995, + "eval_selector_count": 1712.0, + "eval_steps_per_second": 0.177, + "step": 314 + }, + { + "epoch": 1.0191463901076985, + "grad_norm": 0.34810933470726013, + "learning_rate": 9.01646335654399e-05, + "loss": 0.008805014193058014, + "step": 320 + }, + { + "epoch": 1.0829676904666932, + "grad_norm": 0.19888198375701904, + "learning_rate": 8.894171942290817e-05, + "loss": 0.0013909661211073399, + "step": 340 + }, + { + "epoch": 1.146788990825688, + "grad_norm": 1.0506941080093384, + "learning_rate": 8.765652370197003e-05, + "loss": 0.0005901294760406017, + "step": 360 + }, + { + "epoch": 1.210610291184683, + "grad_norm": 2.363455057144165, + "learning_rate": 8.631110452757467e-05, + "loss": -0.0003092627972364426, + "step": 380 + }, + { + "epoch": 1.2744315915436777, + "grad_norm": 0.0766368880867958, + "learning_rate": 8.490761646709642e-05, + "loss": -0.002663038857281208, + "step": 400 + }, + { + "epoch": 1.3382528919026724, + "grad_norm": 0.1551397442817688, + "learning_rate": 8.344830707998953e-05, + "loss": 0.0026730677112936974, + "step": 420 + }, + { + "epoch": 1.4020741922616673, + "grad_norm": 0.7773767113685608, + "learning_rate": 8.193551331852458e-05, + "loss": -0.0011709232814610005, + "step": 440 + }, + { + "epoch": 1.4658954926206622, + "grad_norm": 0.42017874121665955, + "learning_rate": 8.037165778537033e-05, + "loss": -0.0019059792160987855, + "step": 460 + }, + { + "epoch": 1.5297167929796571, + "grad_norm": 1.0544211864471436, + "learning_rate": 7.875924485401427e-05, + "loss": -0.004772515594959259, + "step": 480 + }, + { + "epoch": 1.5935380933386518, + "grad_norm": 0.4706478416919708, + "learning_rate": 7.710085665823444e-05, + "loss": -0.0002438830444589257, + "step": 500 + }, + { + "epoch": 1.6573593936976465, + "grad_norm": 0.22088219225406647, + "learning_rate": 7.539914895704521e-05, + "loss": -0.004391691088676453, + "step": 520 + }, + { + "epoch": 1.7211806940566414, + "grad_norm": 0.5972660183906555, + "learning_rate": 7.365684688173908e-05, + "loss": -0.007541544735431671, + "step": 540 + }, + { + "epoch": 1.7850019944156363, + "grad_norm": 0.19400978088378906, + "learning_rate": 7.18767405718347e-05, + "loss": -0.004146666824817657, + "step": 560 + }, + { + "epoch": 1.848823294774631, + "grad_norm": 1.2469046115875244, + "learning_rate": 7.006168070692036e-05, + "loss": -0.0019529350101947784, + "step": 580 + }, + { + "epoch": 1.9126445951336257, + "grad_norm": 0.14316241443157196, + "learning_rate": 6.821457394154786e-05, + "loss": -0.008291246742010117, + "step": 600 + }, + { + "epoch": 1.9764658954926206, + "grad_norm": 0.4657886326313019, + "learning_rate": 6.633837825048768e-05, + "loss": -0.006107022240757942, + "step": 620 + }, + { + "epoch": 2.0, + "eval_generator_count": 1712.0, + "eval_generator_exact_match": 94.6846, + "eval_generator_rouge1": 99.7652, + "eval_generator_rouge2": 99.667, + "eval_generator_rougeL": 99.5471, + "eval_loss": 0.006834100466221571, + "eval_runtime": 601.0294, + "eval_samples_per_second": 5.68, + "eval_selector_accuracy": 97.8388, + "eval_selector_count": 1712.0, + "eval_steps_per_second": 0.178, + "step": 628 + } + ], + "logging_steps": 20, + "max_steps": 1570, + "num_input_tokens_seen": 0, + "num_train_epochs": 5, + "save_steps": 500, + "stateful_callbacks": { + "TrainerControl": { + "args": { + "should_epoch_stop": false, + "should_evaluate": false, + "should_log": false, + "should_save": true, + "should_training_stop": false + }, + "attributes": {} + } + }, + "total_flos": 2.346351770520781e+16, + "train_batch_size": 2, + "trial_name": null, + "trial_params": null +} diff --git a/qwen3/csd/checkpoint-628/training_args.bin b/qwen3/csd/checkpoint-628/training_args.bin new file mode 100644 index 0000000000000000000000000000000000000000..4b4d426a661bf64c99e9ff7730557b24ebf0e60c --- /dev/null +++ b/qwen3/csd/checkpoint-628/training_args.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:83e0687327fbf0a1cbac0cde783b20e396ed970bb1eed13dcf33e672089c5f44 +size 7185 diff --git a/qwen3/csd/checkpoint-628/zero_to_fp32.py b/qwen3/csd/checkpoint-628/zero_to_fp32.py new file mode 100644 index 0000000000000000000000000000000000000000..f40f1f0acbbff30e8e8d29906b56aae4e8b8a138 --- /dev/null +++ b/qwen3/csd/checkpoint-628/zero_to_fp32.py @@ -0,0 +1,790 @@ +#!/usr/bin/env python + +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: Apache-2.0 + +# DeepSpeed Team + +# This script extracts fp32 consolidated weights from a zero 1, 2 and 3 DeepSpeed checkpoints. It gets +# copied into the top level checkpoint dir, so the user can easily do the conversion at any point in +# the future. Once extracted, the weights don't require DeepSpeed and can be used in any +# application. +# +# example: +# python zero_to_fp32.py . output_dir/ +# or +# python zero_to_fp32.py . output_dir/ --safe_serialization + +import argparse +import torch +import glob +import math +import os +import re +import gc +import json +import numpy as np +from tqdm import tqdm +from collections import OrderedDict +from dataclasses import dataclass + +# while this script doesn't use deepspeed to recover data, since the checkpoints are pickled with +# DeepSpeed data structures it has to be available in the current python environment. +from deepspeed.utils import logger +from deepspeed.checkpoint.constants import (DS_VERSION, OPTIMIZER_STATE_DICT, SINGLE_PARTITION_OF_FP32_GROUPS, + FP32_FLAT_GROUPS, ZERO_STAGE, PARTITION_COUNT, PARAM_SHAPES, BUFFER_NAMES, + FROZEN_PARAM_SHAPES, FROZEN_PARAM_FRAGMENTS, AUTOEP_LAYERS_KEY, + AUTOEP_LAYERS_KEY_LEGACY, AUTOEP_ZERO3_EXPERT_STATE_FORMAT_KEY, + AUTOEP_ZERO3_PARTITIONED_EXPERT_STATE_FORMAT) + + +@dataclass +class zero_model_state: + buffers: dict() + param_shapes: dict() + shared_params: list + ds_version: int + frozen_param_shapes: dict() + frozen_param_fragments: dict() + + +debug = 0 + +# load to cpu +device = torch.device('cpu') + + +def atoi(text): + return int(text) if text.isdigit() else text + + +def natural_keys(text): + ''' + alist.sort(key=natural_keys) sorts in human order + http://nedbatchelder.com/blog/200712/human_sorting.html + (See Toothy's implementation in the comments) + ''' + return [atoi(c) for c in re.split(r'(\d+)', text)] + + +def get_model_state_file(checkpoint_dir, zero_stage): + if not os.path.isdir(checkpoint_dir): + raise FileNotFoundError(f"Directory '{checkpoint_dir}' doesn't exist") + + # there should be only one file + if zero_stage <= 2: + file = os.path.join(checkpoint_dir, "mp_rank_00_model_states.pt") + elif zero_stage == 3: + file = os.path.join(checkpoint_dir, "zero_pp_rank_0_mp_rank_00_model_states.pt") + + if not os.path.exists(file): + raise FileNotFoundError(f"can't find model states file at '{file}'") + + return file + + +def get_checkpoint_files(checkpoint_dir, glob_pattern): + # XXX: need to test that this simple glob rule works for multi-node setup too + ckpt_files = sorted(glob.glob(os.path.join(checkpoint_dir, glob_pattern)), key=natural_keys) + + if len(ckpt_files) == 0: + raise FileNotFoundError(f"can't find {glob_pattern} files in directory '{checkpoint_dir}'") + + return ckpt_files + + +def get_optim_files(checkpoint_dir): + return get_checkpoint_files(checkpoint_dir, "*_optim_states.pt") + + +def get_model_state_files(checkpoint_dir): + return get_checkpoint_files(checkpoint_dir, "*_model_states.pt") + + +def _has_autoep_zero3_partitioned_metadata(state_dict): + autoep_layers = state_dict.get(AUTOEP_LAYERS_KEY) + if autoep_layers is None: + autoep_layers = state_dict.get(AUTOEP_LAYERS_KEY_LEGACY) + if not isinstance(autoep_layers, list): + return False + return any( + isinstance(entry, dict) + and entry.get(AUTOEP_ZERO3_EXPERT_STATE_FORMAT_KEY) == AUTOEP_ZERO3_PARTITIONED_EXPERT_STATE_FORMAT + for entry in autoep_layers) + + +def _raise_if_autoep_zero3_partitioned_state(state_dict): + if _has_autoep_zero3_partitioned_metadata(state_dict): + raise NotImplementedError("zero_to_fp32 does not support AutoEP ZeRO-3 partition-native checkpoints. " + "AutoEP expert parameters are partitioned over expert replica groups, so " + "global data-parallel consolidation would produce incomplete expert tensors. " + "Use ds_to_universal.py for expert-aware conversion.") + + +def _raise_if_autoep_zero3_partitioned_checkpoint(model_files): + for file in model_files: + state_dict = torch.load(file, map_location=device, weights_only=False) + _raise_if_autoep_zero3_partitioned_state(state_dict) + + +def parse_model_states(files): + zero_model_states = [] + for file in files: + state_dict = torch.load(file, map_location=device, weights_only=False) + _raise_if_autoep_zero3_partitioned_state(state_dict) + + if BUFFER_NAMES not in state_dict: + raise ValueError(f"{file} is not a model state checkpoint") + buffer_names = state_dict[BUFFER_NAMES] + if debug: + print("Found buffers:", buffer_names) + + # recover just the buffers while restoring them to fp32 if they were saved in fp16 + buffers = {k: v.float() for k, v in state_dict["module"].items() if k in buffer_names} + param_shapes = state_dict[PARAM_SHAPES] + + # collect parameters that are included in param_shapes + param_names = [] + for s in param_shapes: + for name in s.keys(): + param_names.append(name) + + # update with frozen parameters + frozen_param_shapes = state_dict.get(FROZEN_PARAM_SHAPES, None) + if frozen_param_shapes is not None: + if debug: + print(f"Found frozen_param_shapes: {frozen_param_shapes}") + param_names += list(frozen_param_shapes.keys()) + + # handle shared params + shared_params = [[k, v] for k, v in state_dict["shared_params"].items()] + + ds_version = state_dict.get(DS_VERSION, None) + + frozen_param_fragments = state_dict.get(FROZEN_PARAM_FRAGMENTS, None) + + z_model_state = zero_model_state(buffers=buffers, + param_shapes=param_shapes, + shared_params=shared_params, + ds_version=ds_version, + frozen_param_shapes=frozen_param_shapes, + frozen_param_fragments=frozen_param_fragments) + zero_model_states.append(z_model_state) + + return zero_model_states + + +def parse_optim_states(files, ds_checkpoint_dir): + total_files = len(files) + state_dicts = [] + for f in tqdm(files, desc='Loading checkpoint shards'): + state_dict = torch.load(f, map_location=device, mmap=True, weights_only=False) + # immediately discard the potentially huge 2 optimizer states as we only care for fp32 master weights + # and also handle the case where it was already removed by another helper script + state_dict["optimizer_state_dict"].pop("optimizer_state_dict", None) + state_dicts.append(state_dict) + + if ZERO_STAGE not in state_dicts[0][OPTIMIZER_STATE_DICT]: + raise ValueError(f"{files[0]} is not a zero checkpoint") + zero_stage = state_dicts[0][OPTIMIZER_STATE_DICT][ZERO_STAGE] + world_size = state_dicts[0][OPTIMIZER_STATE_DICT][PARTITION_COUNT] + + # For ZeRO-2 each param group can have different partition_count as data parallelism for expert + # parameters can be different from data parallelism for non-expert parameters. So we can just + # use the max of the partition_count to get the dp world_size. + + if type(world_size) is list: + world_size = max(world_size) + + if world_size != total_files: + raise ValueError( + f"Expected {world_size} of '*_optim_states.pt' under '{ds_checkpoint_dir}' but found {total_files} files. " + "Possibly due to an overwrite of an old checkpoint, or a checkpoint didn't get saved by one or more processes." + ) + + # the groups are named differently in each stage + if zero_stage <= 2: + fp32_groups_key = SINGLE_PARTITION_OF_FP32_GROUPS + elif zero_stage == 3: + fp32_groups_key = FP32_FLAT_GROUPS + else: + raise ValueError(f"unknown zero stage {zero_stage}") + + fp32_flat_groups = [state_dicts[i][OPTIMIZER_STATE_DICT][fp32_groups_key] for i in range(len(state_dicts))] + return zero_stage, world_size, fp32_flat_groups + + +def _get_fp32_state_dict_from_zero_checkpoint(ds_checkpoint_dir, exclude_frozen_parameters): + """ + Returns fp32 state_dict reconstructed from ds checkpoint + + Args: + - ``ds_checkpoint_dir``: path to the deepspeed checkpoint folder (where the optimizer files are) + + """ + print(f"Processing zero checkpoint '{ds_checkpoint_dir}'") + + # parse_model_states rejects AutoEP ZeRO-3 partition-native checkpoints + # before the expensive optimizer-shard load below. + model_files = get_model_state_files(ds_checkpoint_dir) + zero_model_states = parse_model_states(model_files) + print(f'Parsing checkpoint created by deepspeed=={zero_model_states[0].ds_version}') + + optim_files = get_optim_files(ds_checkpoint_dir) + zero_stage, world_size, fp32_flat_groups = parse_optim_states(optim_files, ds_checkpoint_dir) + print(f"Detected checkpoint of type zero stage {zero_stage}, world_size: {world_size}") + + if zero_stage <= 2: + return _get_fp32_state_dict_from_zero2_checkpoint(world_size, fp32_flat_groups, zero_model_states, + exclude_frozen_parameters) + elif zero_stage == 3: + return _get_fp32_state_dict_from_zero3_checkpoint(world_size, fp32_flat_groups, zero_model_states, + exclude_frozen_parameters) + + +def _zero2_merge_frozen_params(state_dict, zero_model_states): + if zero_model_states[0].frozen_param_shapes is None or len(zero_model_states[0].frozen_param_shapes) == 0: + return + + frozen_param_shapes = zero_model_states[0].frozen_param_shapes + frozen_param_fragments = zero_model_states[0].frozen_param_fragments + + if debug: + num_elem = sum(s.numel() for s in frozen_param_shapes.values()) + print(f'rank 0: {FROZEN_PARAM_SHAPES}.numel = {num_elem}') + + wanted_params = len(frozen_param_shapes) + wanted_numel = sum(s.numel() for s in frozen_param_shapes.values()) + avail_numel = sum([p.numel() for p in frozen_param_fragments.values()]) + print(f'Frozen params: Have {avail_numel} numels to process.') + print(f'Frozen params: Need {wanted_numel} numels in {wanted_params} params') + + total_params = 0 + total_numel = 0 + for name, shape in frozen_param_shapes.items(): + total_params += 1 + unpartitioned_numel = shape.numel() + total_numel += unpartitioned_numel + + state_dict[name] = frozen_param_fragments[name] + + if debug: + print(f"{name} full shape: {shape} unpartitioned numel {unpartitioned_numel} ") + + print(f"Reconstructed Frozen fp32 state dict with {total_params} params {total_numel} elements") + + +def _has_callable(obj, fn): + attr = getattr(obj, fn, None) + return callable(attr) + + +def _zero2_merge_trainable_params(state_dict, world_size, fp32_flat_groups, zero_model_states): + param_shapes = zero_model_states[0].param_shapes + + # Reconstruction protocol: + # + # XXX: document this + + if debug: + for i in range(world_size): + for j in range(len(fp32_flat_groups[0])): + print(f"{FP32_FLAT_GROUPS}[{i}][{j}].shape={fp32_flat_groups[i][j].shape}") + + # XXX: memory usage doubles here (zero2) + num_param_groups = len(fp32_flat_groups[0]) + merged_single_partition_of_fp32_groups = [] + for i in range(num_param_groups): + merged_partitions = [sd[i] for sd in fp32_flat_groups] + full_single_fp32_vector = torch.cat(merged_partitions, 0) + merged_single_partition_of_fp32_groups.append(full_single_fp32_vector) + avail_numel = sum( + [full_single_fp32_vector.numel() for full_single_fp32_vector in merged_single_partition_of_fp32_groups]) + + if debug: + wanted_params = sum([len(shapes) for shapes in param_shapes]) + wanted_numel = sum([sum(shape.numel() for shape in shapes.values()) for shapes in param_shapes]) + # not asserting if there is a mismatch due to possible padding + print(f"Have {avail_numel} numels to process.") + print(f"Need {wanted_numel} numels in {wanted_params} params.") + + # params + # XXX: for huge models that can't fit into the host's RAM we will have to recode this to support + # out-of-core computing solution + total_numel = 0 + total_params = 0 + for shapes, full_single_fp32_vector in zip(param_shapes, merged_single_partition_of_fp32_groups): + offset = 0 + avail_numel = full_single_fp32_vector.numel() + for name, shape in shapes.items(): + + unpartitioned_numel = shape.numel() if _has_callable(shape, 'numel') else math.prod(shape) + total_numel += unpartitioned_numel + total_params += 1 + + if debug: + print(f"{name} full shape: {shape} unpartitioned numel {unpartitioned_numel} ") + state_dict[name] = full_single_fp32_vector.narrow(0, offset, unpartitioned_numel).view(shape) + offset += unpartitioned_numel + + # Z2 started to align to 2*world_size to improve nccl performance. Therefore both offset and + # avail_numel can differ by anywhere between 0..2*world_size. Due to two unrelated complex + # paddings performed in the code it's almost impossible to predict the exact numbers w/o the + # live optimizer object, so we are checking that the numbers are within the right range + align_to = 2 * world_size + + def zero2_align(x): + return align_to * math.ceil(x / align_to) + + if debug: + print(f"original offset={offset}, avail_numel={avail_numel}") + + offset = zero2_align(offset) + avail_numel = zero2_align(avail_numel) + + if debug: + print(f"aligned offset={offset}, avail_numel={avail_numel}") + + # Sanity check + if offset != avail_numel: + raise ValueError(f"consumed {offset} numels out of {avail_numel} - something is wrong") + + print(f"Reconstructed fp32 state dict with {total_params} params {total_numel} elements") + + +def _get_fp32_state_dict_from_zero2_checkpoint(world_size, fp32_flat_groups, zero_model_states, + exclude_frozen_parameters): + state_dict = OrderedDict() + + # buffers + buffers = zero_model_states[0].buffers + state_dict.update(buffers) + if debug: + print(f"added {len(buffers)} buffers") + + if not exclude_frozen_parameters: + _zero2_merge_frozen_params(state_dict, zero_model_states) + + _zero2_merge_trainable_params(state_dict, world_size, fp32_flat_groups, zero_model_states) + + # recover shared parameters + for pair in zero_model_states[0].shared_params: + if pair[1] in state_dict: + state_dict[pair[0]] = state_dict[pair[1]] + + return state_dict + + +def zero3_partitioned_param_info(unpartitioned_numel, world_size): + remainder = unpartitioned_numel % world_size + padding_numel = (world_size - remainder) if remainder else 0 + partitioned_numel = math.ceil(unpartitioned_numel / world_size) + return partitioned_numel, padding_numel + + +def _zero3_merge_frozen_params(state_dict, world_size, zero_model_states): + if zero_model_states[0].frozen_param_shapes is None or len(zero_model_states[0].frozen_param_shapes) == 0: + return + + if debug: + for i in range(world_size): + num_elem = sum(s.numel() for s in zero_model_states[i].frozen_param_fragments.values()) + print(f'rank {i}: {FROZEN_PARAM_SHAPES}.numel = {num_elem}') + + frozen_param_shapes = zero_model_states[0].frozen_param_shapes + wanted_params = len(frozen_param_shapes) + wanted_numel = sum(s.numel() for s in frozen_param_shapes.values()) + avail_numel = sum([p.numel() for p in zero_model_states[0].frozen_param_fragments.values()]) * world_size + print(f'Frozen params: Have {avail_numel} numels to process.') + print(f'Frozen params: Need {wanted_numel} numels in {wanted_params} params') + + total_params = 0 + total_numel = 0 + for name, shape in zero_model_states[0].frozen_param_shapes.items(): + total_params += 1 + unpartitioned_numel = shape.numel() + total_numel += unpartitioned_numel + + param_frags = tuple(model_state.frozen_param_fragments[name] for model_state in zero_model_states) + state_dict[name] = torch.cat(param_frags, 0).narrow(0, 0, unpartitioned_numel).view(shape) + + partitioned_numel, partitioned_padding_numel = zero3_partitioned_param_info(unpartitioned_numel, world_size) + + if debug: + print( + f"Frozen params: {total_params} {name} full shape: {shape} partition0 numel={partitioned_numel} partitioned_padding_numel={partitioned_padding_numel}" + ) + + print(f"Reconstructed Frozen fp32 state dict with {total_params} params {total_numel} elements") + + +class GatheredTensor: + """ + A pseudo tensor that collects partitioned weights. + It is more memory efficient when there are multiple groups. + """ + + def __init__(self, flat_groups, flat_groups_offset, offset, partitioned_numel, shape): + self.flat_groups = flat_groups + self.flat_groups_offset = flat_groups_offset + self.offset = offset + self.partitioned_numel = partitioned_numel + self.shape = shape + self.dtype = self.flat_groups[0][0].dtype + + def contiguous(self): + """ + Merge partitioned weights from flat_groups into a single tensor. + """ + end_idx = self.offset + self.partitioned_numel + world_size = len(self.flat_groups) + pad_flat_param_chunks = [] + + for rank_i in range(world_size): + # for each rank, we need to collect weights from related group/groups + flat_groups_at_rank_i = self.flat_groups[rank_i] + start_group_id = None + end_group_id = None + for group_id in range(len(self.flat_groups_offset)): + if self.flat_groups_offset[group_id] <= self.offset < self.flat_groups_offset[group_id + 1]: + start_group_id = group_id + if self.flat_groups_offset[group_id] < end_idx <= self.flat_groups_offset[group_id + 1]: + end_group_id = group_id + break + # collect weights from related group/groups + for group_id in range(start_group_id, end_group_id + 1): + flat_tensor = flat_groups_at_rank_i[group_id] + start_offset = self.offset - self.flat_groups_offset[group_id] + end_offset = min(end_idx, self.flat_groups_offset[group_id + 1]) - self.flat_groups_offset[group_id] + pad_flat_param_chunks.append(flat_tensor[start_offset:end_offset]) + + # collect weights from all ranks + pad_flat_param = torch.cat(pad_flat_param_chunks, dim=0) + param = pad_flat_param[:self.shape.numel()].view(self.shape).contiguous() + return param + + +def _zero3_merge_trainable_params(state_dict, world_size, fp32_flat_groups, zero_model_states): + param_shapes = zero_model_states[0].param_shapes + avail_numel = sum([flat_group.numel() for flat_group in fp32_flat_groups[0]]) * world_size + + # Reconstruction protocol: For zero3 we need to zip the partitions together at boundary of each + # param, re-consolidating each param, while dealing with padding if any + + # merge list of dicts, preserving order + param_shapes = {k: v for d in param_shapes for k, v in d.items()} + + if debug: + for i in range(world_size): + print(f"{FP32_FLAT_GROUPS}[{i}].shape={fp32_flat_groups[i].shape}") + + wanted_params = len(param_shapes) + wanted_numel = sum(shape.numel() for shape in param_shapes.values()) + # not asserting if there is a mismatch due to possible padding + avail_numel = fp32_flat_groups[0].numel() * world_size + print(f"Trainable params: Have {avail_numel} numels to process.") + print(f"Trainable params: Need {wanted_numel} numels in {wanted_params} params.") + + # params + # XXX: for huge models that can't fit into the host's RAM we will have to recode this to support + # out-of-core computing solution + offset = 0 + total_numel = 0 + total_params = 0 + flat_groups_offset = [0] + list(np.cumsum([flat_tensor.numel() for flat_tensor in fp32_flat_groups[0]])) + for name, shape in tqdm(param_shapes.items(), desc='Gathering sharded weights'): + unpartitioned_numel = shape.numel() + total_numel += unpartitioned_numel + total_params += 1 + partitioned_numel, partitioned_padding_numel = zero3_partitioned_param_info(unpartitioned_numel, world_size) + + if debug: + print( + f"Trainable params: {total_params} {name} full shape: {shape} partition0 numel={partitioned_numel} partitioned_padding_numel={partitioned_padding_numel}" + ) + + # memory efficient tensor + tensor = GatheredTensor(fp32_flat_groups, flat_groups_offset, offset, partitioned_numel, shape) + state_dict[name] = tensor + offset += partitioned_numel + + offset *= world_size + + # Sanity check + if offset != avail_numel: + raise ValueError(f"consumed {offset} numels out of {avail_numel} - something is wrong") + + print(f"Reconstructed Trainable fp32 state dict with {total_params} params {total_numel} elements") + + +def _get_fp32_state_dict_from_zero3_checkpoint(world_size, fp32_flat_groups, zero_model_states, + exclude_frozen_parameters): + state_dict = OrderedDict() + + # buffers + buffers = zero_model_states[0].buffers + state_dict.update(buffers) + if debug: + print(f"added {len(buffers)} buffers") + + if not exclude_frozen_parameters: + _zero3_merge_frozen_params(state_dict, world_size, zero_model_states) + + _zero3_merge_trainable_params(state_dict, world_size, fp32_flat_groups, zero_model_states) + + # recover shared parameters + for pair in zero_model_states[0].shared_params: + if pair[1] in state_dict: + state_dict[pair[0]] = state_dict[pair[1]] + + return state_dict + + +def to_torch_tensor(state_dict, return_empty_tensor=False): + """ + Convert state_dict of GatheredTensor to torch tensor + """ + torch_state_dict = {} + converted_tensors = {} + for name, tensor in state_dict.items(): + tensor_id = id(tensor) + if tensor_id in converted_tensors: # shared tensors + shared_tensor = torch_state_dict[converted_tensors[tensor_id]] + torch_state_dict[name] = shared_tensor + else: + converted_tensors[tensor_id] = name + if return_empty_tensor: + torch_state_dict[name] = torch.empty(tensor.shape, dtype=tensor.dtype) + else: + torch_state_dict[name] = tensor.contiguous() + return torch_state_dict + + +def get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir, + tag=None, + exclude_frozen_parameters=False, + lazy_mode=False): + """ + Convert ZeRO 2 or 3 checkpoint into a single fp32 consolidated state_dict that can be loaded with + ``load_state_dict()`` and used for training without DeepSpeed or shared with others, for example + via a model hub. + + Args: + - ``checkpoint_dir``: path to the desired checkpoint folder + - ``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`` + - ``exclude_frozen_parameters``: exclude frozen parameters + - ``lazy_mode``: get state_dict in lazy mode. It returns a dict of pesduo tensor instead of torch tensor, which is more memory efficient. + Convert the pesduo tensor to torch tensor by ``.contiguous()`` + + Returns: + - pytorch ``state_dict`` + + A typical usage might be :: + + from deepspeed.utils.zero_to_fp32 import get_fp32_state_dict_from_zero_checkpoint + # do the training and checkpoint saving + state_dict = get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir) # already on cpu + model = model.cpu() # move to cpu + model.load_state_dict(state_dict) + # submit to model hub or save the model to share with others + + In this example the ``model`` will no longer be usable in the deepspeed context of the same + application. i.e. you will need to re-initialize the deepspeed engine, since + ``model.load_state_dict(state_dict)`` will remove all the deepspeed magic from it. + + If you want it all done for you, use ``load_state_dict_from_zero_checkpoint`` instead. + + Note: the above usage may not work if your application doesn't have sufficient free CPU memory. + You may need to use the offline approach using the ``zero_to_fp32.py`` script that is saved with + the checkpoint. Or you can load state_dict in lazy mode :: + + from deepspeed.utils.zero_to_fp32 import get_fp32_state_dict_from_zero_checkpoint + state_dict = get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir, lazy_mode=True) # not on cpu + for name, lazy_tensor in state_dict.item(): + tensor = lazy_tensor.contiguous() # to cpu + print(name, tensor) + # del tensor to release memory if it no longer in use + """ + if tag is None: + latest_path = os.path.join(checkpoint_dir, 'latest') + if os.path.isfile(latest_path): + with open(latest_path, 'r') as fd: + tag = fd.read().strip() + else: + raise ValueError(f"Unable to find 'latest' file at {latest_path}") + + ds_checkpoint_dir = os.path.join(checkpoint_dir, tag) + + if not os.path.isdir(ds_checkpoint_dir): + raise FileNotFoundError(f"Directory '{ds_checkpoint_dir}' doesn't exist") + + state_dict = _get_fp32_state_dict_from_zero_checkpoint(ds_checkpoint_dir, exclude_frozen_parameters) + if lazy_mode: + return state_dict + else: + return to_torch_tensor(state_dict) + + +def convert_zero_checkpoint_to_fp32_state_dict(checkpoint_dir, + output_dir, + max_shard_size="5GB", + safe_serialization=False, + tag=None, + exclude_frozen_parameters=False): + """ + Convert ZeRO 2 or 3 checkpoint into a single fp32 consolidated ``state_dict`` file that can be + loaded with ``torch.load(file)`` + ``load_state_dict()`` and used for training without DeepSpeed. + + Args: + - ``checkpoint_dir``: path to the desired checkpoint folder. (one that contains the tag-folder, like ``global_step14``) + - ``output_dir``: directory to the pytorch fp32 state_dict output files + - ``max_shard_size``: the maximum size for a checkpoint before being sharded, default value is 5GB + - ``safe_serialization``: whether to save the model using `safetensors` or the traditional PyTorch way (that uses `pickle`). + - ``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`` + - ``exclude_frozen_parameters``: exclude frozen parameters + """ + + # Dependency pre-check + if safe_serialization: + try: + from safetensors.torch import save_file + except ImportError: + print('If you want to use `safe_serialization`, please `pip install safetensors`') + raise + if max_shard_size is not None: + try: + from huggingface_hub import split_torch_state_dict_into_shards + except ImportError: + print('If you want to use `max_shard_size`, please `pip install huggingface_hub`') + raise + + # Convert zero checkpoint to state_dict + state_dict = get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir, + tag, + exclude_frozen_parameters, + lazy_mode=True) + + # Shard the model if it is too big. + weights_name = "model.safetensors" if safe_serialization else "pytorch_model.bin" + if max_shard_size is not None: + filename_pattern = weights_name.replace(".bin", "{suffix}.bin").replace(".safetensors", "{suffix}.safetensors") + # an memory-efficient approach for sharding + empty_state_dict = to_torch_tensor(state_dict, return_empty_tensor=True) + state_dict_split = split_torch_state_dict_into_shards(empty_state_dict, + filename_pattern=filename_pattern, + max_shard_size=max_shard_size) + else: + from collections import namedtuple + StateDictSplit = namedtuple("StateDictSplit", ["is_sharded", "filename_to_tensors"]) + state_dict_split = StateDictSplit(is_sharded=False, + filename_to_tensors={weights_name: list(state_dict.keys())}) + + # Save the model by shard + os.makedirs(output_dir, exist_ok=True) + filename_to_tensors = state_dict_split.filename_to_tensors.items() + for shard_file, tensors in tqdm(filename_to_tensors, desc="Saving checkpoint shards"): + shard_state_dict = {tensor_name: state_dict[tensor_name] for tensor_name in tensors} + shard_state_dict = to_torch_tensor(shard_state_dict) + output_path = os.path.join(output_dir, shard_file) + if safe_serialization: + save_file(shard_state_dict, output_path, metadata={"format": "pt"}) + else: + torch.save(shard_state_dict, output_path) + # release the memory of current shard + for tensor_name in list(shard_state_dict.keys()): + del state_dict[tensor_name] + del shard_state_dict[tensor_name] + del shard_state_dict + gc.collect() + + # Save index if sharded + if state_dict_split.is_sharded: + index = { + "metadata": state_dict_split.metadata, + "weight_map": state_dict_split.tensor_to_filename, + } + save_index_file = "model.safetensors.index.json" if safe_serialization else "pytorch_model.bin.index.json" + save_index_file = os.path.join(output_dir, save_index_file) + with open(save_index_file, "w", encoding="utf-8") as f: + content = json.dumps(index, indent=2, sort_keys=True) + "\n" + f.write(content) + + +def load_state_dict_from_zero_checkpoint(model, checkpoint_dir, tag=None): + """ + 1. Put the provided model to cpu + 2. Convert ZeRO 2 or 3 checkpoint into a single fp32 consolidated ``state_dict`` + 3. Load it into the provided model + + Args: + - ``model``: the model object to update + - ``checkpoint_dir``: path to the desired checkpoint folder. (one that contains the tag-folder, like ``global_step14``) + - ``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`` + + Returns: + - ``model`: modified model + + Make sure you have plenty of CPU memory available before you call this function. If you don't + have enough use the ``zero_to_fp32.py`` utility to do the conversion. You will find it + conveniently placed for you in the checkpoint folder. + + A typical usage might be :: + + from deepspeed.utils.zero_to_fp32 import load_state_dict_from_zero_checkpoint + model = load_state_dict_from_zero_checkpoint(trainer.model, checkpoint_dir) + # submit to model hub or save the model to share with others + + Note, that once this was run, the ``model`` will no longer be usable in the deepspeed context + of the same application. i.e. you will need to re-initialize the deepspeed engine, since + ``model.load_state_dict(state_dict)`` will remove all the deepspeed magic from it. + + """ + logger.info("Extracting fp32 weights") + state_dict = get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir, tag) + + logger.info("Overwriting model with fp32 weights") + model = model.cpu() + model.load_state_dict(state_dict, strict=False) + + return model + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument("checkpoint_dir", + type=str, + help="path to the desired checkpoint folder, e.g., path/checkpoint-12") + parser.add_argument("output_dir", + type=str, + help="directory to the pytorch fp32 state_dict output files" + "(e.g. path/checkpoint-12-output/)") + parser.add_argument( + "--max_shard_size", + type=str, + default="5GB", + help="The maximum size for a checkpoint before being sharded. Checkpoints shard will then be each of size" + "lower than this size. If expressed as a string, needs to be digits followed by a unit (like `5MB`" + "We default it to 5GB in order for models to be able to run easily on free-tier google colab instances" + "without CPU OOM issues.") + parser.add_argument( + "--safe_serialization", + default=False, + action='store_true', + help="Whether to save the model using `safetensors` or the traditional PyTorch way (that uses `pickle`).") + parser.add_argument("-t", + "--tag", + type=str, + default=None, + help="checkpoint tag used as a unique identifier for checkpoint. e.g., global_step1") + parser.add_argument("--exclude_frozen_parameters", action='store_true', help="exclude frozen parameters") + parser.add_argument("-d", "--debug", action='store_true', help="enable debug") + args = parser.parse_args() + + debug = args.debug + + convert_zero_checkpoint_to_fp32_state_dict(args.checkpoint_dir, + args.output_dir, + max_shard_size=args.max_shard_size, + safe_serialization=args.safe_serialization, + tag=args.tag, + exclude_frozen_parameters=args.exclude_frozen_parameters) diff --git a/qwen3/csd/checkpoint-942/README.md b/qwen3/csd/checkpoint-942/README.md new file mode 100644 index 0000000000000000000000000000000000000000..776f98d43659dd923b8c3e5649c5ae66d1f99f3e --- /dev/null +++ b/qwen3/csd/checkpoint-942/README.md @@ -0,0 +1,208 @@ +--- +base_model: Qwen/Qwen3-0.6B +library_name: peft +pipeline_tag: text-generation +tags: +- base_model:adapter:Qwen/Qwen3-0.6B +- llama-factory +- lora +- transformers +--- + +# Model Card for Model ID + + + + + +## Model Details + +### Model Description + + + + + +- **Developed by:** [More Information Needed] +- **Funded by [optional]:** [More Information Needed] +- **Shared by [optional]:** [More Information Needed] +- **Model type:** [More Information Needed] +- **Language(s) (NLP):** [More Information Needed] +- **License:** [More Information Needed] +- **Finetuned from model [optional]:** [More Information Needed] + +### Model Sources [optional] + + + +- **Repository:** [More Information Needed] +- **Paper [optional]:** [More Information Needed] +- **Demo [optional]:** [More Information Needed] + +## Uses + + + +### Direct Use + + + +[More Information Needed] + +### Downstream Use [optional] + + + +[More Information Needed] + +### Out-of-Scope Use + + + +[More Information Needed] + +## Bias, Risks, and Limitations + + + +[More Information Needed] + +### Recommendations + + + +Users (both direct and downstream) should be made aware of the risks, biases and limitations of the model. More information needed for further recommendations. + +## How to Get Started with the Model + +Use the code below to get started with the model. + +[More Information Needed] + +## Training Details + +### Training Data + + + +[More Information Needed] + +### Training Procedure + + + +#### Preprocessing [optional] + +[More Information Needed] + + +#### Training Hyperparameters + +- **Training regime:** [More Information Needed] + +#### Speeds, Sizes, Times [optional] + + + +[More Information Needed] + +## Evaluation + + + +### Testing Data, Factors & Metrics + +#### Testing Data + + + +[More Information Needed] + +#### Factors + + + +[More Information Needed] + +#### Metrics + + + +[More Information Needed] + +### Results + +[More Information Needed] + +#### Summary + + + +## Model Examination [optional] + + + +[More Information Needed] + +## Environmental Impact + + + +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). + +- **Hardware Type:** [More Information Needed] +- **Hours used:** [More Information Needed] +- **Cloud Provider:** [More Information Needed] +- **Compute Region:** [More Information Needed] +- **Carbon Emitted:** [More Information Needed] + +## Technical Specifications [optional] + +### Model Architecture and Objective + +[More Information Needed] + +### Compute Infrastructure + +[More Information Needed] + +#### Hardware + +[More Information Needed] + +#### Software + +[More Information Needed] + +## Citation [optional] + + + +**BibTeX:** + +[More Information Needed] + +**APA:** + +[More Information Needed] + +## Glossary [optional] + + + +[More Information Needed] + +## More Information [optional] + +[More Information Needed] + +## Model Card Authors [optional] + +[More Information Needed] + +## Model Card Contact + +[More Information Needed] +### Framework versions + +- PEFT 0.18.1 \ No newline at end of file diff --git a/qwen3/csd/checkpoint-942/adapter_config.json b/qwen3/csd/checkpoint-942/adapter_config.json new file mode 100644 index 0000000000000000000000000000000000000000..9959003652c9aaae4cece005b46aaf87e6d0f224 --- /dev/null +++ b/qwen3/csd/checkpoint-942/adapter_config.json @@ -0,0 +1,46 @@ +{ + "alora_invocation_tokens": null, + "alpha_pattern": {}, + "arrow_config": null, + "auto_mapping": null, + "base_model_name_or_path": "Qwen/Qwen3-0.6B", + "bias": "none", + "corda_config": null, + "ensure_weight_tying": false, + "eva_config": null, + "exclude_modules": null, + "fan_in_fan_out": false, + "inference_mode": true, + "init_lora_weights": true, + "layer_replication": null, + "layers_pattern": null, + "layers_to_transform": null, + "loftq_config": {}, + "lora_alpha": 64, + "lora_bias": false, + "lora_dropout": 0.1, + "megatron_config": null, + "megatron_core": "megatron.core", + "modules_to_save": null, + "peft_type": "LORA", + "peft_version": "0.18.1", + "qalora_group_size": 16, + "r": 32, + "rank_pattern": {}, + "revision": null, + "target_modules": [ + "down_proj", + "up_proj", + "v_proj", + "q_proj", + "gate_proj", + "o_proj", + "k_proj" + ], + "target_parameters": null, + "task_type": "CAUSAL_LM", + "trainable_token_indices": null, + "use_dora": false, + "use_qalora": false, + "use_rslora": false +} \ No newline at end of file diff --git a/qwen3/csd/checkpoint-942/adapter_model.safetensors b/qwen3/csd/checkpoint-942/adapter_model.safetensors new file mode 100644 index 0000000000000000000000000000000000000000..274d1cb91f7532fc63d04c058e05383bfdcb87bc --- /dev/null +++ b/qwen3/csd/checkpoint-942/adapter_model.safetensors @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:41307e764f199471398c357bef49275eed521835fb93c390c9aa923b54b8fbac +size 40422560 diff --git a/qwen3/csd/checkpoint-942/chat_template.jinja b/qwen3/csd/checkpoint-942/chat_template.jinja new file mode 100644 index 0000000000000000000000000000000000000000..01be9b307daa2d425f7c168c9fb145a286e0afb4 --- /dev/null +++ b/qwen3/csd/checkpoint-942/chat_template.jinja @@ -0,0 +1,89 @@ +{%- if tools %} + {{- '<|im_start|>system\n' }} + {%- if messages[0].role == 'system' %} + {{- messages[0].content + '\n\n' }} + {%- endif %} + {{- "# Tools\n\nYou may call one or more functions to assist with the user query.\n\nYou are provided with function signatures within XML tags:\n" }} + {%- for tool in tools %} + {{- "\n" }} + {{- tool | tojson }} + {%- endfor %} + {{- "\n\n\nFor each function call, return a json object with function name and arguments within XML tags:\n\n{\"name\": , \"arguments\": }\n<|im_end|>\n" }} +{%- else %} + {%- if messages[0].role == 'system' %} + {{- '<|im_start|>system\n' + messages[0].content + '<|im_end|>\n' }} + {%- endif %} +{%- endif %} +{%- set ns = namespace(multi_step_tool=true, last_query_index=messages|length - 1) %} +{%- for message in messages[::-1] %} + {%- set index = (messages|length - 1) - loop.index0 %} + {%- if ns.multi_step_tool and message.role == "user" and message.content is string and not(message.content.startswith('') and message.content.endswith('')) %} + {%- set ns.multi_step_tool = false %} + {%- set ns.last_query_index = index %} + {%- endif %} +{%- endfor %} +{%- for message in messages %} + {%- if message.content is string %} + {%- set content = message.content %} + {%- else %} + {%- set content = '' %} + {%- endif %} + {%- if (message.role == "user") or (message.role == "system" and not loop.first) %} + {{- '<|im_start|>' + message.role + '\n' + content + '<|im_end|>' + '\n' }} + {%- elif message.role == "assistant" %} + {%- set reasoning_content = '' %} + {%- if message.reasoning_content is string %} + {%- set reasoning_content = message.reasoning_content %} + {%- else %} + {%- if '' in content %} + {%- set reasoning_content = content.split('')[0].rstrip('\n').split('')[-1].lstrip('\n') %} + {%- set content = content.split('')[-1].lstrip('\n') %} + {%- endif %} + {%- endif %} + {%- if loop.index0 > ns.last_query_index %} + {%- if loop.last or (not loop.last and reasoning_content) %} + {{- '<|im_start|>' + message.role + '\n\n' + reasoning_content.strip('\n') + '\n\n\n' + content.lstrip('\n') }} + {%- else %} + {{- '<|im_start|>' + message.role + '\n' + content }} + {%- endif %} + {%- else %} + {{- '<|im_start|>' + message.role + '\n' + content }} + {%- endif %} + {%- if message.tool_calls %} + {%- for tool_call in message.tool_calls %} + {%- if (loop.first and content) or (not loop.first) %} + {{- '\n' }} + {%- endif %} + {%- if tool_call.function %} + {%- set tool_call = tool_call.function %} + {%- endif %} + {{- '\n{"name": "' }} + {{- tool_call.name }} + {{- '", "arguments": ' }} + {%- if tool_call.arguments is string %} + {{- tool_call.arguments }} + {%- else %} + {{- tool_call.arguments | tojson }} + {%- endif %} + {{- '}\n' }} + {%- endfor %} + {%- endif %} + {{- '<|im_end|>\n' }} + {%- elif message.role == "tool" %} + {%- if loop.first or (messages[loop.index0 - 1].role != "tool") %} + {{- '<|im_start|>user' }} + {%- endif %} + {{- '\n\n' }} + {{- content }} + {{- '\n' }} + {%- if loop.last or (messages[loop.index0 + 1].role != "tool") %} + {{- '<|im_end|>\n' }} + {%- endif %} + {%- endif %} +{%- endfor %} +{%- if add_generation_prompt %} + {{- '<|im_start|>assistant\n' }} + {%- if enable_thinking is defined and enable_thinking is false %} + {{- '\n\n\n\n' }} + {%- endif %} +{%- endif %} \ No newline at end of file diff --git a/qwen3/csd/checkpoint-942/global_step942/bf16_zero_pp_rank_0_mp_rank_00_optim_states.pt b/qwen3/csd/checkpoint-942/global_step942/bf16_zero_pp_rank_0_mp_rank_00_optim_states.pt new file mode 100644 index 0000000000000000000000000000000000000000..eb9a594bd30d3d3b8f8153a30d966cc4f1279bd8 --- /dev/null +++ b/qwen3/csd/checkpoint-942/global_step942/bf16_zero_pp_rank_0_mp_rank_00_optim_states.pt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3759ef693f54f35b13069160c5d8a07559e35684ed5bf38a0d9ecb784ece88d4 +size 121135557 diff --git a/qwen3/csd/checkpoint-942/global_step942/bf16_zero_pp_rank_1_mp_rank_00_optim_states.pt b/qwen3/csd/checkpoint-942/global_step942/bf16_zero_pp_rank_1_mp_rank_00_optim_states.pt new file mode 100644 index 0000000000000000000000000000000000000000..e5590bfbee8e31c7d9f0366003b00786718d0a93 --- /dev/null +++ b/qwen3/csd/checkpoint-942/global_step942/bf16_zero_pp_rank_1_mp_rank_00_optim_states.pt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5b0d384d4366696a0b6e1d09d5af28e0405cc8fdcc9391aea83352acf2c9df51 +size 121135749 diff --git a/qwen3/csd/checkpoint-942/global_step942/mp_rank_00_model_states.pt b/qwen3/csd/checkpoint-942/global_step942/mp_rank_00_model_states.pt new file mode 100644 index 0000000000000000000000000000000000000000..9682e6908906693685dcc06a8c9fe01363a46000 --- /dev/null +++ b/qwen3/csd/checkpoint-942/global_step942/mp_rank_00_model_states.pt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9e8a2874917593811eb141fe4e6b049753292d104edb3763755e7ee0ea61d64a +size 351841765 diff --git a/qwen3/csd/checkpoint-942/latest b/qwen3/csd/checkpoint-942/latest new file mode 100644 index 0000000000000000000000000000000000000000..4e9a68e4460aca593c480611a486d2a4cd73ef42 --- /dev/null +++ b/qwen3/csd/checkpoint-942/latest @@ -0,0 +1 @@ +global_step942 \ No newline at end of file diff --git a/qwen3/csd/checkpoint-942/rng_state_0.pth b/qwen3/csd/checkpoint-942/rng_state_0.pth new file mode 100644 index 0000000000000000000000000000000000000000..8f8b77d4cdc54516505d36ac7fb5715b58436c78 --- /dev/null +++ b/qwen3/csd/checkpoint-942/rng_state_0.pth @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:18d771c9a513dbae7970979494c25db1b118adc2e913f25175b0c80845d96441 +size 14917 diff --git a/qwen3/csd/checkpoint-942/rng_state_1.pth b/qwen3/csd/checkpoint-942/rng_state_1.pth new file mode 100644 index 0000000000000000000000000000000000000000..7f8a81fb86858f1045478c8dcec2eb804ff91120 --- /dev/null +++ b/qwen3/csd/checkpoint-942/rng_state_1.pth @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5b4d52eca5a91b412c929ff7e86bc2b8e4d0c0eacf6a27c8afc10c8a1d585a8b +size 14917 diff --git a/qwen3/csd/checkpoint-942/scheduler.pt b/qwen3/csd/checkpoint-942/scheduler.pt new file mode 100644 index 0000000000000000000000000000000000000000..6b1f8af0480bf83ab728abfeff11bc3288214349 --- /dev/null +++ b/qwen3/csd/checkpoint-942/scheduler.pt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8076da6f897951c5bdf8649e4fba596e8c49819927746017442ffd85f40b18a3 +size 1465 diff --git a/qwen3/csd/checkpoint-942/tokenizer.json b/qwen3/csd/checkpoint-942/tokenizer.json new file mode 100644 index 0000000000000000000000000000000000000000..c7afbed2efcdf019f88ab0572ec29d3bf595dfe2 --- /dev/null +++ b/qwen3/csd/checkpoint-942/tokenizer.json @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:be75606093db2094d7cd20f3c2f385c212750648bd6ea4fb2bf507a6a4c55506 +size 11422650 diff --git a/qwen3/csd/checkpoint-942/tokenizer_config.json b/qwen3/csd/checkpoint-942/tokenizer_config.json new file mode 100644 index 0000000000000000000000000000000000000000..6623da03457d79d2cd4af9557e9f31407cdb835c --- /dev/null +++ b/qwen3/csd/checkpoint-942/tokenizer_config.json @@ -0,0 +1,31 @@ +{ + "add_prefix_space": false, + "backend": "tokenizers", + "bos_token": null, + "clean_up_tokenization_spaces": false, + "eos_token": "<|im_end|>", + "errors": "replace", + "extra_special_tokens": [ + "<|im_start|>", + "<|im_end|>", + "<|object_ref_start|>", + "<|object_ref_end|>", + "<|box_start|>", + "<|box_end|>", + "<|quad_start|>", + "<|quad_end|>", + "<|vision_start|>", + "<|vision_end|>", + "<|vision_pad|>", + "<|image_pad|>", + "<|video_pad|>" + ], + "is_local": false, + "local_files_only": false, + "model_max_length": 131072, + "pad_token": "<|endoftext|>", + "padding_side": "right", + "split_special_tokens": false, + "tokenizer_class": "Qwen2Tokenizer", + "unk_token": null +} diff --git a/qwen3/csd/checkpoint-942/trainer_state.json b/qwen3/csd/checkpoint-942/trainer_state.json new file mode 100644 index 0000000000000000000000000000000000000000..b0bd542aa0d9b80226abb6e1c26820d3bdb6b96e --- /dev/null +++ b/qwen3/csd/checkpoint-942/trainer_state.json @@ -0,0 +1,408 @@ +{ + "best_global_step": null, + "best_metric": null, + "best_model_checkpoint": null, + "epoch": 3.0, + "eval_steps": 500, + "global_step": 942, + "is_hyper_param_search": false, + "is_local_process_zero": true, + "is_world_process_zero": true, + "log_history": [ + { + "epoch": 0.06382130035899482, + "grad_norm": 6.0161848068237305, + "learning_rate": 9.996390385474569e-05, + "loss": 0.11036398410797119, + "step": 20 + }, + { + "epoch": 0.12764260071798963, + "grad_norm": 4.099686622619629, + "learning_rate": 9.984797509888031e-05, + "loss": 0.01695394217967987, + "step": 40 + }, + { + "epoch": 0.19146390107698444, + "grad_norm": 3.3755345344543457, + "learning_rate": 9.965229938050925e-05, + "loss": 0.03482693731784821, + "step": 60 + }, + { + "epoch": 0.25528520143597927, + "grad_norm": 1.194334864616394, + "learning_rate": 9.937719005663432e-05, + "loss": 0.027955988049507143, + "step": 80 + }, + { + "epoch": 0.3191065017949741, + "grad_norm": 6.6159281730651855, + "learning_rate": 9.902308769000724e-05, + "loss": 0.005286623537540436, + "step": 100 + }, + { + "epoch": 0.3829278021539689, + "grad_norm": 2.851339817047119, + "learning_rate": 9.859055934360789e-05, + "loss": 0.01179061084985733, + "step": 120 + }, + { + "epoch": 0.4467491025129637, + "grad_norm": 0.989425539970398, + "learning_rate": 9.808029767254437e-05, + "loss": 0.006131124496459961, + "step": 140 + }, + { + "epoch": 0.5105704028719585, + "grad_norm": 1.3493149280548096, + "learning_rate": 9.749311981482817e-05, + "loss": 0.007052437216043472, + "step": 160 + }, + { + "epoch": 0.5743917032309533, + "grad_norm": 0.9337753057479858, + "learning_rate": 9.682996608280154e-05, + "loss": -0.002346178889274597, + "step": 180 + }, + { + "epoch": 0.6382130035899481, + "grad_norm": 1.5435981750488281, + "learning_rate": 9.609189845731207e-05, + "loss": 0.013309524953365326, + "step": 200 + }, + { + "epoch": 0.702034303948943, + "grad_norm": 0.7995954155921936, + "learning_rate": 9.52800988870462e-05, + "loss": 0.008521870523691178, + "step": 220 + }, + { + "epoch": 0.7658556043079378, + "grad_norm": 1.6571325063705444, + "learning_rate": 9.439586739574513e-05, + "loss": 0.008653326332569123, + "step": 240 + }, + { + "epoch": 0.8296769046669326, + "grad_norm": 0.519936203956604, + "learning_rate": 9.344062000033414e-05, + "loss": 0.004485934227705002, + "step": 260 + }, + { + "epoch": 0.8934982050259274, + "grad_norm": 0.31598174571990967, + "learning_rate": 9.241588644329919e-05, + "loss": 0.003059915825724602, + "step": 280 + }, + { + "epoch": 0.9573195053849222, + "grad_norm": 0.48084524273872375, + "learning_rate": 9.132330774294252e-05, + "loss": 0.005025627836585045, + "step": 300 + }, + { + "epoch": 1.0, + "eval_generator_count": 1712.0, + "eval_generator_exact_match": 86.2734, + "eval_generator_rouge1": 99.1343, + "eval_generator_rouge2": 98.8297, + "eval_generator_rougeL": 98.6074, + "eval_loss": 0.019235465675592422, + "eval_runtime": 603.0951, + "eval_samples_per_second": 5.661, + "eval_selector_accuracy": 93.3995, + "eval_selector_count": 1712.0, + "eval_steps_per_second": 0.177, + "step": 314 + }, + { + "epoch": 1.0191463901076985, + "grad_norm": 0.34810933470726013, + "learning_rate": 9.01646335654399e-05, + "loss": 0.008805014193058014, + "step": 320 + }, + { + "epoch": 1.0829676904666932, + "grad_norm": 0.19888198375701904, + "learning_rate": 8.894171942290817e-05, + "loss": 0.0013909661211073399, + "step": 340 + }, + { + "epoch": 1.146788990825688, + "grad_norm": 1.0506941080093384, + "learning_rate": 8.765652370197003e-05, + "loss": 0.0005901294760406017, + "step": 360 + }, + { + "epoch": 1.210610291184683, + "grad_norm": 2.363455057144165, + "learning_rate": 8.631110452757467e-05, + "loss": -0.0003092627972364426, + "step": 380 + }, + { + "epoch": 1.2744315915436777, + "grad_norm": 0.0766368880867958, + "learning_rate": 8.490761646709642e-05, + "loss": -0.002663038857281208, + "step": 400 + }, + { + "epoch": 1.3382528919026724, + "grad_norm": 0.1551397442817688, + "learning_rate": 8.344830707998953e-05, + "loss": 0.0026730677112936974, + "step": 420 + }, + { + "epoch": 1.4020741922616673, + "grad_norm": 0.7773767113685608, + "learning_rate": 8.193551331852458e-05, + "loss": -0.0011709232814610005, + "step": 440 + }, + { + "epoch": 1.4658954926206622, + "grad_norm": 0.42017874121665955, + "learning_rate": 8.037165778537033e-05, + "loss": -0.0019059792160987855, + "step": 460 + }, + { + "epoch": 1.5297167929796571, + "grad_norm": 1.0544211864471436, + "learning_rate": 7.875924485401427e-05, + "loss": -0.004772515594959259, + "step": 480 + }, + { + "epoch": 1.5935380933386518, + "grad_norm": 0.4706478416919708, + "learning_rate": 7.710085665823444e-05, + "loss": -0.0002438830444589257, + "step": 500 + }, + { + "epoch": 1.6573593936976465, + "grad_norm": 0.22088219225406647, + "learning_rate": 7.539914895704521e-05, + "loss": -0.004391691088676453, + "step": 520 + }, + { + "epoch": 1.7211806940566414, + "grad_norm": 0.5972660183906555, + "learning_rate": 7.365684688173908e-05, + "loss": -0.007541544735431671, + "step": 540 + }, + { + "epoch": 1.7850019944156363, + "grad_norm": 0.19400978088378906, + "learning_rate": 7.18767405718347e-05, + "loss": -0.004146666824817657, + "step": 560 + }, + { + "epoch": 1.848823294774631, + "grad_norm": 1.2469046115875244, + "learning_rate": 7.006168070692036e-05, + "loss": -0.0019529350101947784, + "step": 580 + }, + { + "epoch": 1.9126445951336257, + "grad_norm": 0.14316241443157196, + "learning_rate": 6.821457394154786e-05, + "loss": -0.008291246742010117, + "step": 600 + }, + { + "epoch": 1.9764658954926206, + "grad_norm": 0.4657886326313019, + "learning_rate": 6.633837825048768e-05, + "loss": -0.006107022240757942, + "step": 620 + }, + { + "epoch": 2.0, + "eval_generator_count": 1712.0, + "eval_generator_exact_match": 94.6846, + "eval_generator_rouge1": 99.7652, + "eval_generator_rouge2": 99.667, + "eval_generator_rougeL": 99.5471, + "eval_loss": 0.006834100466221571, + "eval_runtime": 601.0294, + "eval_samples_per_second": 5.68, + "eval_selector_accuracy": 97.8388, + "eval_selector_count": 1712.0, + "eval_steps_per_second": 0.178, + "step": 628 + }, + { + "epoch": 2.038292780215397, + "grad_norm": 0.22094473242759705, + "learning_rate": 6.443609819179926e-05, + "loss": -0.005953450500965118, + "step": 640 + }, + { + "epoch": 2.102114080574392, + "grad_norm": 0.5406356453895569, + "learning_rate": 6.251078009530256e-05, + "loss": -0.0025423141196370125, + "step": 660 + }, + { + "epoch": 2.1659353809333863, + "grad_norm": 0.09373176842927933, + "learning_rate": 6.0565507184155677e-05, + "loss": -0.0044939789921045305, + "step": 680 + }, + { + "epoch": 2.2297566812923812, + "grad_norm": 0.1080167219042778, + "learning_rate": 5.860339463735136e-05, + "loss": -0.00820673182606697, + "step": 700 + }, + { + "epoch": 2.293577981651376, + "grad_norm": 0.05399267002940178, + "learning_rate": 5.662758460103895e-05, + "loss": -0.009635555744171142, + "step": 720 + }, + { + "epoch": 2.357399282010371, + "grad_norm": 0.2048628032207489, + "learning_rate": 5.464124115666095e-05, + "loss": -0.010086850821971893, + "step": 740 + }, + { + "epoch": 2.421220582369366, + "grad_norm": 0.08765007555484772, + "learning_rate": 5.264754525396212e-05, + "loss": -0.008542184531688691, + "step": 760 + }, + { + "epoch": 2.4850418827283605, + "grad_norm": 0.2229253351688385, + "learning_rate": 5.06496896169857e-05, + "loss": -0.011658547818660736, + "step": 780 + }, + { + "epoch": 2.5488631830873554, + "grad_norm": 0.18513049185276031, + "learning_rate": 4.865087363121384e-05, + "loss": -0.00930779054760933, + "step": 800 + }, + { + "epoch": 2.6126844834463503, + "grad_norm": 0.3498702347278595, + "learning_rate": 4.6654298220040673e-05, + "loss": -0.014870831370353698, + "step": 820 + }, + { + "epoch": 2.6765057838053448, + "grad_norm": 0.16160713136196136, + "learning_rate": 4.466316071878229e-05, + "loss": -0.020250825583934783, + "step": 840 + }, + { + "epoch": 2.74032708416434, + "grad_norm": 0.16046860814094543, + "learning_rate": 4.2680649754432913e-05, + "loss": -0.018617722392082214, + "step": 860 + }, + { + "epoch": 2.8041483845233346, + "grad_norm": 0.17135752737522125, + "learning_rate": 4.070994013936646e-05, + "loss": -0.020963044464588167, + "step": 880 + }, + { + "epoch": 2.8679696848823295, + "grad_norm": 0.24867695569992065, + "learning_rate": 3.8754187787161155e-05, + "loss": -0.020418259501457214, + "step": 900 + }, + { + "epoch": 2.9317909852413244, + "grad_norm": 0.12315966188907623, + "learning_rate": 3.681652465868875e-05, + "loss": -0.018548570573329926, + "step": 920 + }, + { + "epoch": 2.995612285600319, + "grad_norm": 0.14333273470401764, + "learning_rate": 3.490005374656184e-05, + "loss": -0.018815448880195616, + "step": 940 + }, + { + "epoch": 3.0, + "eval_generator_count": 1712.0, + "eval_generator_exact_match": 95.736, + "eval_generator_rouge1": 99.9465, + "eval_generator_rouge2": 99.8866, + "eval_generator_rougeL": 99.7132, + "eval_loss": 0.005336109548807144, + "eval_runtime": 608.1178, + "eval_samples_per_second": 5.614, + "eval_selector_accuracy": 97.722, + "eval_selector_count": 1712.0, + "eval_steps_per_second": 0.176, + "step": 942 + } + ], + "logging_steps": 20, + "max_steps": 1570, + "num_input_tokens_seen": 0, + "num_train_epochs": 5, + "save_steps": 500, + "stateful_callbacks": { + "TrainerControl": { + "args": { + "should_epoch_stop": false, + "should_evaluate": false, + "should_log": false, + "should_save": true, + "should_training_stop": false + }, + "attributes": {} + } + }, + "total_flos": 3.524157743353037e+16, + "train_batch_size": 2, + "trial_name": null, + "trial_params": null +} diff --git a/qwen3/csd/checkpoint-942/training_args.bin b/qwen3/csd/checkpoint-942/training_args.bin new file mode 100644 index 0000000000000000000000000000000000000000..4b4d426a661bf64c99e9ff7730557b24ebf0e60c --- /dev/null +++ b/qwen3/csd/checkpoint-942/training_args.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:83e0687327fbf0a1cbac0cde783b20e396ed970bb1eed13dcf33e672089c5f44 +size 7185 diff --git a/qwen3/csd/checkpoint-942/zero_to_fp32.py b/qwen3/csd/checkpoint-942/zero_to_fp32.py new file mode 100644 index 0000000000000000000000000000000000000000..f40f1f0acbbff30e8e8d29906b56aae4e8b8a138 --- /dev/null +++ b/qwen3/csd/checkpoint-942/zero_to_fp32.py @@ -0,0 +1,790 @@ +#!/usr/bin/env python + +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: Apache-2.0 + +# DeepSpeed Team + +# This script extracts fp32 consolidated weights from a zero 1, 2 and 3 DeepSpeed checkpoints. It gets +# copied into the top level checkpoint dir, so the user can easily do the conversion at any point in +# the future. Once extracted, the weights don't require DeepSpeed and can be used in any +# application. +# +# example: +# python zero_to_fp32.py . output_dir/ +# or +# python zero_to_fp32.py . output_dir/ --safe_serialization + +import argparse +import torch +import glob +import math +import os +import re +import gc +import json +import numpy as np +from tqdm import tqdm +from collections import OrderedDict +from dataclasses import dataclass + +# while this script doesn't use deepspeed to recover data, since the checkpoints are pickled with +# DeepSpeed data structures it has to be available in the current python environment. +from deepspeed.utils import logger +from deepspeed.checkpoint.constants import (DS_VERSION, OPTIMIZER_STATE_DICT, SINGLE_PARTITION_OF_FP32_GROUPS, + FP32_FLAT_GROUPS, ZERO_STAGE, PARTITION_COUNT, PARAM_SHAPES, BUFFER_NAMES, + FROZEN_PARAM_SHAPES, FROZEN_PARAM_FRAGMENTS, AUTOEP_LAYERS_KEY, + AUTOEP_LAYERS_KEY_LEGACY, AUTOEP_ZERO3_EXPERT_STATE_FORMAT_KEY, + AUTOEP_ZERO3_PARTITIONED_EXPERT_STATE_FORMAT) + + +@dataclass +class zero_model_state: + buffers: dict() + param_shapes: dict() + shared_params: list + ds_version: int + frozen_param_shapes: dict() + frozen_param_fragments: dict() + + +debug = 0 + +# load to cpu +device = torch.device('cpu') + + +def atoi(text): + return int(text) if text.isdigit() else text + + +def natural_keys(text): + ''' + alist.sort(key=natural_keys) sorts in human order + http://nedbatchelder.com/blog/200712/human_sorting.html + (See Toothy's implementation in the comments) + ''' + return [atoi(c) for c in re.split(r'(\d+)', text)] + + +def get_model_state_file(checkpoint_dir, zero_stage): + if not os.path.isdir(checkpoint_dir): + raise FileNotFoundError(f"Directory '{checkpoint_dir}' doesn't exist") + + # there should be only one file + if zero_stage <= 2: + file = os.path.join(checkpoint_dir, "mp_rank_00_model_states.pt") + elif zero_stage == 3: + file = os.path.join(checkpoint_dir, "zero_pp_rank_0_mp_rank_00_model_states.pt") + + if not os.path.exists(file): + raise FileNotFoundError(f"can't find model states file at '{file}'") + + return file + + +def get_checkpoint_files(checkpoint_dir, glob_pattern): + # XXX: need to test that this simple glob rule works for multi-node setup too + ckpt_files = sorted(glob.glob(os.path.join(checkpoint_dir, glob_pattern)), key=natural_keys) + + if len(ckpt_files) == 0: + raise FileNotFoundError(f"can't find {glob_pattern} files in directory '{checkpoint_dir}'") + + return ckpt_files + + +def get_optim_files(checkpoint_dir): + return get_checkpoint_files(checkpoint_dir, "*_optim_states.pt") + + +def get_model_state_files(checkpoint_dir): + return get_checkpoint_files(checkpoint_dir, "*_model_states.pt") + + +def _has_autoep_zero3_partitioned_metadata(state_dict): + autoep_layers = state_dict.get(AUTOEP_LAYERS_KEY) + if autoep_layers is None: + autoep_layers = state_dict.get(AUTOEP_LAYERS_KEY_LEGACY) + if not isinstance(autoep_layers, list): + return False + return any( + isinstance(entry, dict) + and entry.get(AUTOEP_ZERO3_EXPERT_STATE_FORMAT_KEY) == AUTOEP_ZERO3_PARTITIONED_EXPERT_STATE_FORMAT + for entry in autoep_layers) + + +def _raise_if_autoep_zero3_partitioned_state(state_dict): + if _has_autoep_zero3_partitioned_metadata(state_dict): + raise NotImplementedError("zero_to_fp32 does not support AutoEP ZeRO-3 partition-native checkpoints. " + "AutoEP expert parameters are partitioned over expert replica groups, so " + "global data-parallel consolidation would produce incomplete expert tensors. " + "Use ds_to_universal.py for expert-aware conversion.") + + +def _raise_if_autoep_zero3_partitioned_checkpoint(model_files): + for file in model_files: + state_dict = torch.load(file, map_location=device, weights_only=False) + _raise_if_autoep_zero3_partitioned_state(state_dict) + + +def parse_model_states(files): + zero_model_states = [] + for file in files: + state_dict = torch.load(file, map_location=device, weights_only=False) + _raise_if_autoep_zero3_partitioned_state(state_dict) + + if BUFFER_NAMES not in state_dict: + raise ValueError(f"{file} is not a model state checkpoint") + buffer_names = state_dict[BUFFER_NAMES] + if debug: + print("Found buffers:", buffer_names) + + # recover just the buffers while restoring them to fp32 if they were saved in fp16 + buffers = {k: v.float() for k, v in state_dict["module"].items() if k in buffer_names} + param_shapes = state_dict[PARAM_SHAPES] + + # collect parameters that are included in param_shapes + param_names = [] + for s in param_shapes: + for name in s.keys(): + param_names.append(name) + + # update with frozen parameters + frozen_param_shapes = state_dict.get(FROZEN_PARAM_SHAPES, None) + if frozen_param_shapes is not None: + if debug: + print(f"Found frozen_param_shapes: {frozen_param_shapes}") + param_names += list(frozen_param_shapes.keys()) + + # handle shared params + shared_params = [[k, v] for k, v in state_dict["shared_params"].items()] + + ds_version = state_dict.get(DS_VERSION, None) + + frozen_param_fragments = state_dict.get(FROZEN_PARAM_FRAGMENTS, None) + + z_model_state = zero_model_state(buffers=buffers, + param_shapes=param_shapes, + shared_params=shared_params, + ds_version=ds_version, + frozen_param_shapes=frozen_param_shapes, + frozen_param_fragments=frozen_param_fragments) + zero_model_states.append(z_model_state) + + return zero_model_states + + +def parse_optim_states(files, ds_checkpoint_dir): + total_files = len(files) + state_dicts = [] + for f in tqdm(files, desc='Loading checkpoint shards'): + state_dict = torch.load(f, map_location=device, mmap=True, weights_only=False) + # immediately discard the potentially huge 2 optimizer states as we only care for fp32 master weights + # and also handle the case where it was already removed by another helper script + state_dict["optimizer_state_dict"].pop("optimizer_state_dict", None) + state_dicts.append(state_dict) + + if ZERO_STAGE not in state_dicts[0][OPTIMIZER_STATE_DICT]: + raise ValueError(f"{files[0]} is not a zero checkpoint") + zero_stage = state_dicts[0][OPTIMIZER_STATE_DICT][ZERO_STAGE] + world_size = state_dicts[0][OPTIMIZER_STATE_DICT][PARTITION_COUNT] + + # For ZeRO-2 each param group can have different partition_count as data parallelism for expert + # parameters can be different from data parallelism for non-expert parameters. So we can just + # use the max of the partition_count to get the dp world_size. + + if type(world_size) is list: + world_size = max(world_size) + + if world_size != total_files: + raise ValueError( + f"Expected {world_size} of '*_optim_states.pt' under '{ds_checkpoint_dir}' but found {total_files} files. " + "Possibly due to an overwrite of an old checkpoint, or a checkpoint didn't get saved by one or more processes." + ) + + # the groups are named differently in each stage + if zero_stage <= 2: + fp32_groups_key = SINGLE_PARTITION_OF_FP32_GROUPS + elif zero_stage == 3: + fp32_groups_key = FP32_FLAT_GROUPS + else: + raise ValueError(f"unknown zero stage {zero_stage}") + + fp32_flat_groups = [state_dicts[i][OPTIMIZER_STATE_DICT][fp32_groups_key] for i in range(len(state_dicts))] + return zero_stage, world_size, fp32_flat_groups + + +def _get_fp32_state_dict_from_zero_checkpoint(ds_checkpoint_dir, exclude_frozen_parameters): + """ + Returns fp32 state_dict reconstructed from ds checkpoint + + Args: + - ``ds_checkpoint_dir``: path to the deepspeed checkpoint folder (where the optimizer files are) + + """ + print(f"Processing zero checkpoint '{ds_checkpoint_dir}'") + + # parse_model_states rejects AutoEP ZeRO-3 partition-native checkpoints + # before the expensive optimizer-shard load below. + model_files = get_model_state_files(ds_checkpoint_dir) + zero_model_states = parse_model_states(model_files) + print(f'Parsing checkpoint created by deepspeed=={zero_model_states[0].ds_version}') + + optim_files = get_optim_files(ds_checkpoint_dir) + zero_stage, world_size, fp32_flat_groups = parse_optim_states(optim_files, ds_checkpoint_dir) + print(f"Detected checkpoint of type zero stage {zero_stage}, world_size: {world_size}") + + if zero_stage <= 2: + return _get_fp32_state_dict_from_zero2_checkpoint(world_size, fp32_flat_groups, zero_model_states, + exclude_frozen_parameters) + elif zero_stage == 3: + return _get_fp32_state_dict_from_zero3_checkpoint(world_size, fp32_flat_groups, zero_model_states, + exclude_frozen_parameters) + + +def _zero2_merge_frozen_params(state_dict, zero_model_states): + if zero_model_states[0].frozen_param_shapes is None or len(zero_model_states[0].frozen_param_shapes) == 0: + return + + frozen_param_shapes = zero_model_states[0].frozen_param_shapes + frozen_param_fragments = zero_model_states[0].frozen_param_fragments + + if debug: + num_elem = sum(s.numel() for s in frozen_param_shapes.values()) + print(f'rank 0: {FROZEN_PARAM_SHAPES}.numel = {num_elem}') + + wanted_params = len(frozen_param_shapes) + wanted_numel = sum(s.numel() for s in frozen_param_shapes.values()) + avail_numel = sum([p.numel() for p in frozen_param_fragments.values()]) + print(f'Frozen params: Have {avail_numel} numels to process.') + print(f'Frozen params: Need {wanted_numel} numels in {wanted_params} params') + + total_params = 0 + total_numel = 0 + for name, shape in frozen_param_shapes.items(): + total_params += 1 + unpartitioned_numel = shape.numel() + total_numel += unpartitioned_numel + + state_dict[name] = frozen_param_fragments[name] + + if debug: + print(f"{name} full shape: {shape} unpartitioned numel {unpartitioned_numel} ") + + print(f"Reconstructed Frozen fp32 state dict with {total_params} params {total_numel} elements") + + +def _has_callable(obj, fn): + attr = getattr(obj, fn, None) + return callable(attr) + + +def _zero2_merge_trainable_params(state_dict, world_size, fp32_flat_groups, zero_model_states): + param_shapes = zero_model_states[0].param_shapes + + # Reconstruction protocol: + # + # XXX: document this + + if debug: + for i in range(world_size): + for j in range(len(fp32_flat_groups[0])): + print(f"{FP32_FLAT_GROUPS}[{i}][{j}].shape={fp32_flat_groups[i][j].shape}") + + # XXX: memory usage doubles here (zero2) + num_param_groups = len(fp32_flat_groups[0]) + merged_single_partition_of_fp32_groups = [] + for i in range(num_param_groups): + merged_partitions = [sd[i] for sd in fp32_flat_groups] + full_single_fp32_vector = torch.cat(merged_partitions, 0) + merged_single_partition_of_fp32_groups.append(full_single_fp32_vector) + avail_numel = sum( + [full_single_fp32_vector.numel() for full_single_fp32_vector in merged_single_partition_of_fp32_groups]) + + if debug: + wanted_params = sum([len(shapes) for shapes in param_shapes]) + wanted_numel = sum([sum(shape.numel() for shape in shapes.values()) for shapes in param_shapes]) + # not asserting if there is a mismatch due to possible padding + print(f"Have {avail_numel} numels to process.") + print(f"Need {wanted_numel} numels in {wanted_params} params.") + + # params + # XXX: for huge models that can't fit into the host's RAM we will have to recode this to support + # out-of-core computing solution + total_numel = 0 + total_params = 0 + for shapes, full_single_fp32_vector in zip(param_shapes, merged_single_partition_of_fp32_groups): + offset = 0 + avail_numel = full_single_fp32_vector.numel() + for name, shape in shapes.items(): + + unpartitioned_numel = shape.numel() if _has_callable(shape, 'numel') else math.prod(shape) + total_numel += unpartitioned_numel + total_params += 1 + + if debug: + print(f"{name} full shape: {shape} unpartitioned numel {unpartitioned_numel} ") + state_dict[name] = full_single_fp32_vector.narrow(0, offset, unpartitioned_numel).view(shape) + offset += unpartitioned_numel + + # Z2 started to align to 2*world_size to improve nccl performance. Therefore both offset and + # avail_numel can differ by anywhere between 0..2*world_size. Due to two unrelated complex + # paddings performed in the code it's almost impossible to predict the exact numbers w/o the + # live optimizer object, so we are checking that the numbers are within the right range + align_to = 2 * world_size + + def zero2_align(x): + return align_to * math.ceil(x / align_to) + + if debug: + print(f"original offset={offset}, avail_numel={avail_numel}") + + offset = zero2_align(offset) + avail_numel = zero2_align(avail_numel) + + if debug: + print(f"aligned offset={offset}, avail_numel={avail_numel}") + + # Sanity check + if offset != avail_numel: + raise ValueError(f"consumed {offset} numels out of {avail_numel} - something is wrong") + + print(f"Reconstructed fp32 state dict with {total_params} params {total_numel} elements") + + +def _get_fp32_state_dict_from_zero2_checkpoint(world_size, fp32_flat_groups, zero_model_states, + exclude_frozen_parameters): + state_dict = OrderedDict() + + # buffers + buffers = zero_model_states[0].buffers + state_dict.update(buffers) + if debug: + print(f"added {len(buffers)} buffers") + + if not exclude_frozen_parameters: + _zero2_merge_frozen_params(state_dict, zero_model_states) + + _zero2_merge_trainable_params(state_dict, world_size, fp32_flat_groups, zero_model_states) + + # recover shared parameters + for pair in zero_model_states[0].shared_params: + if pair[1] in state_dict: + state_dict[pair[0]] = state_dict[pair[1]] + + return state_dict + + +def zero3_partitioned_param_info(unpartitioned_numel, world_size): + remainder = unpartitioned_numel % world_size + padding_numel = (world_size - remainder) if remainder else 0 + partitioned_numel = math.ceil(unpartitioned_numel / world_size) + return partitioned_numel, padding_numel + + +def _zero3_merge_frozen_params(state_dict, world_size, zero_model_states): + if zero_model_states[0].frozen_param_shapes is None or len(zero_model_states[0].frozen_param_shapes) == 0: + return + + if debug: + for i in range(world_size): + num_elem = sum(s.numel() for s in zero_model_states[i].frozen_param_fragments.values()) + print(f'rank {i}: {FROZEN_PARAM_SHAPES}.numel = {num_elem}') + + frozen_param_shapes = zero_model_states[0].frozen_param_shapes + wanted_params = len(frozen_param_shapes) + wanted_numel = sum(s.numel() for s in frozen_param_shapes.values()) + avail_numel = sum([p.numel() for p in zero_model_states[0].frozen_param_fragments.values()]) * world_size + print(f'Frozen params: Have {avail_numel} numels to process.') + print(f'Frozen params: Need {wanted_numel} numels in {wanted_params} params') + + total_params = 0 + total_numel = 0 + for name, shape in zero_model_states[0].frozen_param_shapes.items(): + total_params += 1 + unpartitioned_numel = shape.numel() + total_numel += unpartitioned_numel + + param_frags = tuple(model_state.frozen_param_fragments[name] for model_state in zero_model_states) + state_dict[name] = torch.cat(param_frags, 0).narrow(0, 0, unpartitioned_numel).view(shape) + + partitioned_numel, partitioned_padding_numel = zero3_partitioned_param_info(unpartitioned_numel, world_size) + + if debug: + print( + f"Frozen params: {total_params} {name} full shape: {shape} partition0 numel={partitioned_numel} partitioned_padding_numel={partitioned_padding_numel}" + ) + + print(f"Reconstructed Frozen fp32 state dict with {total_params} params {total_numel} elements") + + +class GatheredTensor: + """ + A pseudo tensor that collects partitioned weights. + It is more memory efficient when there are multiple groups. + """ + + def __init__(self, flat_groups, flat_groups_offset, offset, partitioned_numel, shape): + self.flat_groups = flat_groups + self.flat_groups_offset = flat_groups_offset + self.offset = offset + self.partitioned_numel = partitioned_numel + self.shape = shape + self.dtype = self.flat_groups[0][0].dtype + + def contiguous(self): + """ + Merge partitioned weights from flat_groups into a single tensor. + """ + end_idx = self.offset + self.partitioned_numel + world_size = len(self.flat_groups) + pad_flat_param_chunks = [] + + for rank_i in range(world_size): + # for each rank, we need to collect weights from related group/groups + flat_groups_at_rank_i = self.flat_groups[rank_i] + start_group_id = None + end_group_id = None + for group_id in range(len(self.flat_groups_offset)): + if self.flat_groups_offset[group_id] <= self.offset < self.flat_groups_offset[group_id + 1]: + start_group_id = group_id + if self.flat_groups_offset[group_id] < end_idx <= self.flat_groups_offset[group_id + 1]: + end_group_id = group_id + break + # collect weights from related group/groups + for group_id in range(start_group_id, end_group_id + 1): + flat_tensor = flat_groups_at_rank_i[group_id] + start_offset = self.offset - self.flat_groups_offset[group_id] + end_offset = min(end_idx, self.flat_groups_offset[group_id + 1]) - self.flat_groups_offset[group_id] + pad_flat_param_chunks.append(flat_tensor[start_offset:end_offset]) + + # collect weights from all ranks + pad_flat_param = torch.cat(pad_flat_param_chunks, dim=0) + param = pad_flat_param[:self.shape.numel()].view(self.shape).contiguous() + return param + + +def _zero3_merge_trainable_params(state_dict, world_size, fp32_flat_groups, zero_model_states): + param_shapes = zero_model_states[0].param_shapes + avail_numel = sum([flat_group.numel() for flat_group in fp32_flat_groups[0]]) * world_size + + # Reconstruction protocol: For zero3 we need to zip the partitions together at boundary of each + # param, re-consolidating each param, while dealing with padding if any + + # merge list of dicts, preserving order + param_shapes = {k: v for d in param_shapes for k, v in d.items()} + + if debug: + for i in range(world_size): + print(f"{FP32_FLAT_GROUPS}[{i}].shape={fp32_flat_groups[i].shape}") + + wanted_params = len(param_shapes) + wanted_numel = sum(shape.numel() for shape in param_shapes.values()) + # not asserting if there is a mismatch due to possible padding + avail_numel = fp32_flat_groups[0].numel() * world_size + print(f"Trainable params: Have {avail_numel} numels to process.") + print(f"Trainable params: Need {wanted_numel} numels in {wanted_params} params.") + + # params + # XXX: for huge models that can't fit into the host's RAM we will have to recode this to support + # out-of-core computing solution + offset = 0 + total_numel = 0 + total_params = 0 + flat_groups_offset = [0] + list(np.cumsum([flat_tensor.numel() for flat_tensor in fp32_flat_groups[0]])) + for name, shape in tqdm(param_shapes.items(), desc='Gathering sharded weights'): + unpartitioned_numel = shape.numel() + total_numel += unpartitioned_numel + total_params += 1 + partitioned_numel, partitioned_padding_numel = zero3_partitioned_param_info(unpartitioned_numel, world_size) + + if debug: + print( + f"Trainable params: {total_params} {name} full shape: {shape} partition0 numel={partitioned_numel} partitioned_padding_numel={partitioned_padding_numel}" + ) + + # memory efficient tensor + tensor = GatheredTensor(fp32_flat_groups, flat_groups_offset, offset, partitioned_numel, shape) + state_dict[name] = tensor + offset += partitioned_numel + + offset *= world_size + + # Sanity check + if offset != avail_numel: + raise ValueError(f"consumed {offset} numels out of {avail_numel} - something is wrong") + + print(f"Reconstructed Trainable fp32 state dict with {total_params} params {total_numel} elements") + + +def _get_fp32_state_dict_from_zero3_checkpoint(world_size, fp32_flat_groups, zero_model_states, + exclude_frozen_parameters): + state_dict = OrderedDict() + + # buffers + buffers = zero_model_states[0].buffers + state_dict.update(buffers) + if debug: + print(f"added {len(buffers)} buffers") + + if not exclude_frozen_parameters: + _zero3_merge_frozen_params(state_dict, world_size, zero_model_states) + + _zero3_merge_trainable_params(state_dict, world_size, fp32_flat_groups, zero_model_states) + + # recover shared parameters + for pair in zero_model_states[0].shared_params: + if pair[1] in state_dict: + state_dict[pair[0]] = state_dict[pair[1]] + + return state_dict + + +def to_torch_tensor(state_dict, return_empty_tensor=False): + """ + Convert state_dict of GatheredTensor to torch tensor + """ + torch_state_dict = {} + converted_tensors = {} + for name, tensor in state_dict.items(): + tensor_id = id(tensor) + if tensor_id in converted_tensors: # shared tensors + shared_tensor = torch_state_dict[converted_tensors[tensor_id]] + torch_state_dict[name] = shared_tensor + else: + converted_tensors[tensor_id] = name + if return_empty_tensor: + torch_state_dict[name] = torch.empty(tensor.shape, dtype=tensor.dtype) + else: + torch_state_dict[name] = tensor.contiguous() + return torch_state_dict + + +def get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir, + tag=None, + exclude_frozen_parameters=False, + lazy_mode=False): + """ + Convert ZeRO 2 or 3 checkpoint into a single fp32 consolidated state_dict that can be loaded with + ``load_state_dict()`` and used for training without DeepSpeed or shared with others, for example + via a model hub. + + Args: + - ``checkpoint_dir``: path to the desired checkpoint folder + - ``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`` + - ``exclude_frozen_parameters``: exclude frozen parameters + - ``lazy_mode``: get state_dict in lazy mode. It returns a dict of pesduo tensor instead of torch tensor, which is more memory efficient. + Convert the pesduo tensor to torch tensor by ``.contiguous()`` + + Returns: + - pytorch ``state_dict`` + + A typical usage might be :: + + from deepspeed.utils.zero_to_fp32 import get_fp32_state_dict_from_zero_checkpoint + # do the training and checkpoint saving + state_dict = get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir) # already on cpu + model = model.cpu() # move to cpu + model.load_state_dict(state_dict) + # submit to model hub or save the model to share with others + + In this example the ``model`` will no longer be usable in the deepspeed context of the same + application. i.e. you will need to re-initialize the deepspeed engine, since + ``model.load_state_dict(state_dict)`` will remove all the deepspeed magic from it. + + If you want it all done for you, use ``load_state_dict_from_zero_checkpoint`` instead. + + Note: the above usage may not work if your application doesn't have sufficient free CPU memory. + You may need to use the offline approach using the ``zero_to_fp32.py`` script that is saved with + the checkpoint. Or you can load state_dict in lazy mode :: + + from deepspeed.utils.zero_to_fp32 import get_fp32_state_dict_from_zero_checkpoint + state_dict = get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir, lazy_mode=True) # not on cpu + for name, lazy_tensor in state_dict.item(): + tensor = lazy_tensor.contiguous() # to cpu + print(name, tensor) + # del tensor to release memory if it no longer in use + """ + if tag is None: + latest_path = os.path.join(checkpoint_dir, 'latest') + if os.path.isfile(latest_path): + with open(latest_path, 'r') as fd: + tag = fd.read().strip() + else: + raise ValueError(f"Unable to find 'latest' file at {latest_path}") + + ds_checkpoint_dir = os.path.join(checkpoint_dir, tag) + + if not os.path.isdir(ds_checkpoint_dir): + raise FileNotFoundError(f"Directory '{ds_checkpoint_dir}' doesn't exist") + + state_dict = _get_fp32_state_dict_from_zero_checkpoint(ds_checkpoint_dir, exclude_frozen_parameters) + if lazy_mode: + return state_dict + else: + return to_torch_tensor(state_dict) + + +def convert_zero_checkpoint_to_fp32_state_dict(checkpoint_dir, + output_dir, + max_shard_size="5GB", + safe_serialization=False, + tag=None, + exclude_frozen_parameters=False): + """ + Convert ZeRO 2 or 3 checkpoint into a single fp32 consolidated ``state_dict`` file that can be + loaded with ``torch.load(file)`` + ``load_state_dict()`` and used for training without DeepSpeed. + + Args: + - ``checkpoint_dir``: path to the desired checkpoint folder. (one that contains the tag-folder, like ``global_step14``) + - ``output_dir``: directory to the pytorch fp32 state_dict output files + - ``max_shard_size``: the maximum size for a checkpoint before being sharded, default value is 5GB + - ``safe_serialization``: whether to save the model using `safetensors` or the traditional PyTorch way (that uses `pickle`). + - ``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`` + - ``exclude_frozen_parameters``: exclude frozen parameters + """ + + # Dependency pre-check + if safe_serialization: + try: + from safetensors.torch import save_file + except ImportError: + print('If you want to use `safe_serialization`, please `pip install safetensors`') + raise + if max_shard_size is not None: + try: + from huggingface_hub import split_torch_state_dict_into_shards + except ImportError: + print('If you want to use `max_shard_size`, please `pip install huggingface_hub`') + raise + + # Convert zero checkpoint to state_dict + state_dict = get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir, + tag, + exclude_frozen_parameters, + lazy_mode=True) + + # Shard the model if it is too big. + weights_name = "model.safetensors" if safe_serialization else "pytorch_model.bin" + if max_shard_size is not None: + filename_pattern = weights_name.replace(".bin", "{suffix}.bin").replace(".safetensors", "{suffix}.safetensors") + # an memory-efficient approach for sharding + empty_state_dict = to_torch_tensor(state_dict, return_empty_tensor=True) + state_dict_split = split_torch_state_dict_into_shards(empty_state_dict, + filename_pattern=filename_pattern, + max_shard_size=max_shard_size) + else: + from collections import namedtuple + StateDictSplit = namedtuple("StateDictSplit", ["is_sharded", "filename_to_tensors"]) + state_dict_split = StateDictSplit(is_sharded=False, + filename_to_tensors={weights_name: list(state_dict.keys())}) + + # Save the model by shard + os.makedirs(output_dir, exist_ok=True) + filename_to_tensors = state_dict_split.filename_to_tensors.items() + for shard_file, tensors in tqdm(filename_to_tensors, desc="Saving checkpoint shards"): + shard_state_dict = {tensor_name: state_dict[tensor_name] for tensor_name in tensors} + shard_state_dict = to_torch_tensor(shard_state_dict) + output_path = os.path.join(output_dir, shard_file) + if safe_serialization: + save_file(shard_state_dict, output_path, metadata={"format": "pt"}) + else: + torch.save(shard_state_dict, output_path) + # release the memory of current shard + for tensor_name in list(shard_state_dict.keys()): + del state_dict[tensor_name] + del shard_state_dict[tensor_name] + del shard_state_dict + gc.collect() + + # Save index if sharded + if state_dict_split.is_sharded: + index = { + "metadata": state_dict_split.metadata, + "weight_map": state_dict_split.tensor_to_filename, + } + save_index_file = "model.safetensors.index.json" if safe_serialization else "pytorch_model.bin.index.json" + save_index_file = os.path.join(output_dir, save_index_file) + with open(save_index_file, "w", encoding="utf-8") as f: + content = json.dumps(index, indent=2, sort_keys=True) + "\n" + f.write(content) + + +def load_state_dict_from_zero_checkpoint(model, checkpoint_dir, tag=None): + """ + 1. Put the provided model to cpu + 2. Convert ZeRO 2 or 3 checkpoint into a single fp32 consolidated ``state_dict`` + 3. Load it into the provided model + + Args: + - ``model``: the model object to update + - ``checkpoint_dir``: path to the desired checkpoint folder. (one that contains the tag-folder, like ``global_step14``) + - ``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`` + + Returns: + - ``model`: modified model + + Make sure you have plenty of CPU memory available before you call this function. If you don't + have enough use the ``zero_to_fp32.py`` utility to do the conversion. You will find it + conveniently placed for you in the checkpoint folder. + + A typical usage might be :: + + from deepspeed.utils.zero_to_fp32 import load_state_dict_from_zero_checkpoint + model = load_state_dict_from_zero_checkpoint(trainer.model, checkpoint_dir) + # submit to model hub or save the model to share with others + + Note, that once this was run, the ``model`` will no longer be usable in the deepspeed context + of the same application. i.e. you will need to re-initialize the deepspeed engine, since + ``model.load_state_dict(state_dict)`` will remove all the deepspeed magic from it. + + """ + logger.info("Extracting fp32 weights") + state_dict = get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir, tag) + + logger.info("Overwriting model with fp32 weights") + model = model.cpu() + model.load_state_dict(state_dict, strict=False) + + return model + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument("checkpoint_dir", + type=str, + help="path to the desired checkpoint folder, e.g., path/checkpoint-12") + parser.add_argument("output_dir", + type=str, + help="directory to the pytorch fp32 state_dict output files" + "(e.g. path/checkpoint-12-output/)") + parser.add_argument( + "--max_shard_size", + type=str, + default="5GB", + help="The maximum size for a checkpoint before being sharded. Checkpoints shard will then be each of size" + "lower than this size. If expressed as a string, needs to be digits followed by a unit (like `5MB`" + "We default it to 5GB in order for models to be able to run easily on free-tier google colab instances" + "without CPU OOM issues.") + parser.add_argument( + "--safe_serialization", + default=False, + action='store_true', + help="Whether to save the model using `safetensors` or the traditional PyTorch way (that uses `pickle`).") + parser.add_argument("-t", + "--tag", + type=str, + default=None, + help="checkpoint tag used as a unique identifier for checkpoint. e.g., global_step1") + parser.add_argument("--exclude_frozen_parameters", action='store_true', help="exclude frozen parameters") + parser.add_argument("-d", "--debug", action='store_true', help="enable debug") + args = parser.parse_args() + + debug = args.debug + + convert_zero_checkpoint_to_fp32_state_dict(args.checkpoint_dir, + args.output_dir, + max_shard_size=args.max_shard_size, + safe_serialization=args.safe_serialization, + tag=args.tag, + exclude_frozen_parameters=args.exclude_frozen_parameters) diff --git a/qwen3/csd/eval_results.json b/qwen3/csd/eval_results.json new file mode 100644 index 0000000000000000000000000000000000000000..112d25829a87ac1815d231290e097df398cdcd0d --- /dev/null +++ b/qwen3/csd/eval_results.json @@ -0,0 +1,14 @@ +{ + "epoch": 5.0, + "eval_generator_count": 1712.0, + "eval_generator_exact_match": 96.6121, + "eval_generator_rouge1": 99.9371, + "eval_generator_rouge2": 99.8891, + "eval_generator_rougeL": 99.7571, + "eval_loss": 0.00408697547391057, + "eval_runtime": 585.4618, + "eval_samples_per_second": 5.831, + "eval_selector_accuracy": 98.5981, + "eval_selector_count": 1712.0, + "eval_steps_per_second": 0.183 +} \ No newline at end of file diff --git a/qwen3/csd/tokenizer.json b/qwen3/csd/tokenizer.json new file mode 100644 index 0000000000000000000000000000000000000000..c7afbed2efcdf019f88ab0572ec29d3bf595dfe2 --- /dev/null +++ b/qwen3/csd/tokenizer.json @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:be75606093db2094d7cd20f3c2f385c212750648bd6ea4fb2bf507a6a4c55506 +size 11422650 diff --git a/qwen3/csd/tokenizer_config.json b/qwen3/csd/tokenizer_config.json new file mode 100644 index 0000000000000000000000000000000000000000..6623da03457d79d2cd4af9557e9f31407cdb835c --- /dev/null +++ b/qwen3/csd/tokenizer_config.json @@ -0,0 +1,31 @@ +{ + "add_prefix_space": false, + "backend": "tokenizers", + "bos_token": null, + "clean_up_tokenization_spaces": false, + "eos_token": "<|im_end|>", + "errors": "replace", + "extra_special_tokens": [ + "<|im_start|>", + "<|im_end|>", + "<|object_ref_start|>", + "<|object_ref_end|>", + "<|box_start|>", + "<|box_end|>", + "<|quad_start|>", + "<|quad_end|>", + "<|vision_start|>", + "<|vision_end|>", + "<|vision_pad|>", + "<|image_pad|>", + "<|video_pad|>" + ], + "is_local": false, + "local_files_only": false, + "model_max_length": 131072, + "pad_token": "<|endoftext|>", + "padding_side": "right", + "split_special_tokens": false, + "tokenizer_class": "Qwen2Tokenizer", + "unk_token": null +} diff --git a/qwen3/csd/train_results.json b/qwen3/csd/train_results.json new file mode 100644 index 0000000000000000000000000000000000000000..c3a68d3096d434cf6cb3f07aa92a7d532179dc95 --- /dev/null +++ b/qwen3/csd/train_results.json @@ -0,0 +1,8 @@ +{ + "epoch": 5.0, + "total_flos": 5.871444840310374e+16, + "train_loss": -0.013058029026516779, + "train_runtime": 7965.6329, + "train_samples_per_second": 6.294, + "train_steps_per_second": 0.197 +} \ No newline at end of file diff --git a/qwen3/csd/trainer_state.json b/qwen3/csd/trainer_state.json new file mode 100644 index 0000000000000000000000000000000000000000..955f43064efc44d4f8660d3bba16953130447406 --- /dev/null +++ b/qwen3/csd/trainer_state.json @@ -0,0 +1,664 @@ +{ + "best_global_step": null, + "best_metric": null, + "best_model_checkpoint": null, + "epoch": 5.0, + "eval_steps": 500, + "global_step": 1570, + "is_hyper_param_search": false, + "is_local_process_zero": true, + "is_world_process_zero": true, + "log_history": [ + { + "epoch": 0.06382130035899482, + "grad_norm": 6.0161848068237305, + "learning_rate": 9.996390385474569e-05, + "loss": 0.11036398410797119, + "step": 20 + }, + { + "epoch": 0.12764260071798963, + "grad_norm": 4.099686622619629, + "learning_rate": 9.984797509888031e-05, + "loss": 0.01695394217967987, + "step": 40 + }, + { + "epoch": 0.19146390107698444, + "grad_norm": 3.3755345344543457, + "learning_rate": 9.965229938050925e-05, + "loss": 0.03482693731784821, + "step": 60 + }, + { + "epoch": 0.25528520143597927, + "grad_norm": 1.194334864616394, + "learning_rate": 9.937719005663432e-05, + "loss": 0.027955988049507143, + "step": 80 + }, + { + "epoch": 0.3191065017949741, + "grad_norm": 6.6159281730651855, + "learning_rate": 9.902308769000724e-05, + "loss": 0.005286623537540436, + "step": 100 + }, + { + "epoch": 0.3829278021539689, + "grad_norm": 2.851339817047119, + "learning_rate": 9.859055934360789e-05, + "loss": 0.01179061084985733, + "step": 120 + }, + { + "epoch": 0.4467491025129637, + "grad_norm": 0.989425539970398, + "learning_rate": 9.808029767254437e-05, + "loss": 0.006131124496459961, + "step": 140 + }, + { + "epoch": 0.5105704028719585, + "grad_norm": 1.3493149280548096, + "learning_rate": 9.749311981482817e-05, + "loss": 0.007052437216043472, + "step": 160 + }, + { + "epoch": 0.5743917032309533, + "grad_norm": 0.9337753057479858, + "learning_rate": 9.682996608280154e-05, + "loss": -0.002346178889274597, + "step": 180 + }, + { + "epoch": 0.6382130035899481, + "grad_norm": 1.5435981750488281, + "learning_rate": 9.609189845731207e-05, + "loss": 0.013309524953365326, + "step": 200 + }, + { + "epoch": 0.702034303948943, + "grad_norm": 0.7995954155921936, + "learning_rate": 9.52800988870462e-05, + "loss": 0.008521870523691178, + "step": 220 + }, + { + "epoch": 0.7658556043079378, + "grad_norm": 1.6571325063705444, + "learning_rate": 9.439586739574513e-05, + "loss": 0.008653326332569123, + "step": 240 + }, + { + "epoch": 0.8296769046669326, + "grad_norm": 0.519936203956604, + "learning_rate": 9.344062000033414e-05, + "loss": 0.004485934227705002, + "step": 260 + }, + { + "epoch": 0.8934982050259274, + "grad_norm": 0.31598174571990967, + "learning_rate": 9.241588644329919e-05, + "loss": 0.003059915825724602, + "step": 280 + }, + { + "epoch": 0.9573195053849222, + "grad_norm": 0.48084524273872375, + "learning_rate": 9.132330774294252e-05, + "loss": 0.005025627836585045, + "step": 300 + }, + { + "epoch": 1.0, + "eval_generator_count": 1712.0, + "eval_generator_exact_match": 86.2734, + "eval_generator_rouge1": 99.1343, + "eval_generator_rouge2": 98.8297, + "eval_generator_rougeL": 98.6074, + "eval_loss": 0.019235465675592422, + "eval_runtime": 603.0951, + "eval_samples_per_second": 5.661, + "eval_selector_accuracy": 93.3995, + "eval_selector_count": 1712.0, + "eval_steps_per_second": 0.177, + "step": 314 + }, + { + "epoch": 1.0191463901076985, + "grad_norm": 0.34810933470726013, + "learning_rate": 9.01646335654399e-05, + "loss": 0.008805014193058014, + "step": 320 + }, + { + "epoch": 1.0829676904666932, + "grad_norm": 0.19888198375701904, + "learning_rate": 8.894171942290817e-05, + "loss": 0.0013909661211073399, + "step": 340 + }, + { + "epoch": 1.146788990825688, + "grad_norm": 1.0506941080093384, + "learning_rate": 8.765652370197003e-05, + "loss": 0.0005901294760406017, + "step": 360 + }, + { + "epoch": 1.210610291184683, + "grad_norm": 2.363455057144165, + "learning_rate": 8.631110452757467e-05, + "loss": -0.0003092627972364426, + "step": 380 + }, + { + "epoch": 1.2744315915436777, + "grad_norm": 0.0766368880867958, + "learning_rate": 8.490761646709642e-05, + "loss": -0.002663038857281208, + "step": 400 + }, + { + "epoch": 1.3382528919026724, + "grad_norm": 0.1551397442817688, + "learning_rate": 8.344830707998953e-05, + "loss": 0.0026730677112936974, + "step": 420 + }, + { + "epoch": 1.4020741922616673, + "grad_norm": 0.7773767113685608, + "learning_rate": 8.193551331852458e-05, + "loss": -0.0011709232814610005, + "step": 440 + }, + { + "epoch": 1.4658954926206622, + "grad_norm": 0.42017874121665955, + "learning_rate": 8.037165778537033e-05, + "loss": -0.0019059792160987855, + "step": 460 + }, + { + "epoch": 1.5297167929796571, + "grad_norm": 1.0544211864471436, + "learning_rate": 7.875924485401427e-05, + "loss": -0.004772515594959259, + "step": 480 + }, + { + "epoch": 1.5935380933386518, + "grad_norm": 0.4706478416919708, + "learning_rate": 7.710085665823444e-05, + "loss": -0.0002438830444589257, + "step": 500 + }, + { + "epoch": 1.6573593936976465, + "grad_norm": 0.22088219225406647, + "learning_rate": 7.539914895704521e-05, + "loss": -0.004391691088676453, + "step": 520 + }, + { + "epoch": 1.7211806940566414, + "grad_norm": 0.5972660183906555, + "learning_rate": 7.365684688173908e-05, + "loss": -0.007541544735431671, + "step": 540 + }, + { + "epoch": 1.7850019944156363, + "grad_norm": 0.19400978088378906, + "learning_rate": 7.18767405718347e-05, + "loss": -0.004146666824817657, + "step": 560 + }, + { + "epoch": 1.848823294774631, + "grad_norm": 1.2469046115875244, + "learning_rate": 7.006168070692036e-05, + "loss": -0.0019529350101947784, + "step": 580 + }, + { + "epoch": 1.9126445951336257, + "grad_norm": 0.14316241443157196, + "learning_rate": 6.821457394154786e-05, + "loss": -0.008291246742010117, + "step": 600 + }, + { + "epoch": 1.9764658954926206, + "grad_norm": 0.4657886326313019, + "learning_rate": 6.633837825048768e-05, + "loss": -0.006107022240757942, + "step": 620 + }, + { + "epoch": 2.0, + "eval_generator_count": 1712.0, + "eval_generator_exact_match": 94.6846, + "eval_generator_rouge1": 99.7652, + "eval_generator_rouge2": 99.667, + "eval_generator_rougeL": 99.5471, + "eval_loss": 0.006834100466221571, + "eval_runtime": 601.0294, + "eval_samples_per_second": 5.68, + "eval_selector_accuracy": 97.8388, + "eval_selector_count": 1712.0, + "eval_steps_per_second": 0.178, + "step": 628 + }, + { + "epoch": 2.038292780215397, + "grad_norm": 0.22094473242759705, + "learning_rate": 6.443609819179926e-05, + "loss": -0.005953450500965118, + "step": 640 + }, + { + "epoch": 2.102114080574392, + "grad_norm": 0.5406356453895569, + "learning_rate": 6.251078009530256e-05, + "loss": -0.0025423141196370125, + "step": 660 + }, + { + "epoch": 2.1659353809333863, + "grad_norm": 0.09373176842927933, + "learning_rate": 6.0565507184155677e-05, + "loss": -0.0044939789921045305, + "step": 680 + }, + { + "epoch": 2.2297566812923812, + "grad_norm": 0.1080167219042778, + "learning_rate": 5.860339463735136e-05, + "loss": -0.00820673182606697, + "step": 700 + }, + { + "epoch": 2.293577981651376, + "grad_norm": 0.05399267002940178, + "learning_rate": 5.662758460103895e-05, + "loss": -0.009635555744171142, + "step": 720 + }, + { + "epoch": 2.357399282010371, + "grad_norm": 0.2048628032207489, + "learning_rate": 5.464124115666095e-05, + "loss": -0.010086850821971893, + "step": 740 + }, + { + "epoch": 2.421220582369366, + "grad_norm": 0.08765007555484772, + "learning_rate": 5.264754525396212e-05, + "loss": -0.008542184531688691, + "step": 760 + }, + { + "epoch": 2.4850418827283605, + "grad_norm": 0.2229253351688385, + "learning_rate": 5.06496896169857e-05, + "loss": -0.011658547818660736, + "step": 780 + }, + { + "epoch": 2.5488631830873554, + "grad_norm": 0.18513049185276031, + "learning_rate": 4.865087363121384e-05, + "loss": -0.00930779054760933, + "step": 800 + }, + { + "epoch": 2.6126844834463503, + "grad_norm": 0.3498702347278595, + "learning_rate": 4.6654298220040673e-05, + "loss": -0.014870831370353698, + "step": 820 + }, + { + "epoch": 2.6765057838053448, + "grad_norm": 0.16160713136196136, + "learning_rate": 4.466316071878229e-05, + "loss": -0.020250825583934783, + "step": 840 + }, + { + "epoch": 2.74032708416434, + "grad_norm": 0.16046860814094543, + "learning_rate": 4.2680649754432913e-05, + "loss": -0.018617722392082214, + "step": 860 + }, + { + "epoch": 2.8041483845233346, + "grad_norm": 0.17135752737522125, + "learning_rate": 4.070994013936646e-05, + "loss": -0.020963044464588167, + "step": 880 + }, + { + "epoch": 2.8679696848823295, + "grad_norm": 0.24867695569992065, + "learning_rate": 3.8754187787161155e-05, + "loss": -0.020418259501457214, + "step": 900 + }, + { + "epoch": 2.9317909852413244, + "grad_norm": 0.12315966188907623, + "learning_rate": 3.681652465868875e-05, + "loss": -0.018548570573329926, + "step": 920 + }, + { + "epoch": 2.995612285600319, + "grad_norm": 0.14333273470401764, + "learning_rate": 3.490005374656184e-05, + "loss": -0.018815448880195616, + "step": 940 + }, + { + "epoch": 3.0, + "eval_generator_count": 1712.0, + "eval_generator_exact_match": 95.736, + "eval_generator_rouge1": 99.9465, + "eval_generator_rouge2": 99.8866, + "eval_generator_rougeL": 99.7132, + "eval_loss": 0.005336109548807144, + "eval_runtime": 608.1178, + "eval_samples_per_second": 5.614, + "eval_selector_accuracy": 97.722, + "eval_selector_count": 1712.0, + "eval_steps_per_second": 0.176, + "step": 942 + }, + { + "epoch": 3.057439170323095, + "grad_norm": 0.1492357701063156, + "learning_rate": 3.3007844105971336e-05, + "loss": -0.02238200604915619, + "step": 960 + }, + { + "epoch": 3.12126047068209, + "grad_norm": 0.0778684988617897, + "learning_rate": 3.114292593987149e-05, + "loss": -0.02527567744255066, + "step": 980 + }, + { + "epoch": 3.185081771041085, + "grad_norm": 0.07070758193731308, + "learning_rate": 2.9308285746383408e-05, + "loss": -0.02356054335832596, + "step": 1000 + }, + { + "epoch": 3.24890307140008, + "grad_norm": 0.10038785636425018, + "learning_rate": 2.7506861536187867e-05, + "loss": -0.019069214165210725, + "step": 1020 + }, + { + "epoch": 3.3127243717590744, + "grad_norm": 0.33050113916397095, + "learning_rate": 2.5741538127566396e-05, + "loss": -0.022282478213310242, + "step": 1040 + }, + { + "epoch": 3.3765456721180693, + "grad_norm": 0.12148360908031464, + "learning_rate": 2.4015142526625115e-05, + "loss": -0.02368807643651962, + "step": 1060 + }, + { + "epoch": 3.4403669724770642, + "grad_norm": 0.16367903351783752, + "learning_rate": 2.233043940009967e-05, + "loss": -0.02528309226036072, + "step": 1080 + }, + { + "epoch": 3.504188272836059, + "grad_norm": 0.0877315029501915, + "learning_rate": 2.0690126647990974e-05, + "loss": -0.026697894930839537, + "step": 1100 + }, + { + "epoch": 3.568009573195054, + "grad_norm": 0.06676916033029556, + "learning_rate": 1.9096831083121828e-05, + "loss": -0.028009063005447386, + "step": 1120 + }, + { + "epoch": 3.6318308735540485, + "grad_norm": 0.09503277391195297, + "learning_rate": 1.7553104224533324e-05, + "loss": -0.0323164701461792, + "step": 1140 + }, + { + "epoch": 3.6956521739130435, + "grad_norm": 0.08010950684547424, + "learning_rate": 1.606141821145735e-05, + "loss": -0.03129267990589142, + "step": 1160 + }, + { + "epoch": 3.7594734742720384, + "grad_norm": 0.15882308781147003, + "learning_rate": 1.4624161844408763e-05, + "loss": -0.03188144564628601, + "step": 1180 + }, + { + "epoch": 3.823294774631033, + "grad_norm": 0.07064881920814514, + "learning_rate": 1.324363675973698e-05, + "loss": -0.03279578983783722, + "step": 1200 + }, + { + "epoch": 3.8871160749900278, + "grad_norm": 0.24478258192539215, + "learning_rate": 1.1922053743763052e-05, + "loss": -0.03418469429016113, + "step": 1220 + }, + { + "epoch": 3.9509373753490227, + "grad_norm": 0.09533516317605972, + "learning_rate": 1.0661529192404973e-05, + "loss": -0.036141425371170044, + "step": 1240 + }, + { + "epoch": 4.0, + "eval_generator_count": 1712.0, + "eval_generator_exact_match": 96.2617, + "eval_generator_rouge1": 99.8812, + "eval_generator_rouge2": 99.8259, + "eval_generator_rougeL": 99.6849, + "eval_loss": 0.0041860658675432205, + "eval_runtime": 606.5994, + "eval_samples_per_second": 5.628, + "eval_selector_accuracy": 98.3645, + "eval_selector_count": 1712.0, + "eval_steps_per_second": 0.176, + "step": 1256 + }, + { + "epoch": 4.0127642600717985, + "grad_norm": 0.527934730052948, + "learning_rate": 9.464081721960592e-06, + "loss": -0.034009939432144164, + "step": 1260 + }, + { + "epoch": 4.076585560430794, + "grad_norm": 0.09058220684528351, + "learning_rate": 8.331628936475818e-06, + "loss": -0.037159329652786253, + "step": 1280 + }, + { + "epoch": 4.140406860789788, + "grad_norm": 0.05895598232746124, + "learning_rate": 7.2659843568748385e-06, + "loss": -0.0379990428686142, + "step": 1300 + }, + { + "epoch": 4.204228161148784, + "grad_norm": 0.0801444798707962, + "learning_rate": 6.268854516770008e-06, + "loss": -0.03669540882110596, + "step": 1320 + }, + { + "epoch": 4.268049461507778, + "grad_norm": 0.08857632428407669, + "learning_rate": 5.341836229602331e-06, + "loss": -0.03779337704181671, + "step": 1340 + }, + { + "epoch": 4.331870761866773, + "grad_norm": 0.07376661151647568, + "learning_rate": 4.4864140314888216e-06, + "loss": -0.03757229745388031, + "step": 1360 + }, + { + "epoch": 4.395692062225768, + "grad_norm": 0.08888167142868042, + "learning_rate": 3.703957803871932e-06, + "loss": -0.03948601186275482, + "step": 1380 + }, + { + "epoch": 4.4595133625847625, + "grad_norm": 0.12080858647823334, + "learning_rate": 2.9957205797780495e-06, + "loss": -0.039844200015068054, + "step": 1400 + }, + { + "epoch": 4.523334662943758, + "grad_norm": 0.16051147878170013, + "learning_rate": 2.362836537198199e-06, + "loss": -0.0381706565618515, + "step": 1420 + }, + { + "epoch": 4.587155963302752, + "grad_norm": 0.06491488963365555, + "learning_rate": 1.8063191828043703e-06, + "loss": -0.04070441722869873, + "step": 1440 + }, + { + "epoch": 4.650977263661747, + "grad_norm": 0.10599425435066223, + "learning_rate": 1.3270597289100437e-06, + "loss": -0.03966156244277954, + "step": 1460 + }, + { + "epoch": 4.714798564020742, + "grad_norm": 0.07826361805200577, + "learning_rate": 9.258256662741205e-07, + "loss": -0.040459868311882016, + "step": 1480 + }, + { + "epoch": 4.778619864379737, + "grad_norm": 0.1433020979166031, + "learning_rate": 6.032595350337341e-07, + "loss": -0.04145862460136414, + "step": 1500 + }, + { + "epoch": 4.842441164738732, + "grad_norm": 0.1149950921535492, + "learning_rate": 3.5987789573421356e-07, + "loss": -0.03695116639137268, + "step": 1520 + }, + { + "epoch": 4.9062624650977265, + "grad_norm": 0.15655829012393951, + "learning_rate": 1.9607050210401192e-07, + "loss": -0.03868899643421173, + "step": 1540 + }, + { + "epoch": 4.970083765456721, + "grad_norm": 0.1153496727347374, + "learning_rate": 1.1209967689925832e-07, + "loss": -0.04158148169517517, + "step": 1560 + }, + { + "epoch": 5.0, + "eval_generator_count": 1712.0, + "eval_generator_exact_match": 96.6706, + "eval_generator_rouge1": 99.9491, + "eval_generator_rouge2": 99.8942, + "eval_generator_rougeL": 99.7857, + "eval_loss": 0.00408697547391057, + "eval_runtime": 602.4809, + "eval_samples_per_second": 5.667, + "eval_selector_accuracy": 98.6565, + "eval_selector_count": 1712.0, + "eval_steps_per_second": 0.178, + "step": 1570 + }, + { + "epoch": 5.0, + "step": 1570, + "total_flos": 5.871444840310374e+16, + "train_loss": -0.013058029026516779, + "train_runtime": 7965.6329, + "train_samples_per_second": 6.294, + "train_steps_per_second": 0.197 + } + ], + "logging_steps": 20, + "max_steps": 1570, + "num_input_tokens_seen": 0, + "num_train_epochs": 5, + "save_steps": 500, + "stateful_callbacks": { + "TrainerControl": { + "args": { + "should_epoch_stop": false, + "should_evaluate": false, + "should_log": false, + "should_save": true, + "should_training_stop": true + }, + "attributes": {} + } + }, + "total_flos": 5.871444840310374e+16, + "train_batch_size": 2, + "trial_name": null, + "trial_params": null +} diff --git a/qwen3/csd/training_args.bin b/qwen3/csd/training_args.bin new file mode 100644 index 0000000000000000000000000000000000000000..4b4d426a661bf64c99e9ff7730557b24ebf0e60c --- /dev/null +++ b/qwen3/csd/training_args.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:83e0687327fbf0a1cbac0cde783b20e396ed970bb1eed13dcf33e672089c5f44 +size 7185 diff --git a/qwen3/distillm_adaptive_sfkl/README.md b/qwen3/distillm_adaptive_sfkl/README.md new file mode 100644 index 0000000000000000000000000000000000000000..112a32962ddbbc571ea4b0e02cc7e2527c21da68 --- /dev/null +++ b/qwen3/distillm_adaptive_sfkl/README.md @@ -0,0 +1,79 @@ +--- +library_name: peft +license: other +base_model: Qwen/Qwen3-0.6B +tags: +- base_model:adapter:Qwen/Qwen3-0.6B +- llama-factory +- lora +- transformers +pipeline_tag: text-generation +model-index: +- name: distillm_adaptive_sfkl + results: [] +--- + + + +# distillm_adaptive_sfkl + +This model is a fine-tuned version of [Qwen/Qwen3-0.6B](https://huggingface.co/Qwen/Qwen3-0.6B) on the cypher_prepared_train dataset. +It achieves the following results on the evaluation set: +- Loss: 0.0032 +- Selector Count: 1712.0 +- Generator Count: 1712.0 +- Selector Accuracy: 98.715 +- Generator Exact Match: 96.3785 +- Generator Rouge1: 99.9305 +- Generator Rouge2: 99.8682 +- Generator Rougel: 99.7529 + +## Model description + +More information needed + +## Intended uses & limitations + +More information needed + +## Training and evaluation data + +More information needed + +## Training procedure + +### Training hyperparameters + +The following hyperparameters were used during training: +- learning_rate: 0.0001 +- train_batch_size: 2 +- eval_batch_size: 16 +- seed: 42 +- distributed_type: multi-GPU +- num_devices: 2 +- gradient_accumulation_steps: 8 +- total_train_batch_size: 32 +- total_eval_batch_size: 32 +- optimizer: Use OptimizerNames.ADAMW_TORCH with betas=(0.9,0.999) and epsilon=1e-08 and optimizer_args=No additional optimizer arguments +- lr_scheduler_type: cosine_with_min_lr +- num_epochs: 5 + +### Training results + +| Training Loss | Epoch | Step | Validation Loss | Selector Count | Generator Count | Selector Accuracy | Generator Exact Match | Generator Rouge1 | Generator Rouge2 | Generator Rougel | +|:-------------:|:-----:|:----:|:---------------:|:--------------:|:---------------:|:-----------------:|:---------------------:|:----------------:|:----------------:|:----------------:| +| 0.0097 | 1.0 | 314 | 0.0078 | 1712.0 | 1712.0 | 95.5607 | 90.0701 | 99.4297 | 99.1758 | 99.0503 | +| 0.0035 | 2.0 | 628 | 0.0057 | 1712.0 | 1712.0 | 97.722 | 92.9907 | 99.8109 | 99.6137 | 99.5606 | +| 0.0014 | 3.0 | 942 | 0.0040 | 1712.0 | 1712.0 | 98.0724 | 95.3271 | 99.9061 | 99.7991 | 99.6925 | +| 0.0009 | 4.0 | 1256 | 0.0032 | 1712.0 | 1712.0 | 98.5981 | 96.6706 | 99.9312 | 99.8709 | 99.7682 | +| 0.0011 | 5.0 | 1570 | 0.0032 | 1712.0 | 1712.0 | 98.7734 | 96.4953 | 99.9278 | 99.8599 | 99.777 | + + +### Framework versions + +- PEFT 0.18.1 +- Transformers 5.8.0 +- Pytorch 2.9.1+cu128 +- Datasets 4.0.0 +- Tokenizers 0.22.2 \ No newline at end of file diff --git a/qwen3/distillm_adaptive_sfkl/adapter_config.json b/qwen3/distillm_adaptive_sfkl/adapter_config.json new file mode 100644 index 0000000000000000000000000000000000000000..d88d3ddd2a1fe81f4cf32eb7f116cfcaecff483e --- /dev/null +++ b/qwen3/distillm_adaptive_sfkl/adapter_config.json @@ -0,0 +1,46 @@ +{ + "alora_invocation_tokens": null, + "alpha_pattern": {}, + "arrow_config": null, + "auto_mapping": null, + "base_model_name_or_path": "Qwen/Qwen3-0.6B", + "bias": "none", + "corda_config": null, + "ensure_weight_tying": false, + "eva_config": null, + "exclude_modules": null, + "fan_in_fan_out": false, + "inference_mode": true, + "init_lora_weights": true, + "layer_replication": null, + "layers_pattern": null, + "layers_to_transform": null, + "loftq_config": {}, + "lora_alpha": 64, + "lora_bias": false, + "lora_dropout": 0.1, + "megatron_config": null, + "megatron_core": "megatron.core", + "modules_to_save": null, + "peft_type": "LORA", + "peft_version": "0.18.1", + "qalora_group_size": 16, + "r": 32, + "rank_pattern": {}, + "revision": null, + "target_modules": [ + "gate_proj", + "o_proj", + "down_proj", + "v_proj", + "q_proj", + "up_proj", + "k_proj" + ], + "target_parameters": null, + "task_type": "CAUSAL_LM", + "trainable_token_indices": null, + "use_dora": false, + "use_qalora": false, + "use_rslora": false +} \ No newline at end of file diff --git a/qwen3/distillm_adaptive_sfkl/adapter_model.safetensors b/qwen3/distillm_adaptive_sfkl/adapter_model.safetensors new file mode 100644 index 0000000000000000000000000000000000000000..906be98e4f889370ba814eecd51b8209eb2a3815 --- /dev/null +++ b/qwen3/distillm_adaptive_sfkl/adapter_model.safetensors @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a99e7a0decfbd11795996653da7c5bc4e9262944d052503644f577fff3ab8626 +size 40422560 diff --git a/qwen3/distillm_adaptive_sfkl/all_results.json b/qwen3/distillm_adaptive_sfkl/all_results.json new file mode 100644 index 0000000000000000000000000000000000000000..b6c1608e9d66e99a3172e8a9b93ecd591af7801b --- /dev/null +++ b/qwen3/distillm_adaptive_sfkl/all_results.json @@ -0,0 +1,24 @@ +{ + "epoch": 5.0, + "eval_distillm_threshold": 0.0, + "eval_distillm_threshold_changed": 0.0, + "eval_generator_count": 1712.0, + "eval_generator_exact_match": 96.3785, + "eval_generator_rouge1": 99.9305, + "eval_generator_rouge2": 99.8682, + "eval_generator_rougeL": 99.7529, + "eval_loss": 0.003217515302821994, + "eval_rollout_dataset_steps": 12535, + "eval_rollout_fresh_steps": 0, + "eval_rollout_replay_steps": 0, + "eval_runtime": 579.9368, + "eval_samples_per_second": 5.887, + "eval_selector_accuracy": 98.715, + "eval_selector_count": 1712.0, + "eval_steps_per_second": 0.185, + "total_flos": 5.871444840310374e+16, + "train_loss": 0.011652989937051847, + "train_runtime": 11256.8941, + "train_samples_per_second": 4.454, + "train_steps_per_second": 0.139 +} \ No newline at end of file diff --git a/qwen3/distillm_adaptive_sfkl/chat_template.jinja b/qwen3/distillm_adaptive_sfkl/chat_template.jinja new file mode 100644 index 0000000000000000000000000000000000000000..01be9b307daa2d425f7c168c9fb145a286e0afb4 --- /dev/null +++ b/qwen3/distillm_adaptive_sfkl/chat_template.jinja @@ -0,0 +1,89 @@ +{%- if tools %} + {{- '<|im_start|>system\n' }} + {%- if messages[0].role == 'system' %} + {{- messages[0].content + '\n\n' }} + {%- endif %} + {{- "# Tools\n\nYou may call one or more functions to assist with the user query.\n\nYou are provided with function signatures within XML tags:\n" }} + {%- for tool in tools %} + {{- "\n" }} + {{- tool | tojson }} + {%- endfor %} + {{- "\n\n\nFor each function call, return a json object with function name and arguments within XML tags:\n\n{\"name\": , \"arguments\": }\n<|im_end|>\n" }} +{%- else %} + {%- if messages[0].role == 'system' %} + {{- '<|im_start|>system\n' + messages[0].content + '<|im_end|>\n' }} + {%- endif %} +{%- endif %} +{%- set ns = namespace(multi_step_tool=true, last_query_index=messages|length - 1) %} +{%- for message in messages[::-1] %} + {%- set index = (messages|length - 1) - loop.index0 %} + {%- if ns.multi_step_tool and message.role == "user" and message.content is string and not(message.content.startswith('') and message.content.endswith('')) %} + {%- set ns.multi_step_tool = false %} + {%- set ns.last_query_index = index %} + {%- endif %} +{%- endfor %} +{%- for message in messages %} + {%- if message.content is string %} + {%- set content = message.content %} + {%- else %} + {%- set content = '' %} + {%- endif %} + {%- if (message.role == "user") or (message.role == "system" and not loop.first) %} + {{- '<|im_start|>' + message.role + '\n' + content + '<|im_end|>' + '\n' }} + {%- elif message.role == "assistant" %} + {%- set reasoning_content = '' %} + {%- if message.reasoning_content is string %} + {%- set reasoning_content = message.reasoning_content %} + {%- else %} + {%- if '' in content %} + {%- set reasoning_content = content.split('')[0].rstrip('\n').split('')[-1].lstrip('\n') %} + {%- set content = content.split('')[-1].lstrip('\n') %} + {%- endif %} + {%- endif %} + {%- if loop.index0 > ns.last_query_index %} + {%- if loop.last or (not loop.last and reasoning_content) %} + {{- '<|im_start|>' + message.role + '\n\n' + reasoning_content.strip('\n') + '\n\n\n' + content.lstrip('\n') }} + {%- else %} + {{- '<|im_start|>' + message.role + '\n' + content }} + {%- endif %} + {%- else %} + {{- '<|im_start|>' + message.role + '\n' + content }} + {%- endif %} + {%- if message.tool_calls %} + {%- for tool_call in message.tool_calls %} + {%- if (loop.first and content) or (not loop.first) %} + {{- '\n' }} + {%- endif %} + {%- if tool_call.function %} + {%- set tool_call = tool_call.function %} + {%- endif %} + {{- '\n{"name": "' }} + {{- tool_call.name }} + {{- '", "arguments": ' }} + {%- if tool_call.arguments is string %} + {{- tool_call.arguments }} + {%- else %} + {{- tool_call.arguments | tojson }} + {%- endif %} + {{- '}\n' }} + {%- endfor %} + {%- endif %} + {{- '<|im_end|>\n' }} + {%- elif message.role == "tool" %} + {%- if loop.first or (messages[loop.index0 - 1].role != "tool") %} + {{- '<|im_start|>user' }} + {%- endif %} + {{- '\n\n' }} + {{- content }} + {{- '\n' }} + {%- if loop.last or (messages[loop.index0 + 1].role != "tool") %} + {{- '<|im_end|>\n' }} + {%- endif %} + {%- endif %} +{%- endfor %} +{%- if add_generation_prompt %} + {{- '<|im_start|>assistant\n' }} + {%- if enable_thinking is defined and enable_thinking is false %} + {{- '\n\n\n\n' }} + {%- endif %} +{%- endif %} \ No newline at end of file diff --git a/qwen3/distillm_adaptive_sfkl/checkpoint-1256/README.md b/qwen3/distillm_adaptive_sfkl/checkpoint-1256/README.md new file mode 100644 index 0000000000000000000000000000000000000000..776f98d43659dd923b8c3e5649c5ae66d1f99f3e --- /dev/null +++ b/qwen3/distillm_adaptive_sfkl/checkpoint-1256/README.md @@ -0,0 +1,208 @@ +--- +base_model: Qwen/Qwen3-0.6B +library_name: peft +pipeline_tag: text-generation +tags: +- base_model:adapter:Qwen/Qwen3-0.6B +- llama-factory +- lora +- transformers +--- + +# Model Card for Model ID + + + + + +## Model Details + +### Model Description + + + + + +- **Developed by:** [More Information Needed] +- **Funded by [optional]:** [More Information Needed] +- **Shared by [optional]:** [More Information Needed] +- **Model type:** [More Information Needed] +- **Language(s) (NLP):** [More Information Needed] +- **License:** [More Information Needed] +- **Finetuned from model [optional]:** [More Information Needed] + +### Model Sources [optional] + + + +- **Repository:** [More Information Needed] +- **Paper [optional]:** [More Information Needed] +- **Demo [optional]:** [More Information Needed] + +## Uses + + + +### Direct Use + + + +[More Information Needed] + +### Downstream Use [optional] + + + +[More Information Needed] + +### Out-of-Scope Use + + + +[More Information Needed] + +## Bias, Risks, and Limitations + + + +[More Information Needed] + +### Recommendations + + + +Users (both direct and downstream) should be made aware of the risks, biases and limitations of the model. More information needed for further recommendations. + +## How to Get Started with the Model + +Use the code below to get started with the model. + +[More Information Needed] + +## Training Details + +### Training Data + + + +[More Information Needed] + +### Training Procedure + + + +#### Preprocessing [optional] + +[More Information Needed] + + +#### Training Hyperparameters + +- **Training regime:** [More Information Needed] + +#### Speeds, Sizes, Times [optional] + + + +[More Information Needed] + +## Evaluation + + + +### Testing Data, Factors & Metrics + +#### Testing Data + + + +[More Information Needed] + +#### Factors + + + +[More Information Needed] + +#### Metrics + + + +[More Information Needed] + +### Results + +[More Information Needed] + +#### Summary + + + +## Model Examination [optional] + + + +[More Information Needed] + +## Environmental Impact + + + +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). + +- **Hardware Type:** [More Information Needed] +- **Hours used:** [More Information Needed] +- **Cloud Provider:** [More Information Needed] +- **Compute Region:** [More Information Needed] +- **Carbon Emitted:** [More Information Needed] + +## Technical Specifications [optional] + +### Model Architecture and Objective + +[More Information Needed] + +### Compute Infrastructure + +[More Information Needed] + +#### Hardware + +[More Information Needed] + +#### Software + +[More Information Needed] + +## Citation [optional] + + + +**BibTeX:** + +[More Information Needed] + +**APA:** + +[More Information Needed] + +## Glossary [optional] + + + +[More Information Needed] + +## More Information [optional] + +[More Information Needed] + +## Model Card Authors [optional] + +[More Information Needed] + +## Model Card Contact + +[More Information Needed] +### Framework versions + +- PEFT 0.18.1 \ No newline at end of file diff --git a/qwen3/distillm_adaptive_sfkl/checkpoint-1256/adapter_config.json b/qwen3/distillm_adaptive_sfkl/checkpoint-1256/adapter_config.json new file mode 100644 index 0000000000000000000000000000000000000000..d88d3ddd2a1fe81f4cf32eb7f116cfcaecff483e --- /dev/null +++ b/qwen3/distillm_adaptive_sfkl/checkpoint-1256/adapter_config.json @@ -0,0 +1,46 @@ +{ + "alora_invocation_tokens": null, + "alpha_pattern": {}, + "arrow_config": null, + "auto_mapping": null, + "base_model_name_or_path": "Qwen/Qwen3-0.6B", + "bias": "none", + "corda_config": null, + "ensure_weight_tying": false, + "eva_config": null, + "exclude_modules": null, + "fan_in_fan_out": false, + "inference_mode": true, + "init_lora_weights": true, + "layer_replication": null, + "layers_pattern": null, + "layers_to_transform": null, + "loftq_config": {}, + "lora_alpha": 64, + "lora_bias": false, + "lora_dropout": 0.1, + "megatron_config": null, + "megatron_core": "megatron.core", + "modules_to_save": null, + "peft_type": "LORA", + "peft_version": "0.18.1", + "qalora_group_size": 16, + "r": 32, + "rank_pattern": {}, + "revision": null, + "target_modules": [ + "gate_proj", + "o_proj", + "down_proj", + "v_proj", + "q_proj", + "up_proj", + "k_proj" + ], + "target_parameters": null, + "task_type": "CAUSAL_LM", + "trainable_token_indices": null, + "use_dora": false, + "use_qalora": false, + "use_rslora": false +} \ No newline at end of file diff --git a/qwen3/distillm_adaptive_sfkl/checkpoint-1256/adapter_model.safetensors b/qwen3/distillm_adaptive_sfkl/checkpoint-1256/adapter_model.safetensors new file mode 100644 index 0000000000000000000000000000000000000000..372afd30ebfa129646c46970f09e3bf30c8a13a1 --- /dev/null +++ b/qwen3/distillm_adaptive_sfkl/checkpoint-1256/adapter_model.safetensors @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4f58e3b2fa10c1d01313865a7357234cc6333c4bd4046e8d6688a71a03aa4d13 +size 40422560 diff --git a/qwen3/distillm_adaptive_sfkl/checkpoint-1256/chat_template.jinja b/qwen3/distillm_adaptive_sfkl/checkpoint-1256/chat_template.jinja new file mode 100644 index 0000000000000000000000000000000000000000..01be9b307daa2d425f7c168c9fb145a286e0afb4 --- /dev/null +++ b/qwen3/distillm_adaptive_sfkl/checkpoint-1256/chat_template.jinja @@ -0,0 +1,89 @@ +{%- if tools %} + {{- '<|im_start|>system\n' }} + {%- if messages[0].role == 'system' %} + {{- messages[0].content + '\n\n' }} + {%- endif %} + {{- "# Tools\n\nYou may call one or more functions to assist with the user query.\n\nYou are provided with function signatures within XML tags:\n" }} + {%- for tool in tools %} + {{- "\n" }} + {{- tool | tojson }} + {%- endfor %} + {{- "\n\n\nFor each function call, return a json object with function name and arguments within XML tags:\n\n{\"name\": , \"arguments\": }\n<|im_end|>\n" }} +{%- else %} + {%- if messages[0].role == 'system' %} + {{- '<|im_start|>system\n' + messages[0].content + '<|im_end|>\n' }} + {%- endif %} +{%- endif %} +{%- set ns = namespace(multi_step_tool=true, last_query_index=messages|length - 1) %} +{%- for message in messages[::-1] %} + {%- set index = (messages|length - 1) - loop.index0 %} + {%- if ns.multi_step_tool and message.role == "user" and message.content is string and not(message.content.startswith('') and message.content.endswith('')) %} + {%- set ns.multi_step_tool = false %} + {%- set ns.last_query_index = index %} + {%- endif %} +{%- endfor %} +{%- for message in messages %} + {%- if message.content is string %} + {%- set content = message.content %} + {%- else %} + {%- set content = '' %} + {%- endif %} + {%- if (message.role == "user") or (message.role == "system" and not loop.first) %} + {{- '<|im_start|>' + message.role + '\n' + content + '<|im_end|>' + '\n' }} + {%- elif message.role == "assistant" %} + {%- set reasoning_content = '' %} + {%- if message.reasoning_content is string %} + {%- set reasoning_content = message.reasoning_content %} + {%- else %} + {%- if '' in content %} + {%- set reasoning_content = content.split('')[0].rstrip('\n').split('')[-1].lstrip('\n') %} + {%- set content = content.split('')[-1].lstrip('\n') %} + {%- endif %} + {%- endif %} + {%- if loop.index0 > ns.last_query_index %} + {%- if loop.last or (not loop.last and reasoning_content) %} + {{- '<|im_start|>' + message.role + '\n\n' + reasoning_content.strip('\n') + '\n\n\n' + content.lstrip('\n') }} + {%- else %} + {{- '<|im_start|>' + message.role + '\n' + content }} + {%- endif %} + {%- else %} + {{- '<|im_start|>' + message.role + '\n' + content }} + {%- endif %} + {%- if message.tool_calls %} + {%- for tool_call in message.tool_calls %} + {%- if (loop.first and content) or (not loop.first) %} + {{- '\n' }} + {%- endif %} + {%- if tool_call.function %} + {%- set tool_call = tool_call.function %} + {%- endif %} + {{- '\n{"name": "' }} + {{- tool_call.name }} + {{- '", "arguments": ' }} + {%- if tool_call.arguments is string %} + {{- tool_call.arguments }} + {%- else %} + {{- tool_call.arguments | tojson }} + {%- endif %} + {{- '}\n' }} + {%- endfor %} + {%- endif %} + {{- '<|im_end|>\n' }} + {%- elif message.role == "tool" %} + {%- if loop.first or (messages[loop.index0 - 1].role != "tool") %} + {{- '<|im_start|>user' }} + {%- endif %} + {{- '\n\n' }} + {{- content }} + {{- '\n' }} + {%- if loop.last or (messages[loop.index0 + 1].role != "tool") %} + {{- '<|im_end|>\n' }} + {%- endif %} + {%- endif %} +{%- endfor %} +{%- if add_generation_prompt %} + {{- '<|im_start|>assistant\n' }} + {%- if enable_thinking is defined and enable_thinking is false %} + {{- '\n\n\n\n' }} + {%- endif %} +{%- endif %} \ No newline at end of file diff --git a/qwen3/distillm_adaptive_sfkl/checkpoint-1256/distillm_state_rank0.pt b/qwen3/distillm_adaptive_sfkl/checkpoint-1256/distillm_state_rank0.pt new file mode 100644 index 0000000000000000000000000000000000000000..ba55d0738648d06c6b1157efaafadb891c3ede66 --- /dev/null +++ b/qwen3/distillm_adaptive_sfkl/checkpoint-1256/distillm_state_rank0.pt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5a9b5a84ccbbe30ec49486231d2b6d24ec7caa2a645eaeb1ef1ac1046bacb30f +size 9403 diff --git a/qwen3/distillm_adaptive_sfkl/checkpoint-1256/distillm_state_rank1.pt b/qwen3/distillm_adaptive_sfkl/checkpoint-1256/distillm_state_rank1.pt new file mode 100644 index 0000000000000000000000000000000000000000..7d6f6e0743fd8e8410d9dfaa520a36a19db24f2f --- /dev/null +++ b/qwen3/distillm_adaptive_sfkl/checkpoint-1256/distillm_state_rank1.pt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:55b029e6dfb2341a0bd92c4bf670fd9d1504f4e3c5bfe7a81b0984f5e033f257 +size 9339 diff --git a/qwen3/distillm_adaptive_sfkl/checkpoint-1256/global_step1256/bf16_zero_pp_rank_0_mp_rank_00_optim_states.pt b/qwen3/distillm_adaptive_sfkl/checkpoint-1256/global_step1256/bf16_zero_pp_rank_0_mp_rank_00_optim_states.pt new file mode 100644 index 0000000000000000000000000000000000000000..87579889f5e5584141ab4a19dd302d972ada8d32 --- /dev/null +++ b/qwen3/distillm_adaptive_sfkl/checkpoint-1256/global_step1256/bf16_zero_pp_rank_0_mp_rank_00_optim_states.pt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:58b78c70f5888623805998daab9f14c7e2814bd923742b7f2f0b621ee3f04007 +size 121135557 diff --git a/qwen3/distillm_adaptive_sfkl/checkpoint-1256/global_step1256/bf16_zero_pp_rank_1_mp_rank_00_optim_states.pt b/qwen3/distillm_adaptive_sfkl/checkpoint-1256/global_step1256/bf16_zero_pp_rank_1_mp_rank_00_optim_states.pt new file mode 100644 index 0000000000000000000000000000000000000000..9483b621110fc9dda6dc979a47f28d2e46c22851 --- /dev/null +++ b/qwen3/distillm_adaptive_sfkl/checkpoint-1256/global_step1256/bf16_zero_pp_rank_1_mp_rank_00_optim_states.pt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:59424cfcbfd035bb92538ce0e6f10147c53b280b7714a52322c8a59e77787f3a +size 121135749 diff --git a/qwen3/distillm_adaptive_sfkl/checkpoint-1256/global_step1256/mp_rank_00_model_states.pt b/qwen3/distillm_adaptive_sfkl/checkpoint-1256/global_step1256/mp_rank_00_model_states.pt new file mode 100644 index 0000000000000000000000000000000000000000..d91391fa7c229c8eec9b1b6d05fd03b3b03d559b --- /dev/null +++ b/qwen3/distillm_adaptive_sfkl/checkpoint-1256/global_step1256/mp_rank_00_model_states.pt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:26c5dd1b685e3e6a02aa27262d7215ba3e7570008ea738399c9cf0fceb699c6d +size 351841765 diff --git a/qwen3/distillm_adaptive_sfkl/checkpoint-1256/latest b/qwen3/distillm_adaptive_sfkl/checkpoint-1256/latest new file mode 100644 index 0000000000000000000000000000000000000000..74abb3d23ea83ebdac59918752db5d1782834ca7 --- /dev/null +++ b/qwen3/distillm_adaptive_sfkl/checkpoint-1256/latest @@ -0,0 +1 @@ +global_step1256 \ No newline at end of file diff --git a/qwen3/distillm_adaptive_sfkl/checkpoint-1256/rng_state_0.pth b/qwen3/distillm_adaptive_sfkl/checkpoint-1256/rng_state_0.pth new file mode 100644 index 0000000000000000000000000000000000000000..fff1c25f9b0daed6d86b07a8a74fb5a26e71a4cc --- /dev/null +++ b/qwen3/distillm_adaptive_sfkl/checkpoint-1256/rng_state_0.pth @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3938975c7fa1c658632f9261d8c2105e3cb55a634ad1d7f0de51ab9cba34601b +size 14917 diff --git a/qwen3/distillm_adaptive_sfkl/checkpoint-1256/rng_state_1.pth b/qwen3/distillm_adaptive_sfkl/checkpoint-1256/rng_state_1.pth new file mode 100644 index 0000000000000000000000000000000000000000..4ffa55d98ace7ca67ac9fe09cc26debcaf9358b9 --- /dev/null +++ b/qwen3/distillm_adaptive_sfkl/checkpoint-1256/rng_state_1.pth @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:08b65105f0441eb434f927c31aeb8917c9a0b1ce46d94c0a321be03146ac2bdd +size 14917 diff --git a/qwen3/distillm_adaptive_sfkl/checkpoint-1256/scheduler.pt b/qwen3/distillm_adaptive_sfkl/checkpoint-1256/scheduler.pt new file mode 100644 index 0000000000000000000000000000000000000000..40e863d07cfed22cd912014eb3ba3fd2b16b173f --- /dev/null +++ b/qwen3/distillm_adaptive_sfkl/checkpoint-1256/scheduler.pt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1775297f14e75f7463ae51983a66296f81f4b2e2e5d7234f1a6d295abfa4cf23 +size 1465 diff --git a/qwen3/distillm_adaptive_sfkl/checkpoint-1256/tokenizer.json b/qwen3/distillm_adaptive_sfkl/checkpoint-1256/tokenizer.json new file mode 100644 index 0000000000000000000000000000000000000000..c7afbed2efcdf019f88ab0572ec29d3bf595dfe2 --- /dev/null +++ b/qwen3/distillm_adaptive_sfkl/checkpoint-1256/tokenizer.json @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:be75606093db2094d7cd20f3c2f385c212750648bd6ea4fb2bf507a6a4c55506 +size 11422650 diff --git a/qwen3/distillm_adaptive_sfkl/checkpoint-1256/tokenizer_config.json b/qwen3/distillm_adaptive_sfkl/checkpoint-1256/tokenizer_config.json new file mode 100644 index 0000000000000000000000000000000000000000..6623da03457d79d2cd4af9557e9f31407cdb835c --- /dev/null +++ b/qwen3/distillm_adaptive_sfkl/checkpoint-1256/tokenizer_config.json @@ -0,0 +1,31 @@ +{ + "add_prefix_space": false, + "backend": "tokenizers", + "bos_token": null, + "clean_up_tokenization_spaces": false, + "eos_token": "<|im_end|>", + "errors": "replace", + "extra_special_tokens": [ + "<|im_start|>", + "<|im_end|>", + "<|object_ref_start|>", + "<|object_ref_end|>", + "<|box_start|>", + "<|box_end|>", + "<|quad_start|>", + "<|quad_end|>", + "<|vision_start|>", + "<|vision_end|>", + "<|vision_pad|>", + "<|image_pad|>", + "<|video_pad|>" + ], + "is_local": false, + "local_files_only": false, + "model_max_length": 131072, + "pad_token": "<|endoftext|>", + "padding_side": "right", + "split_special_tokens": false, + "tokenizer_class": "Qwen2Tokenizer", + "unk_token": null +} diff --git a/qwen3/distillm_adaptive_sfkl/checkpoint-1256/trainer_state.json b/qwen3/distillm_adaptive_sfkl/checkpoint-1256/trainer_state.json new file mode 100644 index 0000000000000000000000000000000000000000..7026bc2435f14e47e197ec7304b6752cea12e1bb --- /dev/null +++ b/qwen3/distillm_adaptive_sfkl/checkpoint-1256/trainer_state.json @@ -0,0 +1,543 @@ +{ + "best_global_step": null, + "best_metric": null, + "best_model_checkpoint": null, + "epoch": 4.0, + "eval_steps": 500, + "global_step": 1256, + "is_hyper_param_search": false, + "is_local_process_zero": true, + "is_world_process_zero": true, + "log_history": [ + { + "distillm_initial_generator_count": 1712.0, + "distillm_initial_generator_exact_match": 0.0, + "distillm_initial_generator_rouge1": 16.2149, + "distillm_initial_generator_rouge2": 3.2276, + "distillm_initial_generator_rougeL": 11.6725, + "distillm_initial_loss": 2.494271755218506, + "distillm_initial_runtime": 2988.1286, + "distillm_initial_samples_per_second": 1.143, + "distillm_initial_selector_accuracy": 52.278, + "distillm_initial_selector_count": 1712.0, + "distillm_initial_steps_per_second": 0.036, + "epoch": 0, + "step": 0 + }, + { + "epoch": 0.06382130035899482, + "grad_norm": 1.4179933071136475, + "learning_rate": 9.996390385474569e-05, + "loss": 0.360275936126709, + "step": 20 + }, + { + "epoch": 0.12764260071798963, + "grad_norm": 0.6145927309989929, + "learning_rate": 9.984797509888031e-05, + "loss": 0.0921450138092041, + "step": 40 + }, + { + "epoch": 0.19146390107698444, + "grad_norm": 0.949298083782196, + "learning_rate": 9.965229938050925e-05, + "loss": 0.06155582666397095, + "step": 60 + }, + { + "epoch": 0.25528520143597927, + "grad_norm": 0.32781288027763367, + "learning_rate": 9.937719005663432e-05, + "loss": 0.03148526251316071, + "step": 80 + }, + { + "epoch": 0.3191065017949741, + "grad_norm": 0.42831170558929443, + "learning_rate": 9.902308769000724e-05, + "loss": 0.0304107666015625, + "step": 100 + }, + { + "epoch": 0.3829278021539689, + "grad_norm": 0.37467315793037415, + "learning_rate": 9.859055934360789e-05, + "loss": 0.018133948743343353, + "step": 120 + }, + { + "epoch": 0.4467491025129637, + "grad_norm": 0.26231899857521057, + "learning_rate": 9.808029767254437e-05, + "loss": 0.023359841108322142, + "step": 140 + }, + { + "epoch": 0.5105704028719585, + "grad_norm": 0.23304614424705505, + "learning_rate": 9.749311981482817e-05, + "loss": 0.015377765893936158, + "step": 160 + }, + { + "epoch": 0.5743917032309533, + "grad_norm": 4.825753688812256, + "learning_rate": 9.682996608280154e-05, + "loss": 0.0134853795170784, + "step": 180 + }, + { + "epoch": 0.6382130035899481, + "grad_norm": 0.29226061701774597, + "learning_rate": 9.609189845731207e-05, + "loss": 0.022103385627269746, + "step": 200 + }, + { + "epoch": 0.702034303948943, + "grad_norm": 0.1759956330060959, + "learning_rate": 9.52800988870462e-05, + "loss": 0.011787685751914977, + "step": 220 + }, + { + "epoch": 0.7658556043079378, + "grad_norm": 0.18942032754421234, + "learning_rate": 9.439586739574513e-05, + "loss": 0.009058185666799546, + "step": 240 + }, + { + "epoch": 0.8296769046669326, + "grad_norm": 0.2657412886619568, + "learning_rate": 9.344062000033414e-05, + "loss": 0.009212753176689148, + "step": 260 + }, + { + "epoch": 0.8934982050259274, + "grad_norm": 0.28189197182655334, + "learning_rate": 9.241588644329919e-05, + "loss": 0.009374459087848664, + "step": 280 + }, + { + "epoch": 0.9573195053849222, + "grad_norm": 0.22191843390464783, + "learning_rate": 9.132330774294252e-05, + "loss": 0.009671492874622345, + "step": 300 + }, + { + "epoch": 1.0, + "eval_generator_count": 1712.0, + "eval_generator_exact_match": 90.0701, + "eval_generator_rouge1": 99.4297, + "eval_generator_rouge2": 99.1758, + "eval_generator_rougeL": 99.0503, + "eval_loss": 0.007805492263287306, + "eval_runtime": 601.5417, + "eval_samples_per_second": 5.675, + "eval_selector_accuracy": 95.5607, + "eval_selector_count": 1712.0, + "eval_steps_per_second": 0.178, + "step": 314 + }, + { + "epoch": 1.0191463901076985, + "grad_norm": 1.0133247375488281, + "learning_rate": 9.01646335654399e-05, + "loss": 0.013477623462677002, + "step": 320 + }, + { + "epoch": 1.0829676904666932, + "grad_norm": 0.07633373141288757, + "learning_rate": 8.894171942290817e-05, + "loss": 0.0067503504455089566, + "step": 340 + }, + { + "epoch": 1.146788990825688, + "grad_norm": 0.10817505419254303, + "learning_rate": 8.765652370197003e-05, + "loss": 0.005428457632660866, + "step": 360 + }, + { + "epoch": 1.210610291184683, + "grad_norm": 0.13295228779315948, + "learning_rate": 8.631110452757467e-05, + "loss": 0.004656650871038437, + "step": 380 + }, + { + "epoch": 1.2744315915436777, + "grad_norm": 0.09486064314842224, + "learning_rate": 8.490761646709642e-05, + "loss": 0.008230840414762497, + "step": 400 + }, + { + "epoch": 1.3382528919026724, + "grad_norm": 0.3019433617591858, + "learning_rate": 8.344830707998953e-05, + "loss": 0.008267045021057129, + "step": 420 + }, + { + "epoch": 1.4020741922616673, + "grad_norm": 0.06807491928339005, + "learning_rate": 8.193551331852458e-05, + "loss": 0.006827282160520554, + "step": 440 + }, + { + "epoch": 1.4658954926206622, + "grad_norm": 0.31115707755088806, + "learning_rate": 8.037165778537033e-05, + "loss": 0.005447100847959518, + "step": 460 + }, + { + "epoch": 1.5297167929796571, + "grad_norm": 0.09037721902132034, + "learning_rate": 7.875924485401427e-05, + "loss": 0.0037935201078653337, + "step": 480 + }, + { + "epoch": 1.5935380933386518, + "grad_norm": 0.050306856632232666, + "learning_rate": 7.710085665823444e-05, + "loss": 0.004351192712783813, + "step": 500 + }, + { + "epoch": 1.6573593936976465, + "grad_norm": 0.06550924479961395, + "learning_rate": 7.539914895704521e-05, + "loss": 0.004179144278168678, + "step": 520 + }, + { + "epoch": 1.7211806940566414, + "grad_norm": 0.037223804742097855, + "learning_rate": 7.365684688173908e-05, + "loss": 0.006012631207704544, + "step": 540 + }, + { + "epoch": 1.7850019944156363, + "grad_norm": 0.07440082728862762, + "learning_rate": 7.18767405718347e-05, + "loss": 0.0067665338516235355, + "step": 560 + }, + { + "epoch": 1.848823294774631, + "grad_norm": 0.4098421037197113, + "learning_rate": 7.006168070692036e-05, + "loss": 0.007050857692956924, + "step": 580 + }, + { + "epoch": 1.9126445951336257, + "grad_norm": 1.077409029006958, + "learning_rate": 6.821457394154786e-05, + "loss": 0.0025460906326770782, + "step": 600 + }, + { + "epoch": 1.9764658954926206, + "grad_norm": 0.14294511079788208, + "learning_rate": 6.633837825048768e-05, + "loss": 0.0034835845232009887, + "step": 620 + }, + { + "epoch": 2.0, + "eval_generator_count": 1712.0, + "eval_generator_exact_match": 92.9907, + "eval_generator_rouge1": 99.8109, + "eval_generator_rouge2": 99.6137, + "eval_generator_rougeL": 99.5606, + "eval_loss": 0.005652441177517176, + "eval_runtime": 602.3066, + "eval_samples_per_second": 5.668, + "eval_selector_accuracy": 97.722, + "eval_selector_count": 1712.0, + "eval_steps_per_second": 0.178, + "step": 628 + }, + { + "epoch": 2.038292780215397, + "grad_norm": 0.15983566641807556, + "learning_rate": 6.443609819179926e-05, + "loss": 0.0025436000898480414, + "step": 640 + }, + { + "epoch": 2.102114080574392, + "grad_norm": 0.24636076390743256, + "learning_rate": 6.251078009530256e-05, + "loss": 0.005166642367839813, + "step": 660 + }, + { + "epoch": 2.1659353809333863, + "grad_norm": 0.05653794854879379, + "learning_rate": 6.0565507184155677e-05, + "loss": 0.0020019154995679854, + "step": 680 + }, + { + "epoch": 2.2297566812923812, + "grad_norm": 0.020209209993481636, + "learning_rate": 5.860339463735136e-05, + "loss": 0.003964858502149582, + "step": 700 + }, + { + "epoch": 2.293577981651376, + "grad_norm": 0.015605684369802475, + "learning_rate": 5.662758460103895e-05, + "loss": 0.005196084827184677, + "step": 720 + }, + { + "epoch": 2.357399282010371, + "grad_norm": 0.05083553120493889, + "learning_rate": 5.464124115666095e-05, + "loss": 0.002757585048675537, + "step": 740 + }, + { + "epoch": 2.421220582369366, + "grad_norm": 0.023810580372810364, + "learning_rate": 5.264754525396212e-05, + "loss": 0.0015414590016007423, + "step": 760 + }, + { + "epoch": 2.4850418827283605, + "grad_norm": 0.022960327565670013, + "learning_rate": 5.06496896169857e-05, + "loss": 0.0012374447658658027, + "step": 780 + }, + { + "epoch": 2.5488631830873554, + "grad_norm": 0.08331727981567383, + "learning_rate": 4.865087363121384e-05, + "loss": 0.0037563137710094454, + "step": 800 + }, + { + "epoch": 2.6126844834463503, + "grad_norm": 0.3172169327735901, + "learning_rate": 4.6654298220040673e-05, + "loss": 0.0025980696082115173, + "step": 820 + }, + { + "epoch": 2.6765057838053448, + "grad_norm": 0.0642293244600296, + "learning_rate": 4.466316071878229e-05, + "loss": 0.0016859130933880805, + "step": 840 + }, + { + "epoch": 2.74032708416434, + "grad_norm": 0.07357119768857956, + "learning_rate": 4.2680649754432913e-05, + "loss": 0.002408899739384651, + "step": 860 + }, + { + "epoch": 2.8041483845233346, + "grad_norm": 0.12400355935096741, + "learning_rate": 4.070994013936646e-05, + "loss": 0.0020469389855861664, + "step": 880 + }, + { + "epoch": 2.8679696848823295, + "grad_norm": 0.21444188058376312, + "learning_rate": 3.8754187787161155e-05, + "loss": 0.0023752737790346144, + "step": 900 + }, + { + "epoch": 2.9317909852413244, + "grad_norm": 0.07703635096549988, + "learning_rate": 3.681652465868875e-05, + "loss": 0.004145454987883568, + "step": 920 + }, + { + "epoch": 2.995612285600319, + "grad_norm": 0.11405396461486816, + "learning_rate": 3.490005374656184e-05, + "loss": 0.0013555588200688362, + "step": 940 + }, + { + "epoch": 3.0, + "eval_generator_count": 1712.0, + "eval_generator_exact_match": 95.3271, + "eval_generator_rouge1": 99.9061, + "eval_generator_rouge2": 99.7991, + "eval_generator_rougeL": 99.6925, + "eval_loss": 0.003950633108615875, + "eval_runtime": 595.0919, + "eval_samples_per_second": 5.737, + "eval_selector_accuracy": 98.0724, + "eval_selector_count": 1712.0, + "eval_steps_per_second": 0.18, + "step": 942 + }, + { + "epoch": 3.057439170323095, + "grad_norm": 0.01742524839937687, + "learning_rate": 3.3007844105971336e-05, + "loss": 0.0017176205292344093, + "step": 960 + }, + { + "epoch": 3.12126047068209, + "grad_norm": 0.003188655711710453, + "learning_rate": 3.114292593987149e-05, + "loss": 0.0026764504611492155, + "step": 980 + }, + { + "epoch": 3.185081771041085, + "grad_norm": 0.01925867609679699, + "learning_rate": 2.9308285746383408e-05, + "loss": 0.0012796200811862946, + "step": 1000 + }, + { + "epoch": 3.24890307140008, + "grad_norm": 0.02856561355292797, + "learning_rate": 2.7506861536187867e-05, + "loss": 0.003274943307042122, + "step": 1020 + }, + { + "epoch": 3.3127243717590744, + "grad_norm": 0.28238120675086975, + "learning_rate": 2.5741538127566396e-05, + "loss": 0.0020828992128372192, + "step": 1040 + }, + { + "epoch": 3.3765456721180693, + "grad_norm": 0.0034029490780085325, + "learning_rate": 2.4015142526625115e-05, + "loss": 0.0026421770453453064, + "step": 1060 + }, + { + "epoch": 3.4403669724770642, + "grad_norm": 0.08193282783031464, + "learning_rate": 2.233043940009967e-05, + "loss": 0.002248910814523697, + "step": 1080 + }, + { + "epoch": 3.504188272836059, + "grad_norm": 0.006192841101437807, + "learning_rate": 2.0690126647990974e-05, + "loss": 0.0024001479148864748, + "step": 1100 + }, + { + "epoch": 3.568009573195054, + "grad_norm": 0.023488029837608337, + "learning_rate": 1.9096831083121828e-05, + "loss": 0.001568210683763027, + "step": 1120 + }, + { + "epoch": 3.6318308735540485, + "grad_norm": 0.10149848461151123, + "learning_rate": 1.7553104224533324e-05, + "loss": 0.0015563317574560642, + "step": 1140 + }, + { + "epoch": 3.6956521739130435, + "grad_norm": 0.016474615782499313, + "learning_rate": 1.606141821145735e-05, + "loss": 0.003182568401098251, + "step": 1160 + }, + { + "epoch": 3.7594734742720384, + "grad_norm": 0.015502875670790672, + "learning_rate": 1.4624161844408763e-05, + "loss": 0.002123878337442875, + "step": 1180 + }, + { + "epoch": 3.823294774631033, + "grad_norm": 0.013245862908661366, + "learning_rate": 1.324363675973698e-05, + "loss": 0.0021719962358474733, + "step": 1200 + }, + { + "epoch": 3.8871160749900278, + "grad_norm": 0.176155224442482, + "learning_rate": 1.1922053743763052e-05, + "loss": 0.003167513757944107, + "step": 1220 + }, + { + "epoch": 3.9509373753490227, + "grad_norm": 0.00724257156252861, + "learning_rate": 1.0661529192404973e-05, + "loss": 0.0008703418076038361, + "step": 1240 + }, + { + "epoch": 4.0, + "eval_generator_count": 1712.0, + "eval_generator_exact_match": 96.6706, + "eval_generator_rouge1": 99.9312, + "eval_generator_rouge2": 99.8709, + "eval_generator_rougeL": 99.7682, + "eval_loss": 0.0032213269732892513, + "eval_runtime": 594.8325, + "eval_samples_per_second": 5.739, + "eval_selector_accuracy": 98.5981, + "eval_selector_count": 1712.0, + "eval_steps_per_second": 0.18, + "step": 1256 + } + ], + "logging_steps": 20, + "max_steps": 1570, + "num_input_tokens_seen": 0, + "num_train_epochs": 5, + "save_steps": 500, + "stateful_callbacks": { + "TrainerControl": { + "args": { + "should_epoch_stop": false, + "should_evaluate": false, + "should_log": false, + "should_save": true, + "should_training_stop": false + }, + "attributes": {} + } + }, + "total_flos": 4.697643190059008e+16, + "train_batch_size": 2, + "trial_name": null, + "trial_params": null +} diff --git a/qwen3/distillm_adaptive_sfkl/checkpoint-1256/training_args.bin b/qwen3/distillm_adaptive_sfkl/checkpoint-1256/training_args.bin new file mode 100644 index 0000000000000000000000000000000000000000..9965b3704c5694d942c823f03f32ef4aa365d5a2 --- /dev/null +++ b/qwen3/distillm_adaptive_sfkl/checkpoint-1256/training_args.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4080ce6c122d894dce2a6242fb58ae879822809092a9484cf3c306a91aacf376 +size 7185 diff --git a/qwen3/distillm_adaptive_sfkl/checkpoint-1256/zero_to_fp32.py b/qwen3/distillm_adaptive_sfkl/checkpoint-1256/zero_to_fp32.py new file mode 100644 index 0000000000000000000000000000000000000000..f40f1f0acbbff30e8e8d29906b56aae4e8b8a138 --- /dev/null +++ b/qwen3/distillm_adaptive_sfkl/checkpoint-1256/zero_to_fp32.py @@ -0,0 +1,790 @@ +#!/usr/bin/env python + +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: Apache-2.0 + +# DeepSpeed Team + +# This script extracts fp32 consolidated weights from a zero 1, 2 and 3 DeepSpeed checkpoints. It gets +# copied into the top level checkpoint dir, so the user can easily do the conversion at any point in +# the future. Once extracted, the weights don't require DeepSpeed and can be used in any +# application. +# +# example: +# python zero_to_fp32.py . output_dir/ +# or +# python zero_to_fp32.py . output_dir/ --safe_serialization + +import argparse +import torch +import glob +import math +import os +import re +import gc +import json +import numpy as np +from tqdm import tqdm +from collections import OrderedDict +from dataclasses import dataclass + +# while this script doesn't use deepspeed to recover data, since the checkpoints are pickled with +# DeepSpeed data structures it has to be available in the current python environment. +from deepspeed.utils import logger +from deepspeed.checkpoint.constants import (DS_VERSION, OPTIMIZER_STATE_DICT, SINGLE_PARTITION_OF_FP32_GROUPS, + FP32_FLAT_GROUPS, ZERO_STAGE, PARTITION_COUNT, PARAM_SHAPES, BUFFER_NAMES, + FROZEN_PARAM_SHAPES, FROZEN_PARAM_FRAGMENTS, AUTOEP_LAYERS_KEY, + AUTOEP_LAYERS_KEY_LEGACY, AUTOEP_ZERO3_EXPERT_STATE_FORMAT_KEY, + AUTOEP_ZERO3_PARTITIONED_EXPERT_STATE_FORMAT) + + +@dataclass +class zero_model_state: + buffers: dict() + param_shapes: dict() + shared_params: list + ds_version: int + frozen_param_shapes: dict() + frozen_param_fragments: dict() + + +debug = 0 + +# load to cpu +device = torch.device('cpu') + + +def atoi(text): + return int(text) if text.isdigit() else text + + +def natural_keys(text): + ''' + alist.sort(key=natural_keys) sorts in human order + http://nedbatchelder.com/blog/200712/human_sorting.html + (See Toothy's implementation in the comments) + ''' + return [atoi(c) for c in re.split(r'(\d+)', text)] + + +def get_model_state_file(checkpoint_dir, zero_stage): + if not os.path.isdir(checkpoint_dir): + raise FileNotFoundError(f"Directory '{checkpoint_dir}' doesn't exist") + + # there should be only one file + if zero_stage <= 2: + file = os.path.join(checkpoint_dir, "mp_rank_00_model_states.pt") + elif zero_stage == 3: + file = os.path.join(checkpoint_dir, "zero_pp_rank_0_mp_rank_00_model_states.pt") + + if not os.path.exists(file): + raise FileNotFoundError(f"can't find model states file at '{file}'") + + return file + + +def get_checkpoint_files(checkpoint_dir, glob_pattern): + # XXX: need to test that this simple glob rule works for multi-node setup too + ckpt_files = sorted(glob.glob(os.path.join(checkpoint_dir, glob_pattern)), key=natural_keys) + + if len(ckpt_files) == 0: + raise FileNotFoundError(f"can't find {glob_pattern} files in directory '{checkpoint_dir}'") + + return ckpt_files + + +def get_optim_files(checkpoint_dir): + return get_checkpoint_files(checkpoint_dir, "*_optim_states.pt") + + +def get_model_state_files(checkpoint_dir): + return get_checkpoint_files(checkpoint_dir, "*_model_states.pt") + + +def _has_autoep_zero3_partitioned_metadata(state_dict): + autoep_layers = state_dict.get(AUTOEP_LAYERS_KEY) + if autoep_layers is None: + autoep_layers = state_dict.get(AUTOEP_LAYERS_KEY_LEGACY) + if not isinstance(autoep_layers, list): + return False + return any( + isinstance(entry, dict) + and entry.get(AUTOEP_ZERO3_EXPERT_STATE_FORMAT_KEY) == AUTOEP_ZERO3_PARTITIONED_EXPERT_STATE_FORMAT + for entry in autoep_layers) + + +def _raise_if_autoep_zero3_partitioned_state(state_dict): + if _has_autoep_zero3_partitioned_metadata(state_dict): + raise NotImplementedError("zero_to_fp32 does not support AutoEP ZeRO-3 partition-native checkpoints. " + "AutoEP expert parameters are partitioned over expert replica groups, so " + "global data-parallel consolidation would produce incomplete expert tensors. " + "Use ds_to_universal.py for expert-aware conversion.") + + +def _raise_if_autoep_zero3_partitioned_checkpoint(model_files): + for file in model_files: + state_dict = torch.load(file, map_location=device, weights_only=False) + _raise_if_autoep_zero3_partitioned_state(state_dict) + + +def parse_model_states(files): + zero_model_states = [] + for file in files: + state_dict = torch.load(file, map_location=device, weights_only=False) + _raise_if_autoep_zero3_partitioned_state(state_dict) + + if BUFFER_NAMES not in state_dict: + raise ValueError(f"{file} is not a model state checkpoint") + buffer_names = state_dict[BUFFER_NAMES] + if debug: + print("Found buffers:", buffer_names) + + # recover just the buffers while restoring them to fp32 if they were saved in fp16 + buffers = {k: v.float() for k, v in state_dict["module"].items() if k in buffer_names} + param_shapes = state_dict[PARAM_SHAPES] + + # collect parameters that are included in param_shapes + param_names = [] + for s in param_shapes: + for name in s.keys(): + param_names.append(name) + + # update with frozen parameters + frozen_param_shapes = state_dict.get(FROZEN_PARAM_SHAPES, None) + if frozen_param_shapes is not None: + if debug: + print(f"Found frozen_param_shapes: {frozen_param_shapes}") + param_names += list(frozen_param_shapes.keys()) + + # handle shared params + shared_params = [[k, v] for k, v in state_dict["shared_params"].items()] + + ds_version = state_dict.get(DS_VERSION, None) + + frozen_param_fragments = state_dict.get(FROZEN_PARAM_FRAGMENTS, None) + + z_model_state = zero_model_state(buffers=buffers, + param_shapes=param_shapes, + shared_params=shared_params, + ds_version=ds_version, + frozen_param_shapes=frozen_param_shapes, + frozen_param_fragments=frozen_param_fragments) + zero_model_states.append(z_model_state) + + return zero_model_states + + +def parse_optim_states(files, ds_checkpoint_dir): + total_files = len(files) + state_dicts = [] + for f in tqdm(files, desc='Loading checkpoint shards'): + state_dict = torch.load(f, map_location=device, mmap=True, weights_only=False) + # immediately discard the potentially huge 2 optimizer states as we only care for fp32 master weights + # and also handle the case where it was already removed by another helper script + state_dict["optimizer_state_dict"].pop("optimizer_state_dict", None) + state_dicts.append(state_dict) + + if ZERO_STAGE not in state_dicts[0][OPTIMIZER_STATE_DICT]: + raise ValueError(f"{files[0]} is not a zero checkpoint") + zero_stage = state_dicts[0][OPTIMIZER_STATE_DICT][ZERO_STAGE] + world_size = state_dicts[0][OPTIMIZER_STATE_DICT][PARTITION_COUNT] + + # For ZeRO-2 each param group can have different partition_count as data parallelism for expert + # parameters can be different from data parallelism for non-expert parameters. So we can just + # use the max of the partition_count to get the dp world_size. + + if type(world_size) is list: + world_size = max(world_size) + + if world_size != total_files: + raise ValueError( + f"Expected {world_size} of '*_optim_states.pt' under '{ds_checkpoint_dir}' but found {total_files} files. " + "Possibly due to an overwrite of an old checkpoint, or a checkpoint didn't get saved by one or more processes." + ) + + # the groups are named differently in each stage + if zero_stage <= 2: + fp32_groups_key = SINGLE_PARTITION_OF_FP32_GROUPS + elif zero_stage == 3: + fp32_groups_key = FP32_FLAT_GROUPS + else: + raise ValueError(f"unknown zero stage {zero_stage}") + + fp32_flat_groups = [state_dicts[i][OPTIMIZER_STATE_DICT][fp32_groups_key] for i in range(len(state_dicts))] + return zero_stage, world_size, fp32_flat_groups + + +def _get_fp32_state_dict_from_zero_checkpoint(ds_checkpoint_dir, exclude_frozen_parameters): + """ + Returns fp32 state_dict reconstructed from ds checkpoint + + Args: + - ``ds_checkpoint_dir``: path to the deepspeed checkpoint folder (where the optimizer files are) + + """ + print(f"Processing zero checkpoint '{ds_checkpoint_dir}'") + + # parse_model_states rejects AutoEP ZeRO-3 partition-native checkpoints + # before the expensive optimizer-shard load below. + model_files = get_model_state_files(ds_checkpoint_dir) + zero_model_states = parse_model_states(model_files) + print(f'Parsing checkpoint created by deepspeed=={zero_model_states[0].ds_version}') + + optim_files = get_optim_files(ds_checkpoint_dir) + zero_stage, world_size, fp32_flat_groups = parse_optim_states(optim_files, ds_checkpoint_dir) + print(f"Detected checkpoint of type zero stage {zero_stage}, world_size: {world_size}") + + if zero_stage <= 2: + return _get_fp32_state_dict_from_zero2_checkpoint(world_size, fp32_flat_groups, zero_model_states, + exclude_frozen_parameters) + elif zero_stage == 3: + return _get_fp32_state_dict_from_zero3_checkpoint(world_size, fp32_flat_groups, zero_model_states, + exclude_frozen_parameters) + + +def _zero2_merge_frozen_params(state_dict, zero_model_states): + if zero_model_states[0].frozen_param_shapes is None or len(zero_model_states[0].frozen_param_shapes) == 0: + return + + frozen_param_shapes = zero_model_states[0].frozen_param_shapes + frozen_param_fragments = zero_model_states[0].frozen_param_fragments + + if debug: + num_elem = sum(s.numel() for s in frozen_param_shapes.values()) + print(f'rank 0: {FROZEN_PARAM_SHAPES}.numel = {num_elem}') + + wanted_params = len(frozen_param_shapes) + wanted_numel = sum(s.numel() for s in frozen_param_shapes.values()) + avail_numel = sum([p.numel() for p in frozen_param_fragments.values()]) + print(f'Frozen params: Have {avail_numel} numels to process.') + print(f'Frozen params: Need {wanted_numel} numels in {wanted_params} params') + + total_params = 0 + total_numel = 0 + for name, shape in frozen_param_shapes.items(): + total_params += 1 + unpartitioned_numel = shape.numel() + total_numel += unpartitioned_numel + + state_dict[name] = frozen_param_fragments[name] + + if debug: + print(f"{name} full shape: {shape} unpartitioned numel {unpartitioned_numel} ") + + print(f"Reconstructed Frozen fp32 state dict with {total_params} params {total_numel} elements") + + +def _has_callable(obj, fn): + attr = getattr(obj, fn, None) + return callable(attr) + + +def _zero2_merge_trainable_params(state_dict, world_size, fp32_flat_groups, zero_model_states): + param_shapes = zero_model_states[0].param_shapes + + # Reconstruction protocol: + # + # XXX: document this + + if debug: + for i in range(world_size): + for j in range(len(fp32_flat_groups[0])): + print(f"{FP32_FLAT_GROUPS}[{i}][{j}].shape={fp32_flat_groups[i][j].shape}") + + # XXX: memory usage doubles here (zero2) + num_param_groups = len(fp32_flat_groups[0]) + merged_single_partition_of_fp32_groups = [] + for i in range(num_param_groups): + merged_partitions = [sd[i] for sd in fp32_flat_groups] + full_single_fp32_vector = torch.cat(merged_partitions, 0) + merged_single_partition_of_fp32_groups.append(full_single_fp32_vector) + avail_numel = sum( + [full_single_fp32_vector.numel() for full_single_fp32_vector in merged_single_partition_of_fp32_groups]) + + if debug: + wanted_params = sum([len(shapes) for shapes in param_shapes]) + wanted_numel = sum([sum(shape.numel() for shape in shapes.values()) for shapes in param_shapes]) + # not asserting if there is a mismatch due to possible padding + print(f"Have {avail_numel} numels to process.") + print(f"Need {wanted_numel} numels in {wanted_params} params.") + + # params + # XXX: for huge models that can't fit into the host's RAM we will have to recode this to support + # out-of-core computing solution + total_numel = 0 + total_params = 0 + for shapes, full_single_fp32_vector in zip(param_shapes, merged_single_partition_of_fp32_groups): + offset = 0 + avail_numel = full_single_fp32_vector.numel() + for name, shape in shapes.items(): + + unpartitioned_numel = shape.numel() if _has_callable(shape, 'numel') else math.prod(shape) + total_numel += unpartitioned_numel + total_params += 1 + + if debug: + print(f"{name} full shape: {shape} unpartitioned numel {unpartitioned_numel} ") + state_dict[name] = full_single_fp32_vector.narrow(0, offset, unpartitioned_numel).view(shape) + offset += unpartitioned_numel + + # Z2 started to align to 2*world_size to improve nccl performance. Therefore both offset and + # avail_numel can differ by anywhere between 0..2*world_size. Due to two unrelated complex + # paddings performed in the code it's almost impossible to predict the exact numbers w/o the + # live optimizer object, so we are checking that the numbers are within the right range + align_to = 2 * world_size + + def zero2_align(x): + return align_to * math.ceil(x / align_to) + + if debug: + print(f"original offset={offset}, avail_numel={avail_numel}") + + offset = zero2_align(offset) + avail_numel = zero2_align(avail_numel) + + if debug: + print(f"aligned offset={offset}, avail_numel={avail_numel}") + + # Sanity check + if offset != avail_numel: + raise ValueError(f"consumed {offset} numels out of {avail_numel} - something is wrong") + + print(f"Reconstructed fp32 state dict with {total_params} params {total_numel} elements") + + +def _get_fp32_state_dict_from_zero2_checkpoint(world_size, fp32_flat_groups, zero_model_states, + exclude_frozen_parameters): + state_dict = OrderedDict() + + # buffers + buffers = zero_model_states[0].buffers + state_dict.update(buffers) + if debug: + print(f"added {len(buffers)} buffers") + + if not exclude_frozen_parameters: + _zero2_merge_frozen_params(state_dict, zero_model_states) + + _zero2_merge_trainable_params(state_dict, world_size, fp32_flat_groups, zero_model_states) + + # recover shared parameters + for pair in zero_model_states[0].shared_params: + if pair[1] in state_dict: + state_dict[pair[0]] = state_dict[pair[1]] + + return state_dict + + +def zero3_partitioned_param_info(unpartitioned_numel, world_size): + remainder = unpartitioned_numel % world_size + padding_numel = (world_size - remainder) if remainder else 0 + partitioned_numel = math.ceil(unpartitioned_numel / world_size) + return partitioned_numel, padding_numel + + +def _zero3_merge_frozen_params(state_dict, world_size, zero_model_states): + if zero_model_states[0].frozen_param_shapes is None or len(zero_model_states[0].frozen_param_shapes) == 0: + return + + if debug: + for i in range(world_size): + num_elem = sum(s.numel() for s in zero_model_states[i].frozen_param_fragments.values()) + print(f'rank {i}: {FROZEN_PARAM_SHAPES}.numel = {num_elem}') + + frozen_param_shapes = zero_model_states[0].frozen_param_shapes + wanted_params = len(frozen_param_shapes) + wanted_numel = sum(s.numel() for s in frozen_param_shapes.values()) + avail_numel = sum([p.numel() for p in zero_model_states[0].frozen_param_fragments.values()]) * world_size + print(f'Frozen params: Have {avail_numel} numels to process.') + print(f'Frozen params: Need {wanted_numel} numels in {wanted_params} params') + + total_params = 0 + total_numel = 0 + for name, shape in zero_model_states[0].frozen_param_shapes.items(): + total_params += 1 + unpartitioned_numel = shape.numel() + total_numel += unpartitioned_numel + + param_frags = tuple(model_state.frozen_param_fragments[name] for model_state in zero_model_states) + state_dict[name] = torch.cat(param_frags, 0).narrow(0, 0, unpartitioned_numel).view(shape) + + partitioned_numel, partitioned_padding_numel = zero3_partitioned_param_info(unpartitioned_numel, world_size) + + if debug: + print( + f"Frozen params: {total_params} {name} full shape: {shape} partition0 numel={partitioned_numel} partitioned_padding_numel={partitioned_padding_numel}" + ) + + print(f"Reconstructed Frozen fp32 state dict with {total_params} params {total_numel} elements") + + +class GatheredTensor: + """ + A pseudo tensor that collects partitioned weights. + It is more memory efficient when there are multiple groups. + """ + + def __init__(self, flat_groups, flat_groups_offset, offset, partitioned_numel, shape): + self.flat_groups = flat_groups + self.flat_groups_offset = flat_groups_offset + self.offset = offset + self.partitioned_numel = partitioned_numel + self.shape = shape + self.dtype = self.flat_groups[0][0].dtype + + def contiguous(self): + """ + Merge partitioned weights from flat_groups into a single tensor. + """ + end_idx = self.offset + self.partitioned_numel + world_size = len(self.flat_groups) + pad_flat_param_chunks = [] + + for rank_i in range(world_size): + # for each rank, we need to collect weights from related group/groups + flat_groups_at_rank_i = self.flat_groups[rank_i] + start_group_id = None + end_group_id = None + for group_id in range(len(self.flat_groups_offset)): + if self.flat_groups_offset[group_id] <= self.offset < self.flat_groups_offset[group_id + 1]: + start_group_id = group_id + if self.flat_groups_offset[group_id] < end_idx <= self.flat_groups_offset[group_id + 1]: + end_group_id = group_id + break + # collect weights from related group/groups + for group_id in range(start_group_id, end_group_id + 1): + flat_tensor = flat_groups_at_rank_i[group_id] + start_offset = self.offset - self.flat_groups_offset[group_id] + end_offset = min(end_idx, self.flat_groups_offset[group_id + 1]) - self.flat_groups_offset[group_id] + pad_flat_param_chunks.append(flat_tensor[start_offset:end_offset]) + + # collect weights from all ranks + pad_flat_param = torch.cat(pad_flat_param_chunks, dim=0) + param = pad_flat_param[:self.shape.numel()].view(self.shape).contiguous() + return param + + +def _zero3_merge_trainable_params(state_dict, world_size, fp32_flat_groups, zero_model_states): + param_shapes = zero_model_states[0].param_shapes + avail_numel = sum([flat_group.numel() for flat_group in fp32_flat_groups[0]]) * world_size + + # Reconstruction protocol: For zero3 we need to zip the partitions together at boundary of each + # param, re-consolidating each param, while dealing with padding if any + + # merge list of dicts, preserving order + param_shapes = {k: v for d in param_shapes for k, v in d.items()} + + if debug: + for i in range(world_size): + print(f"{FP32_FLAT_GROUPS}[{i}].shape={fp32_flat_groups[i].shape}") + + wanted_params = len(param_shapes) + wanted_numel = sum(shape.numel() for shape in param_shapes.values()) + # not asserting if there is a mismatch due to possible padding + avail_numel = fp32_flat_groups[0].numel() * world_size + print(f"Trainable params: Have {avail_numel} numels to process.") + print(f"Trainable params: Need {wanted_numel} numels in {wanted_params} params.") + + # params + # XXX: for huge models that can't fit into the host's RAM we will have to recode this to support + # out-of-core computing solution + offset = 0 + total_numel = 0 + total_params = 0 + flat_groups_offset = [0] + list(np.cumsum([flat_tensor.numel() for flat_tensor in fp32_flat_groups[0]])) + for name, shape in tqdm(param_shapes.items(), desc='Gathering sharded weights'): + unpartitioned_numel = shape.numel() + total_numel += unpartitioned_numel + total_params += 1 + partitioned_numel, partitioned_padding_numel = zero3_partitioned_param_info(unpartitioned_numel, world_size) + + if debug: + print( + f"Trainable params: {total_params} {name} full shape: {shape} partition0 numel={partitioned_numel} partitioned_padding_numel={partitioned_padding_numel}" + ) + + # memory efficient tensor + tensor = GatheredTensor(fp32_flat_groups, flat_groups_offset, offset, partitioned_numel, shape) + state_dict[name] = tensor + offset += partitioned_numel + + offset *= world_size + + # Sanity check + if offset != avail_numel: + raise ValueError(f"consumed {offset} numels out of {avail_numel} - something is wrong") + + print(f"Reconstructed Trainable fp32 state dict with {total_params} params {total_numel} elements") + + +def _get_fp32_state_dict_from_zero3_checkpoint(world_size, fp32_flat_groups, zero_model_states, + exclude_frozen_parameters): + state_dict = OrderedDict() + + # buffers + buffers = zero_model_states[0].buffers + state_dict.update(buffers) + if debug: + print(f"added {len(buffers)} buffers") + + if not exclude_frozen_parameters: + _zero3_merge_frozen_params(state_dict, world_size, zero_model_states) + + _zero3_merge_trainable_params(state_dict, world_size, fp32_flat_groups, zero_model_states) + + # recover shared parameters + for pair in zero_model_states[0].shared_params: + if pair[1] in state_dict: + state_dict[pair[0]] = state_dict[pair[1]] + + return state_dict + + +def to_torch_tensor(state_dict, return_empty_tensor=False): + """ + Convert state_dict of GatheredTensor to torch tensor + """ + torch_state_dict = {} + converted_tensors = {} + for name, tensor in state_dict.items(): + tensor_id = id(tensor) + if tensor_id in converted_tensors: # shared tensors + shared_tensor = torch_state_dict[converted_tensors[tensor_id]] + torch_state_dict[name] = shared_tensor + else: + converted_tensors[tensor_id] = name + if return_empty_tensor: + torch_state_dict[name] = torch.empty(tensor.shape, dtype=tensor.dtype) + else: + torch_state_dict[name] = tensor.contiguous() + return torch_state_dict + + +def get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir, + tag=None, + exclude_frozen_parameters=False, + lazy_mode=False): + """ + Convert ZeRO 2 or 3 checkpoint into a single fp32 consolidated state_dict that can be loaded with + ``load_state_dict()`` and used for training without DeepSpeed or shared with others, for example + via a model hub. + + Args: + - ``checkpoint_dir``: path to the desired checkpoint folder + - ``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`` + - ``exclude_frozen_parameters``: exclude frozen parameters + - ``lazy_mode``: get state_dict in lazy mode. It returns a dict of pesduo tensor instead of torch tensor, which is more memory efficient. + Convert the pesduo tensor to torch tensor by ``.contiguous()`` + + Returns: + - pytorch ``state_dict`` + + A typical usage might be :: + + from deepspeed.utils.zero_to_fp32 import get_fp32_state_dict_from_zero_checkpoint + # do the training and checkpoint saving + state_dict = get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir) # already on cpu + model = model.cpu() # move to cpu + model.load_state_dict(state_dict) + # submit to model hub or save the model to share with others + + In this example the ``model`` will no longer be usable in the deepspeed context of the same + application. i.e. you will need to re-initialize the deepspeed engine, since + ``model.load_state_dict(state_dict)`` will remove all the deepspeed magic from it. + + If you want it all done for you, use ``load_state_dict_from_zero_checkpoint`` instead. + + Note: the above usage may not work if your application doesn't have sufficient free CPU memory. + You may need to use the offline approach using the ``zero_to_fp32.py`` script that is saved with + the checkpoint. Or you can load state_dict in lazy mode :: + + from deepspeed.utils.zero_to_fp32 import get_fp32_state_dict_from_zero_checkpoint + state_dict = get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir, lazy_mode=True) # not on cpu + for name, lazy_tensor in state_dict.item(): + tensor = lazy_tensor.contiguous() # to cpu + print(name, tensor) + # del tensor to release memory if it no longer in use + """ + if tag is None: + latest_path = os.path.join(checkpoint_dir, 'latest') + if os.path.isfile(latest_path): + with open(latest_path, 'r') as fd: + tag = fd.read().strip() + else: + raise ValueError(f"Unable to find 'latest' file at {latest_path}") + + ds_checkpoint_dir = os.path.join(checkpoint_dir, tag) + + if not os.path.isdir(ds_checkpoint_dir): + raise FileNotFoundError(f"Directory '{ds_checkpoint_dir}' doesn't exist") + + state_dict = _get_fp32_state_dict_from_zero_checkpoint(ds_checkpoint_dir, exclude_frozen_parameters) + if lazy_mode: + return state_dict + else: + return to_torch_tensor(state_dict) + + +def convert_zero_checkpoint_to_fp32_state_dict(checkpoint_dir, + output_dir, + max_shard_size="5GB", + safe_serialization=False, + tag=None, + exclude_frozen_parameters=False): + """ + Convert ZeRO 2 or 3 checkpoint into a single fp32 consolidated ``state_dict`` file that can be + loaded with ``torch.load(file)`` + ``load_state_dict()`` and used for training without DeepSpeed. + + Args: + - ``checkpoint_dir``: path to the desired checkpoint folder. (one that contains the tag-folder, like ``global_step14``) + - ``output_dir``: directory to the pytorch fp32 state_dict output files + - ``max_shard_size``: the maximum size for a checkpoint before being sharded, default value is 5GB + - ``safe_serialization``: whether to save the model using `safetensors` or the traditional PyTorch way (that uses `pickle`). + - ``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`` + - ``exclude_frozen_parameters``: exclude frozen parameters + """ + + # Dependency pre-check + if safe_serialization: + try: + from safetensors.torch import save_file + except ImportError: + print('If you want to use `safe_serialization`, please `pip install safetensors`') + raise + if max_shard_size is not None: + try: + from huggingface_hub import split_torch_state_dict_into_shards + except ImportError: + print('If you want to use `max_shard_size`, please `pip install huggingface_hub`') + raise + + # Convert zero checkpoint to state_dict + state_dict = get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir, + tag, + exclude_frozen_parameters, + lazy_mode=True) + + # Shard the model if it is too big. + weights_name = "model.safetensors" if safe_serialization else "pytorch_model.bin" + if max_shard_size is not None: + filename_pattern = weights_name.replace(".bin", "{suffix}.bin").replace(".safetensors", "{suffix}.safetensors") + # an memory-efficient approach for sharding + empty_state_dict = to_torch_tensor(state_dict, return_empty_tensor=True) + state_dict_split = split_torch_state_dict_into_shards(empty_state_dict, + filename_pattern=filename_pattern, + max_shard_size=max_shard_size) + else: + from collections import namedtuple + StateDictSplit = namedtuple("StateDictSplit", ["is_sharded", "filename_to_tensors"]) + state_dict_split = StateDictSplit(is_sharded=False, + filename_to_tensors={weights_name: list(state_dict.keys())}) + + # Save the model by shard + os.makedirs(output_dir, exist_ok=True) + filename_to_tensors = state_dict_split.filename_to_tensors.items() + for shard_file, tensors in tqdm(filename_to_tensors, desc="Saving checkpoint shards"): + shard_state_dict = {tensor_name: state_dict[tensor_name] for tensor_name in tensors} + shard_state_dict = to_torch_tensor(shard_state_dict) + output_path = os.path.join(output_dir, shard_file) + if safe_serialization: + save_file(shard_state_dict, output_path, metadata={"format": "pt"}) + else: + torch.save(shard_state_dict, output_path) + # release the memory of current shard + for tensor_name in list(shard_state_dict.keys()): + del state_dict[tensor_name] + del shard_state_dict[tensor_name] + del shard_state_dict + gc.collect() + + # Save index if sharded + if state_dict_split.is_sharded: + index = { + "metadata": state_dict_split.metadata, + "weight_map": state_dict_split.tensor_to_filename, + } + save_index_file = "model.safetensors.index.json" if safe_serialization else "pytorch_model.bin.index.json" + save_index_file = os.path.join(output_dir, save_index_file) + with open(save_index_file, "w", encoding="utf-8") as f: + content = json.dumps(index, indent=2, sort_keys=True) + "\n" + f.write(content) + + +def load_state_dict_from_zero_checkpoint(model, checkpoint_dir, tag=None): + """ + 1. Put the provided model to cpu + 2. Convert ZeRO 2 or 3 checkpoint into a single fp32 consolidated ``state_dict`` + 3. Load it into the provided model + + Args: + - ``model``: the model object to update + - ``checkpoint_dir``: path to the desired checkpoint folder. (one that contains the tag-folder, like ``global_step14``) + - ``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`` + + Returns: + - ``model`: modified model + + Make sure you have plenty of CPU memory available before you call this function. If you don't + have enough use the ``zero_to_fp32.py`` utility to do the conversion. You will find it + conveniently placed for you in the checkpoint folder. + + A typical usage might be :: + + from deepspeed.utils.zero_to_fp32 import load_state_dict_from_zero_checkpoint + model = load_state_dict_from_zero_checkpoint(trainer.model, checkpoint_dir) + # submit to model hub or save the model to share with others + + Note, that once this was run, the ``model`` will no longer be usable in the deepspeed context + of the same application. i.e. you will need to re-initialize the deepspeed engine, since + ``model.load_state_dict(state_dict)`` will remove all the deepspeed magic from it. + + """ + logger.info("Extracting fp32 weights") + state_dict = get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir, tag) + + logger.info("Overwriting model with fp32 weights") + model = model.cpu() + model.load_state_dict(state_dict, strict=False) + + return model + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument("checkpoint_dir", + type=str, + help="path to the desired checkpoint folder, e.g., path/checkpoint-12") + parser.add_argument("output_dir", + type=str, + help="directory to the pytorch fp32 state_dict output files" + "(e.g. path/checkpoint-12-output/)") + parser.add_argument( + "--max_shard_size", + type=str, + default="5GB", + help="The maximum size for a checkpoint before being sharded. Checkpoints shard will then be each of size" + "lower than this size. If expressed as a string, needs to be digits followed by a unit (like `5MB`" + "We default it to 5GB in order for models to be able to run easily on free-tier google colab instances" + "without CPU OOM issues.") + parser.add_argument( + "--safe_serialization", + default=False, + action='store_true', + help="Whether to save the model using `safetensors` or the traditional PyTorch way (that uses `pickle`).") + parser.add_argument("-t", + "--tag", + type=str, + default=None, + help="checkpoint tag used as a unique identifier for checkpoint. e.g., global_step1") + parser.add_argument("--exclude_frozen_parameters", action='store_true', help="exclude frozen parameters") + parser.add_argument("-d", "--debug", action='store_true', help="enable debug") + args = parser.parse_args() + + debug = args.debug + + convert_zero_checkpoint_to_fp32_state_dict(args.checkpoint_dir, + args.output_dir, + max_shard_size=args.max_shard_size, + safe_serialization=args.safe_serialization, + tag=args.tag, + exclude_frozen_parameters=args.exclude_frozen_parameters) diff --git a/qwen3/distillm_adaptive_sfkl/checkpoint-1570/README.md b/qwen3/distillm_adaptive_sfkl/checkpoint-1570/README.md new file mode 100644 index 0000000000000000000000000000000000000000..776f98d43659dd923b8c3e5649c5ae66d1f99f3e --- /dev/null +++ b/qwen3/distillm_adaptive_sfkl/checkpoint-1570/README.md @@ -0,0 +1,208 @@ +--- +base_model: Qwen/Qwen3-0.6B +library_name: peft +pipeline_tag: text-generation +tags: +- base_model:adapter:Qwen/Qwen3-0.6B +- llama-factory +- lora +- transformers +--- + +# Model Card for Model ID + + + + + +## Model Details + +### Model Description + + + + + +- **Developed by:** [More Information Needed] +- **Funded by [optional]:** [More Information Needed] +- **Shared by [optional]:** [More Information Needed] +- **Model type:** [More Information Needed] +- **Language(s) (NLP):** [More Information Needed] +- **License:** [More Information Needed] +- **Finetuned from model [optional]:** [More Information Needed] + +### Model Sources [optional] + + + +- **Repository:** [More Information Needed] +- **Paper [optional]:** [More Information Needed] +- **Demo [optional]:** [More Information Needed] + +## Uses + + + +### Direct Use + + + +[More Information Needed] + +### Downstream Use [optional] + + + +[More Information Needed] + +### Out-of-Scope Use + + + +[More Information Needed] + +## Bias, Risks, and Limitations + + + +[More Information Needed] + +### Recommendations + + + +Users (both direct and downstream) should be made aware of the risks, biases and limitations of the model. More information needed for further recommendations. + +## How to Get Started with the Model + +Use the code below to get started with the model. + +[More Information Needed] + +## Training Details + +### Training Data + + + +[More Information Needed] + +### Training Procedure + + + +#### Preprocessing [optional] + +[More Information Needed] + + +#### Training Hyperparameters + +- **Training regime:** [More Information Needed] + +#### Speeds, Sizes, Times [optional] + + + +[More Information Needed] + +## Evaluation + + + +### Testing Data, Factors & Metrics + +#### Testing Data + + + +[More Information Needed] + +#### Factors + + + +[More Information Needed] + +#### Metrics + + + +[More Information Needed] + +### Results + +[More Information Needed] + +#### Summary + + + +## Model Examination [optional] + + + +[More Information Needed] + +## Environmental Impact + + + +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). + +- **Hardware Type:** [More Information Needed] +- **Hours used:** [More Information Needed] +- **Cloud Provider:** [More Information Needed] +- **Compute Region:** [More Information Needed] +- **Carbon Emitted:** [More Information Needed] + +## Technical Specifications [optional] + +### Model Architecture and Objective + +[More Information Needed] + +### Compute Infrastructure + +[More Information Needed] + +#### Hardware + +[More Information Needed] + +#### Software + +[More Information Needed] + +## Citation [optional] + + + +**BibTeX:** + +[More Information Needed] + +**APA:** + +[More Information Needed] + +## Glossary [optional] + + + +[More Information Needed] + +## More Information [optional] + +[More Information Needed] + +## Model Card Authors [optional] + +[More Information Needed] + +## Model Card Contact + +[More Information Needed] +### Framework versions + +- PEFT 0.18.1 \ No newline at end of file diff --git a/qwen3/distillm_adaptive_sfkl/checkpoint-1570/adapter_config.json b/qwen3/distillm_adaptive_sfkl/checkpoint-1570/adapter_config.json new file mode 100644 index 0000000000000000000000000000000000000000..d88d3ddd2a1fe81f4cf32eb7f116cfcaecff483e --- /dev/null +++ b/qwen3/distillm_adaptive_sfkl/checkpoint-1570/adapter_config.json @@ -0,0 +1,46 @@ +{ + "alora_invocation_tokens": null, + "alpha_pattern": {}, + "arrow_config": null, + "auto_mapping": null, + "base_model_name_or_path": "Qwen/Qwen3-0.6B", + "bias": "none", + "corda_config": null, + "ensure_weight_tying": false, + "eva_config": null, + "exclude_modules": null, + "fan_in_fan_out": false, + "inference_mode": true, + "init_lora_weights": true, + "layer_replication": null, + "layers_pattern": null, + "layers_to_transform": null, + "loftq_config": {}, + "lora_alpha": 64, + "lora_bias": false, + "lora_dropout": 0.1, + "megatron_config": null, + "megatron_core": "megatron.core", + "modules_to_save": null, + "peft_type": "LORA", + "peft_version": "0.18.1", + "qalora_group_size": 16, + "r": 32, + "rank_pattern": {}, + "revision": null, + "target_modules": [ + "gate_proj", + "o_proj", + "down_proj", + "v_proj", + "q_proj", + "up_proj", + "k_proj" + ], + "target_parameters": null, + "task_type": "CAUSAL_LM", + "trainable_token_indices": null, + "use_dora": false, + "use_qalora": false, + "use_rslora": false +} \ No newline at end of file diff --git a/qwen3/distillm_adaptive_sfkl/checkpoint-1570/adapter_model.safetensors b/qwen3/distillm_adaptive_sfkl/checkpoint-1570/adapter_model.safetensors new file mode 100644 index 0000000000000000000000000000000000000000..906be98e4f889370ba814eecd51b8209eb2a3815 --- /dev/null +++ b/qwen3/distillm_adaptive_sfkl/checkpoint-1570/adapter_model.safetensors @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a99e7a0decfbd11795996653da7c5bc4e9262944d052503644f577fff3ab8626 +size 40422560 diff --git a/qwen3/distillm_adaptive_sfkl/checkpoint-1570/chat_template.jinja b/qwen3/distillm_adaptive_sfkl/checkpoint-1570/chat_template.jinja new file mode 100644 index 0000000000000000000000000000000000000000..01be9b307daa2d425f7c168c9fb145a286e0afb4 --- /dev/null +++ b/qwen3/distillm_adaptive_sfkl/checkpoint-1570/chat_template.jinja @@ -0,0 +1,89 @@ +{%- if tools %} + {{- '<|im_start|>system\n' }} + {%- if messages[0].role == 'system' %} + {{- messages[0].content + '\n\n' }} + {%- endif %} + {{- "# Tools\n\nYou may call one or more functions to assist with the user query.\n\nYou are provided with function signatures within XML tags:\n" }} + {%- for tool in tools %} + {{- "\n" }} + {{- tool | tojson }} + {%- endfor %} + {{- "\n\n\nFor each function call, return a json object with function name and arguments within XML tags:\n\n{\"name\": , \"arguments\": }\n<|im_end|>\n" }} +{%- else %} + {%- if messages[0].role == 'system' %} + {{- '<|im_start|>system\n' + messages[0].content + '<|im_end|>\n' }} + {%- endif %} +{%- endif %} +{%- set ns = namespace(multi_step_tool=true, last_query_index=messages|length - 1) %} +{%- for message in messages[::-1] %} + {%- set index = (messages|length - 1) - loop.index0 %} + {%- if ns.multi_step_tool and message.role == "user" and message.content is string and not(message.content.startswith('') and message.content.endswith('')) %} + {%- set ns.multi_step_tool = false %} + {%- set ns.last_query_index = index %} + {%- endif %} +{%- endfor %} +{%- for message in messages %} + {%- if message.content is string %} + {%- set content = message.content %} + {%- else %} + {%- set content = '' %} + {%- endif %} + {%- if (message.role == "user") or (message.role == "system" and not loop.first) %} + {{- '<|im_start|>' + message.role + '\n' + content + '<|im_end|>' + '\n' }} + {%- elif message.role == "assistant" %} + {%- set reasoning_content = '' %} + {%- if message.reasoning_content is string %} + {%- set reasoning_content = message.reasoning_content %} + {%- else %} + {%- if '' in content %} + {%- set reasoning_content = content.split('')[0].rstrip('\n').split('')[-1].lstrip('\n') %} + {%- set content = content.split('')[-1].lstrip('\n') %} + {%- endif %} + {%- endif %} + {%- if loop.index0 > ns.last_query_index %} + {%- if loop.last or (not loop.last and reasoning_content) %} + {{- '<|im_start|>' + message.role + '\n\n' + reasoning_content.strip('\n') + '\n\n\n' + content.lstrip('\n') }} + {%- else %} + {{- '<|im_start|>' + message.role + '\n' + content }} + {%- endif %} + {%- else %} + {{- '<|im_start|>' + message.role + '\n' + content }} + {%- endif %} + {%- if message.tool_calls %} + {%- for tool_call in message.tool_calls %} + {%- if (loop.first and content) or (not loop.first) %} + {{- '\n' }} + {%- endif %} + {%- if tool_call.function %} + {%- set tool_call = tool_call.function %} + {%- endif %} + {{- '\n{"name": "' }} + {{- tool_call.name }} + {{- '", "arguments": ' }} + {%- if tool_call.arguments is string %} + {{- tool_call.arguments }} + {%- else %} + {{- tool_call.arguments | tojson }} + {%- endif %} + {{- '}\n' }} + {%- endfor %} + {%- endif %} + {{- '<|im_end|>\n' }} + {%- elif message.role == "tool" %} + {%- if loop.first or (messages[loop.index0 - 1].role != "tool") %} + {{- '<|im_start|>user' }} + {%- endif %} + {{- '\n\n' }} + {{- content }} + {{- '\n' }} + {%- if loop.last or (messages[loop.index0 + 1].role != "tool") %} + {{- '<|im_end|>\n' }} + {%- endif %} + {%- endif %} +{%- endfor %} +{%- if add_generation_prompt %} + {{- '<|im_start|>assistant\n' }} + {%- if enable_thinking is defined and enable_thinking is false %} + {{- '\n\n\n\n' }} + {%- endif %} +{%- endif %} \ No newline at end of file diff --git a/qwen3/distillm_adaptive_sfkl/checkpoint-1570/distillm_state_rank0.pt b/qwen3/distillm_adaptive_sfkl/checkpoint-1570/distillm_state_rank0.pt new file mode 100644 index 0000000000000000000000000000000000000000..becca175688219a9b4a422f423edefb47590217d --- /dev/null +++ b/qwen3/distillm_adaptive_sfkl/checkpoint-1570/distillm_state_rank0.pt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c45fea5636ba58d552a49ba5a651afe08fe7e86b64bd29d82359e1ffb3df111f +size 9403 diff --git a/qwen3/distillm_adaptive_sfkl/checkpoint-1570/distillm_state_rank1.pt b/qwen3/distillm_adaptive_sfkl/checkpoint-1570/distillm_state_rank1.pt new file mode 100644 index 0000000000000000000000000000000000000000..2d7c319e37a117a78ed636f3109afc6ef3c8fd98 --- /dev/null +++ b/qwen3/distillm_adaptive_sfkl/checkpoint-1570/distillm_state_rank1.pt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:34b6ffca878fd86b6133b9eb70d94fee805ff00ef1d33571b54dc0de3a307df3 +size 9339 diff --git a/qwen3/distillm_adaptive_sfkl/checkpoint-1570/global_step1570/bf16_zero_pp_rank_0_mp_rank_00_optim_states.pt b/qwen3/distillm_adaptive_sfkl/checkpoint-1570/global_step1570/bf16_zero_pp_rank_0_mp_rank_00_optim_states.pt new file mode 100644 index 0000000000000000000000000000000000000000..3b24b94f1149c43a697a92512f3edd89444400ec --- /dev/null +++ b/qwen3/distillm_adaptive_sfkl/checkpoint-1570/global_step1570/bf16_zero_pp_rank_0_mp_rank_00_optim_states.pt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dea9f965e183cf6e75cc938d2101c21aebc2cc249d288e312672c5b1c17a5de6 +size 121135557 diff --git a/qwen3/distillm_adaptive_sfkl/checkpoint-1570/global_step1570/bf16_zero_pp_rank_1_mp_rank_00_optim_states.pt b/qwen3/distillm_adaptive_sfkl/checkpoint-1570/global_step1570/bf16_zero_pp_rank_1_mp_rank_00_optim_states.pt new file mode 100644 index 0000000000000000000000000000000000000000..9c18f90b893aa54624a6cf9a7820d62d24dc8a50 --- /dev/null +++ b/qwen3/distillm_adaptive_sfkl/checkpoint-1570/global_step1570/bf16_zero_pp_rank_1_mp_rank_00_optim_states.pt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:712782b89f3f2a08edd6b14367d0d1c1f316231e121f4e9f2ad44141927379c7 +size 121135749 diff --git a/qwen3/distillm_adaptive_sfkl/checkpoint-1570/global_step1570/mp_rank_00_model_states.pt b/qwen3/distillm_adaptive_sfkl/checkpoint-1570/global_step1570/mp_rank_00_model_states.pt new file mode 100644 index 0000000000000000000000000000000000000000..39a22f7bb9c8a25d3c0bf9adaa55a6adbe3cfe2f --- /dev/null +++ b/qwen3/distillm_adaptive_sfkl/checkpoint-1570/global_step1570/mp_rank_00_model_states.pt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4eb5d89461998455656d00f5f8b8b13c336625ba0180c96c30ae3fcddb30b535 +size 351841765 diff --git a/qwen3/distillm_adaptive_sfkl/checkpoint-1570/latest b/qwen3/distillm_adaptive_sfkl/checkpoint-1570/latest new file mode 100644 index 0000000000000000000000000000000000000000..18c2fcff58fa6daa0a2e7c3a015552a69085778b --- /dev/null +++ b/qwen3/distillm_adaptive_sfkl/checkpoint-1570/latest @@ -0,0 +1 @@ +global_step1570 \ No newline at end of file diff --git a/qwen3/distillm_adaptive_sfkl/checkpoint-1570/rng_state_0.pth b/qwen3/distillm_adaptive_sfkl/checkpoint-1570/rng_state_0.pth new file mode 100644 index 0000000000000000000000000000000000000000..d4b6079ff4d744e907933ebe2f9df086a16f163f --- /dev/null +++ b/qwen3/distillm_adaptive_sfkl/checkpoint-1570/rng_state_0.pth @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b4b7c956a417bcc6c356c97ca412ef5c5e2b5fc70fba8223db55cb48ac282753 +size 14917 diff --git a/qwen3/distillm_adaptive_sfkl/checkpoint-1570/rng_state_1.pth b/qwen3/distillm_adaptive_sfkl/checkpoint-1570/rng_state_1.pth new file mode 100644 index 0000000000000000000000000000000000000000..d90069af091242b4bae104ce1480faa3b6b594c2 --- /dev/null +++ b/qwen3/distillm_adaptive_sfkl/checkpoint-1570/rng_state_1.pth @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:10569e1274020cceec29016fb35178a5dffe88d926ec542d32d89b0016d59ccf +size 14917 diff --git a/qwen3/distillm_adaptive_sfkl/checkpoint-1570/scheduler.pt b/qwen3/distillm_adaptive_sfkl/checkpoint-1570/scheduler.pt new file mode 100644 index 0000000000000000000000000000000000000000..e22954463492d8a070ae427c95418df61893c54c --- /dev/null +++ b/qwen3/distillm_adaptive_sfkl/checkpoint-1570/scheduler.pt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e6332fac17ae99a07597512c705658da2fd8429d1c39bb776b30e107c2cb7aae +size 1465 diff --git a/qwen3/distillm_adaptive_sfkl/checkpoint-1570/tokenizer.json b/qwen3/distillm_adaptive_sfkl/checkpoint-1570/tokenizer.json new file mode 100644 index 0000000000000000000000000000000000000000..c7afbed2efcdf019f88ab0572ec29d3bf595dfe2 --- /dev/null +++ b/qwen3/distillm_adaptive_sfkl/checkpoint-1570/tokenizer.json @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:be75606093db2094d7cd20f3c2f385c212750648bd6ea4fb2bf507a6a4c55506 +size 11422650 diff --git a/qwen3/distillm_adaptive_sfkl/checkpoint-1570/tokenizer_config.json b/qwen3/distillm_adaptive_sfkl/checkpoint-1570/tokenizer_config.json new file mode 100644 index 0000000000000000000000000000000000000000..6623da03457d79d2cd4af9557e9f31407cdb835c --- /dev/null +++ b/qwen3/distillm_adaptive_sfkl/checkpoint-1570/tokenizer_config.json @@ -0,0 +1,31 @@ +{ + "add_prefix_space": false, + "backend": "tokenizers", + "bos_token": null, + "clean_up_tokenization_spaces": false, + "eos_token": "<|im_end|>", + "errors": "replace", + "extra_special_tokens": [ + "<|im_start|>", + "<|im_end|>", + "<|object_ref_start|>", + "<|object_ref_end|>", + "<|box_start|>", + "<|box_end|>", + "<|quad_start|>", + "<|quad_end|>", + "<|vision_start|>", + "<|vision_end|>", + "<|vision_pad|>", + "<|image_pad|>", + "<|video_pad|>" + ], + "is_local": false, + "local_files_only": false, + "model_max_length": 131072, + "pad_token": "<|endoftext|>", + "padding_side": "right", + "split_special_tokens": false, + "tokenizer_class": "Qwen2Tokenizer", + "unk_token": null +} diff --git a/qwen3/distillm_adaptive_sfkl/checkpoint-1570/trainer_state.json b/qwen3/distillm_adaptive_sfkl/checkpoint-1570/trainer_state.json new file mode 100644 index 0000000000000000000000000000000000000000..aeeaa7242620077d49ec3151c11f99879000d0a3 --- /dev/null +++ b/qwen3/distillm_adaptive_sfkl/checkpoint-1570/trainer_state.json @@ -0,0 +1,670 @@ +{ + "best_global_step": null, + "best_metric": null, + "best_model_checkpoint": null, + "epoch": 5.0, + "eval_steps": 500, + "global_step": 1570, + "is_hyper_param_search": false, + "is_local_process_zero": true, + "is_world_process_zero": true, + "log_history": [ + { + "distillm_initial_generator_count": 1712.0, + "distillm_initial_generator_exact_match": 0.0, + "distillm_initial_generator_rouge1": 16.2149, + "distillm_initial_generator_rouge2": 3.2276, + "distillm_initial_generator_rougeL": 11.6725, + "distillm_initial_loss": 2.494271755218506, + "distillm_initial_runtime": 2988.1286, + "distillm_initial_samples_per_second": 1.143, + "distillm_initial_selector_accuracy": 52.278, + "distillm_initial_selector_count": 1712.0, + "distillm_initial_steps_per_second": 0.036, + "epoch": 0, + "step": 0 + }, + { + "epoch": 0.06382130035899482, + "grad_norm": 1.4179933071136475, + "learning_rate": 9.996390385474569e-05, + "loss": 0.360275936126709, + "step": 20 + }, + { + "epoch": 0.12764260071798963, + "grad_norm": 0.6145927309989929, + "learning_rate": 9.984797509888031e-05, + "loss": 0.0921450138092041, + "step": 40 + }, + { + "epoch": 0.19146390107698444, + "grad_norm": 0.949298083782196, + "learning_rate": 9.965229938050925e-05, + "loss": 0.06155582666397095, + "step": 60 + }, + { + "epoch": 0.25528520143597927, + "grad_norm": 0.32781288027763367, + "learning_rate": 9.937719005663432e-05, + "loss": 0.03148526251316071, + "step": 80 + }, + { + "epoch": 0.3191065017949741, + "grad_norm": 0.42831170558929443, + "learning_rate": 9.902308769000724e-05, + "loss": 0.0304107666015625, + "step": 100 + }, + { + "epoch": 0.3829278021539689, + "grad_norm": 0.37467315793037415, + "learning_rate": 9.859055934360789e-05, + "loss": 0.018133948743343353, + "step": 120 + }, + { + "epoch": 0.4467491025129637, + "grad_norm": 0.26231899857521057, + "learning_rate": 9.808029767254437e-05, + "loss": 0.023359841108322142, + "step": 140 + }, + { + "epoch": 0.5105704028719585, + "grad_norm": 0.23304614424705505, + "learning_rate": 9.749311981482817e-05, + "loss": 0.015377765893936158, + "step": 160 + }, + { + "epoch": 0.5743917032309533, + "grad_norm": 4.825753688812256, + "learning_rate": 9.682996608280154e-05, + "loss": 0.0134853795170784, + "step": 180 + }, + { + "epoch": 0.6382130035899481, + "grad_norm": 0.29226061701774597, + "learning_rate": 9.609189845731207e-05, + "loss": 0.022103385627269746, + "step": 200 + }, + { + "epoch": 0.702034303948943, + "grad_norm": 0.1759956330060959, + "learning_rate": 9.52800988870462e-05, + "loss": 0.011787685751914977, + "step": 220 + }, + { + "epoch": 0.7658556043079378, + "grad_norm": 0.18942032754421234, + "learning_rate": 9.439586739574513e-05, + "loss": 0.009058185666799546, + "step": 240 + }, + { + "epoch": 0.8296769046669326, + "grad_norm": 0.2657412886619568, + "learning_rate": 9.344062000033414e-05, + "loss": 0.009212753176689148, + "step": 260 + }, + { + "epoch": 0.8934982050259274, + "grad_norm": 0.28189197182655334, + "learning_rate": 9.241588644329919e-05, + "loss": 0.009374459087848664, + "step": 280 + }, + { + "epoch": 0.9573195053849222, + "grad_norm": 0.22191843390464783, + "learning_rate": 9.132330774294252e-05, + "loss": 0.009671492874622345, + "step": 300 + }, + { + "epoch": 1.0, + "eval_generator_count": 1712.0, + "eval_generator_exact_match": 90.0701, + "eval_generator_rouge1": 99.4297, + "eval_generator_rouge2": 99.1758, + "eval_generator_rougeL": 99.0503, + "eval_loss": 0.007805492263287306, + "eval_runtime": 601.5417, + "eval_samples_per_second": 5.675, + "eval_selector_accuracy": 95.5607, + "eval_selector_count": 1712.0, + "eval_steps_per_second": 0.178, + "step": 314 + }, + { + "epoch": 1.0191463901076985, + "grad_norm": 1.0133247375488281, + "learning_rate": 9.01646335654399e-05, + "loss": 0.013477623462677002, + "step": 320 + }, + { + "epoch": 1.0829676904666932, + "grad_norm": 0.07633373141288757, + "learning_rate": 8.894171942290817e-05, + "loss": 0.0067503504455089566, + "step": 340 + }, + { + "epoch": 1.146788990825688, + "grad_norm": 0.10817505419254303, + "learning_rate": 8.765652370197003e-05, + "loss": 0.005428457632660866, + "step": 360 + }, + { + "epoch": 1.210610291184683, + "grad_norm": 0.13295228779315948, + "learning_rate": 8.631110452757467e-05, + "loss": 0.004656650871038437, + "step": 380 + }, + { + "epoch": 1.2744315915436777, + "grad_norm": 0.09486064314842224, + "learning_rate": 8.490761646709642e-05, + "loss": 0.008230840414762497, + "step": 400 + }, + { + "epoch": 1.3382528919026724, + "grad_norm": 0.3019433617591858, + "learning_rate": 8.344830707998953e-05, + "loss": 0.008267045021057129, + "step": 420 + }, + { + "epoch": 1.4020741922616673, + "grad_norm": 0.06807491928339005, + "learning_rate": 8.193551331852458e-05, + "loss": 0.006827282160520554, + "step": 440 + }, + { + "epoch": 1.4658954926206622, + "grad_norm": 0.31115707755088806, + "learning_rate": 8.037165778537033e-05, + "loss": 0.005447100847959518, + "step": 460 + }, + { + "epoch": 1.5297167929796571, + "grad_norm": 0.09037721902132034, + "learning_rate": 7.875924485401427e-05, + "loss": 0.0037935201078653337, + "step": 480 + }, + { + "epoch": 1.5935380933386518, + "grad_norm": 0.050306856632232666, + "learning_rate": 7.710085665823444e-05, + "loss": 0.004351192712783813, + "step": 500 + }, + { + "epoch": 1.6573593936976465, + "grad_norm": 0.06550924479961395, + "learning_rate": 7.539914895704521e-05, + "loss": 0.004179144278168678, + "step": 520 + }, + { + "epoch": 1.7211806940566414, + "grad_norm": 0.037223804742097855, + "learning_rate": 7.365684688173908e-05, + "loss": 0.006012631207704544, + "step": 540 + }, + { + "epoch": 1.7850019944156363, + "grad_norm": 0.07440082728862762, + "learning_rate": 7.18767405718347e-05, + "loss": 0.0067665338516235355, + "step": 560 + }, + { + "epoch": 1.848823294774631, + "grad_norm": 0.4098421037197113, + "learning_rate": 7.006168070692036e-05, + "loss": 0.007050857692956924, + "step": 580 + }, + { + "epoch": 1.9126445951336257, + "grad_norm": 1.077409029006958, + "learning_rate": 6.821457394154786e-05, + "loss": 0.0025460906326770782, + "step": 600 + }, + { + "epoch": 1.9764658954926206, + "grad_norm": 0.14294511079788208, + "learning_rate": 6.633837825048768e-05, + "loss": 0.0034835845232009887, + "step": 620 + }, + { + "epoch": 2.0, + "eval_generator_count": 1712.0, + "eval_generator_exact_match": 92.9907, + "eval_generator_rouge1": 99.8109, + "eval_generator_rouge2": 99.6137, + "eval_generator_rougeL": 99.5606, + "eval_loss": 0.005652441177517176, + "eval_runtime": 602.3066, + "eval_samples_per_second": 5.668, + "eval_selector_accuracy": 97.722, + "eval_selector_count": 1712.0, + "eval_steps_per_second": 0.178, + "step": 628 + }, + { + "epoch": 2.038292780215397, + "grad_norm": 0.15983566641807556, + "learning_rate": 6.443609819179926e-05, + "loss": 0.0025436000898480414, + "step": 640 + }, + { + "epoch": 2.102114080574392, + "grad_norm": 0.24636076390743256, + "learning_rate": 6.251078009530256e-05, + "loss": 0.005166642367839813, + "step": 660 + }, + { + "epoch": 2.1659353809333863, + "grad_norm": 0.05653794854879379, + "learning_rate": 6.0565507184155677e-05, + "loss": 0.0020019154995679854, + "step": 680 + }, + { + "epoch": 2.2297566812923812, + "grad_norm": 0.020209209993481636, + "learning_rate": 5.860339463735136e-05, + "loss": 0.003964858502149582, + "step": 700 + }, + { + "epoch": 2.293577981651376, + "grad_norm": 0.015605684369802475, + "learning_rate": 5.662758460103895e-05, + "loss": 0.005196084827184677, + "step": 720 + }, + { + "epoch": 2.357399282010371, + "grad_norm": 0.05083553120493889, + "learning_rate": 5.464124115666095e-05, + "loss": 0.002757585048675537, + "step": 740 + }, + { + "epoch": 2.421220582369366, + "grad_norm": 0.023810580372810364, + "learning_rate": 5.264754525396212e-05, + "loss": 0.0015414590016007423, + "step": 760 + }, + { + "epoch": 2.4850418827283605, + "grad_norm": 0.022960327565670013, + "learning_rate": 5.06496896169857e-05, + "loss": 0.0012374447658658027, + "step": 780 + }, + { + "epoch": 2.5488631830873554, + "grad_norm": 0.08331727981567383, + "learning_rate": 4.865087363121384e-05, + "loss": 0.0037563137710094454, + "step": 800 + }, + { + "epoch": 2.6126844834463503, + "grad_norm": 0.3172169327735901, + "learning_rate": 4.6654298220040673e-05, + "loss": 0.0025980696082115173, + "step": 820 + }, + { + "epoch": 2.6765057838053448, + "grad_norm": 0.0642293244600296, + "learning_rate": 4.466316071878229e-05, + "loss": 0.0016859130933880805, + "step": 840 + }, + { + "epoch": 2.74032708416434, + "grad_norm": 0.07357119768857956, + "learning_rate": 4.2680649754432913e-05, + "loss": 0.002408899739384651, + "step": 860 + }, + { + "epoch": 2.8041483845233346, + "grad_norm": 0.12400355935096741, + "learning_rate": 4.070994013936646e-05, + "loss": 0.0020469389855861664, + "step": 880 + }, + { + "epoch": 2.8679696848823295, + "grad_norm": 0.21444188058376312, + "learning_rate": 3.8754187787161155e-05, + "loss": 0.0023752737790346144, + "step": 900 + }, + { + "epoch": 2.9317909852413244, + "grad_norm": 0.07703635096549988, + "learning_rate": 3.681652465868875e-05, + "loss": 0.004145454987883568, + "step": 920 + }, + { + "epoch": 2.995612285600319, + "grad_norm": 0.11405396461486816, + "learning_rate": 3.490005374656184e-05, + "loss": 0.0013555588200688362, + "step": 940 + }, + { + "epoch": 3.0, + "eval_generator_count": 1712.0, + "eval_generator_exact_match": 95.3271, + "eval_generator_rouge1": 99.9061, + "eval_generator_rouge2": 99.7991, + "eval_generator_rougeL": 99.6925, + "eval_loss": 0.003950633108615875, + "eval_runtime": 595.0919, + "eval_samples_per_second": 5.737, + "eval_selector_accuracy": 98.0724, + "eval_selector_count": 1712.0, + "eval_steps_per_second": 0.18, + "step": 942 + }, + { + "epoch": 3.057439170323095, + "grad_norm": 0.01742524839937687, + "learning_rate": 3.3007844105971336e-05, + "loss": 0.0017176205292344093, + "step": 960 + }, + { + "epoch": 3.12126047068209, + "grad_norm": 0.003188655711710453, + "learning_rate": 3.114292593987149e-05, + "loss": 0.0026764504611492155, + "step": 980 + }, + { + "epoch": 3.185081771041085, + "grad_norm": 0.01925867609679699, + "learning_rate": 2.9308285746383408e-05, + "loss": 0.0012796200811862946, + "step": 1000 + }, + { + "epoch": 3.24890307140008, + "grad_norm": 0.02856561355292797, + "learning_rate": 2.7506861536187867e-05, + "loss": 0.003274943307042122, + "step": 1020 + }, + { + "epoch": 3.3127243717590744, + "grad_norm": 0.28238120675086975, + "learning_rate": 2.5741538127566396e-05, + "loss": 0.0020828992128372192, + "step": 1040 + }, + { + "epoch": 3.3765456721180693, + "grad_norm": 0.0034029490780085325, + "learning_rate": 2.4015142526625115e-05, + "loss": 0.0026421770453453064, + "step": 1060 + }, + { + "epoch": 3.4403669724770642, + "grad_norm": 0.08193282783031464, + "learning_rate": 2.233043940009967e-05, + "loss": 0.002248910814523697, + "step": 1080 + }, + { + "epoch": 3.504188272836059, + "grad_norm": 0.006192841101437807, + "learning_rate": 2.0690126647990974e-05, + "loss": 0.0024001479148864748, + "step": 1100 + }, + { + "epoch": 3.568009573195054, + "grad_norm": 0.023488029837608337, + "learning_rate": 1.9096831083121828e-05, + "loss": 0.001568210683763027, + "step": 1120 + }, + { + "epoch": 3.6318308735540485, + "grad_norm": 0.10149848461151123, + "learning_rate": 1.7553104224533324e-05, + "loss": 0.0015563317574560642, + "step": 1140 + }, + { + "epoch": 3.6956521739130435, + "grad_norm": 0.016474615782499313, + "learning_rate": 1.606141821145735e-05, + "loss": 0.003182568401098251, + "step": 1160 + }, + { + "epoch": 3.7594734742720384, + "grad_norm": 0.015502875670790672, + "learning_rate": 1.4624161844408763e-05, + "loss": 0.002123878337442875, + "step": 1180 + }, + { + "epoch": 3.823294774631033, + "grad_norm": 0.013245862908661366, + "learning_rate": 1.324363675973698e-05, + "loss": 0.0021719962358474733, + "step": 1200 + }, + { + "epoch": 3.8871160749900278, + "grad_norm": 0.176155224442482, + "learning_rate": 1.1922053743763052e-05, + "loss": 0.003167513757944107, + "step": 1220 + }, + { + "epoch": 3.9509373753490227, + "grad_norm": 0.00724257156252861, + "learning_rate": 1.0661529192404973e-05, + "loss": 0.0008703418076038361, + "step": 1240 + }, + { + "epoch": 4.0, + "eval_generator_count": 1712.0, + "eval_generator_exact_match": 96.6706, + "eval_generator_rouge1": 99.9312, + "eval_generator_rouge2": 99.8709, + "eval_generator_rougeL": 99.7682, + "eval_loss": 0.0032213269732892513, + "eval_runtime": 594.8325, + "eval_samples_per_second": 5.739, + "eval_selector_accuracy": 98.5981, + "eval_selector_count": 1712.0, + "eval_steps_per_second": 0.18, + "step": 1256 + }, + { + "epoch": 4.0127642600717985, + "grad_norm": 0.2515179216861725, + "learning_rate": 9.464081721960592e-06, + "loss": 0.0021197797730565073, + "step": 1260 + }, + { + "epoch": 4.076585560430794, + "grad_norm": 0.052773285657167435, + "learning_rate": 8.331628936475818e-06, + "loss": 0.0007191885262727738, + "step": 1280 + }, + { + "epoch": 4.140406860789788, + "grad_norm": 0.020960243418812752, + "learning_rate": 7.2659843568748385e-06, + "loss": 0.0012289942242205143, + "step": 1300 + }, + { + "epoch": 4.204228161148784, + "grad_norm": 0.009606960229575634, + "learning_rate": 6.268854516770008e-06, + "loss": 0.0012783183716237544, + "step": 1320 + }, + { + "epoch": 4.268049461507778, + "grad_norm": 0.03356768190860748, + "learning_rate": 5.341836229602331e-06, + "loss": 0.0015904821455478668, + "step": 1340 + }, + { + "epoch": 4.331870761866773, + "grad_norm": 0.43399015069007874, + "learning_rate": 4.4864140314888216e-06, + "loss": 0.0019017960876226425, + "step": 1360 + }, + { + "epoch": 4.395692062225768, + "grad_norm": 0.09213124215602875, + "learning_rate": 3.703957803871932e-06, + "loss": 0.000992914568632841, + "step": 1380 + }, + { + "epoch": 4.4595133625847625, + "grad_norm": 0.030944187194108963, + "learning_rate": 2.9957205797780495e-06, + "loss": 0.0019235227257013321, + "step": 1400 + }, + { + "epoch": 4.523334662943758, + "grad_norm": 0.04038539156317711, + "learning_rate": 2.362836537198199e-06, + "loss": 0.001333768479526043, + "step": 1420 + }, + { + "epoch": 4.587155963302752, + "grad_norm": 0.009491882286965847, + "learning_rate": 1.8063191828043703e-06, + "loss": 0.0010302967391908168, + "step": 1440 + }, + { + "epoch": 4.650977263661747, + "grad_norm": 0.02417566254734993, + "learning_rate": 1.3270597289100437e-06, + "loss": 0.0008206027559936047, + "step": 1460 + }, + { + "epoch": 4.714798564020742, + "grad_norm": 0.0027866039890795946, + "learning_rate": 9.258256662741205e-07, + "loss": 0.0008394632488489151, + "step": 1480 + }, + { + "epoch": 4.778619864379737, + "grad_norm": 0.01856832019984722, + "learning_rate": 6.032595350337341e-07, + "loss": 0.0011719820089638234, + "step": 1500 + }, + { + "epoch": 4.842441164738732, + "grad_norm": 0.013062495738267899, + "learning_rate": 3.5987789573421356e-07, + "loss": 0.0029238536953926086, + "step": 1520 + }, + { + "epoch": 4.9062624650977265, + "grad_norm": 0.094195157289505, + "learning_rate": 1.9607050210401192e-07, + "loss": 0.0008629086427390575, + "step": 1540 + }, + { + "epoch": 4.970083765456721, + "grad_norm": 0.02496415562927723, + "learning_rate": 1.1209967689925832e-07, + "loss": 0.0011463512666523457, + "step": 1560 + }, + { + "epoch": 5.0, + "eval_generator_count": 1712.0, + "eval_generator_exact_match": 96.4953, + "eval_generator_rouge1": 99.9278, + "eval_generator_rouge2": 99.8599, + "eval_generator_rougeL": 99.777, + "eval_loss": 0.003217515302821994, + "eval_runtime": 592.4524, + "eval_samples_per_second": 5.762, + "eval_selector_accuracy": 98.7734, + "eval_selector_count": 1712.0, + "eval_steps_per_second": 0.181, + "step": 1570 + } + ], + "logging_steps": 20, + "max_steps": 1570, + "num_input_tokens_seen": 0, + "num_train_epochs": 5, + "save_steps": 500, + "stateful_callbacks": { + "TrainerControl": { + "args": { + "should_epoch_stop": false, + "should_evaluate": false, + "should_log": false, + "should_save": true, + "should_training_stop": true + }, + "attributes": {} + } + }, + "total_flos": 5.871444840310374e+16, + "train_batch_size": 2, + "trial_name": null, + "trial_params": null +} diff --git a/qwen3/distillm_adaptive_sfkl/checkpoint-1570/training_args.bin b/qwen3/distillm_adaptive_sfkl/checkpoint-1570/training_args.bin new file mode 100644 index 0000000000000000000000000000000000000000..9965b3704c5694d942c823f03f32ef4aa365d5a2 --- /dev/null +++ b/qwen3/distillm_adaptive_sfkl/checkpoint-1570/training_args.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4080ce6c122d894dce2a6242fb58ae879822809092a9484cf3c306a91aacf376 +size 7185 diff --git a/qwen3/distillm_adaptive_sfkl/checkpoint-1570/zero_to_fp32.py b/qwen3/distillm_adaptive_sfkl/checkpoint-1570/zero_to_fp32.py new file mode 100644 index 0000000000000000000000000000000000000000..f40f1f0acbbff30e8e8d29906b56aae4e8b8a138 --- /dev/null +++ b/qwen3/distillm_adaptive_sfkl/checkpoint-1570/zero_to_fp32.py @@ -0,0 +1,790 @@ +#!/usr/bin/env python + +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: Apache-2.0 + +# DeepSpeed Team + +# This script extracts fp32 consolidated weights from a zero 1, 2 and 3 DeepSpeed checkpoints. It gets +# copied into the top level checkpoint dir, so the user can easily do the conversion at any point in +# the future. Once extracted, the weights don't require DeepSpeed and can be used in any +# application. +# +# example: +# python zero_to_fp32.py . output_dir/ +# or +# python zero_to_fp32.py . output_dir/ --safe_serialization + +import argparse +import torch +import glob +import math +import os +import re +import gc +import json +import numpy as np +from tqdm import tqdm +from collections import OrderedDict +from dataclasses import dataclass + +# while this script doesn't use deepspeed to recover data, since the checkpoints are pickled with +# DeepSpeed data structures it has to be available in the current python environment. +from deepspeed.utils import logger +from deepspeed.checkpoint.constants import (DS_VERSION, OPTIMIZER_STATE_DICT, SINGLE_PARTITION_OF_FP32_GROUPS, + FP32_FLAT_GROUPS, ZERO_STAGE, PARTITION_COUNT, PARAM_SHAPES, BUFFER_NAMES, + FROZEN_PARAM_SHAPES, FROZEN_PARAM_FRAGMENTS, AUTOEP_LAYERS_KEY, + AUTOEP_LAYERS_KEY_LEGACY, AUTOEP_ZERO3_EXPERT_STATE_FORMAT_KEY, + AUTOEP_ZERO3_PARTITIONED_EXPERT_STATE_FORMAT) + + +@dataclass +class zero_model_state: + buffers: dict() + param_shapes: dict() + shared_params: list + ds_version: int + frozen_param_shapes: dict() + frozen_param_fragments: dict() + + +debug = 0 + +# load to cpu +device = torch.device('cpu') + + +def atoi(text): + return int(text) if text.isdigit() else text + + +def natural_keys(text): + ''' + alist.sort(key=natural_keys) sorts in human order + http://nedbatchelder.com/blog/200712/human_sorting.html + (See Toothy's implementation in the comments) + ''' + return [atoi(c) for c in re.split(r'(\d+)', text)] + + +def get_model_state_file(checkpoint_dir, zero_stage): + if not os.path.isdir(checkpoint_dir): + raise FileNotFoundError(f"Directory '{checkpoint_dir}' doesn't exist") + + # there should be only one file + if zero_stage <= 2: + file = os.path.join(checkpoint_dir, "mp_rank_00_model_states.pt") + elif zero_stage == 3: + file = os.path.join(checkpoint_dir, "zero_pp_rank_0_mp_rank_00_model_states.pt") + + if not os.path.exists(file): + raise FileNotFoundError(f"can't find model states file at '{file}'") + + return file + + +def get_checkpoint_files(checkpoint_dir, glob_pattern): + # XXX: need to test that this simple glob rule works for multi-node setup too + ckpt_files = sorted(glob.glob(os.path.join(checkpoint_dir, glob_pattern)), key=natural_keys) + + if len(ckpt_files) == 0: + raise FileNotFoundError(f"can't find {glob_pattern} files in directory '{checkpoint_dir}'") + + return ckpt_files + + +def get_optim_files(checkpoint_dir): + return get_checkpoint_files(checkpoint_dir, "*_optim_states.pt") + + +def get_model_state_files(checkpoint_dir): + return get_checkpoint_files(checkpoint_dir, "*_model_states.pt") + + +def _has_autoep_zero3_partitioned_metadata(state_dict): + autoep_layers = state_dict.get(AUTOEP_LAYERS_KEY) + if autoep_layers is None: + autoep_layers = state_dict.get(AUTOEP_LAYERS_KEY_LEGACY) + if not isinstance(autoep_layers, list): + return False + return any( + isinstance(entry, dict) + and entry.get(AUTOEP_ZERO3_EXPERT_STATE_FORMAT_KEY) == AUTOEP_ZERO3_PARTITIONED_EXPERT_STATE_FORMAT + for entry in autoep_layers) + + +def _raise_if_autoep_zero3_partitioned_state(state_dict): + if _has_autoep_zero3_partitioned_metadata(state_dict): + raise NotImplementedError("zero_to_fp32 does not support AutoEP ZeRO-3 partition-native checkpoints. " + "AutoEP expert parameters are partitioned over expert replica groups, so " + "global data-parallel consolidation would produce incomplete expert tensors. " + "Use ds_to_universal.py for expert-aware conversion.") + + +def _raise_if_autoep_zero3_partitioned_checkpoint(model_files): + for file in model_files: + state_dict = torch.load(file, map_location=device, weights_only=False) + _raise_if_autoep_zero3_partitioned_state(state_dict) + + +def parse_model_states(files): + zero_model_states = [] + for file in files: + state_dict = torch.load(file, map_location=device, weights_only=False) + _raise_if_autoep_zero3_partitioned_state(state_dict) + + if BUFFER_NAMES not in state_dict: + raise ValueError(f"{file} is not a model state checkpoint") + buffer_names = state_dict[BUFFER_NAMES] + if debug: + print("Found buffers:", buffer_names) + + # recover just the buffers while restoring them to fp32 if they were saved in fp16 + buffers = {k: v.float() for k, v in state_dict["module"].items() if k in buffer_names} + param_shapes = state_dict[PARAM_SHAPES] + + # collect parameters that are included in param_shapes + param_names = [] + for s in param_shapes: + for name in s.keys(): + param_names.append(name) + + # update with frozen parameters + frozen_param_shapes = state_dict.get(FROZEN_PARAM_SHAPES, None) + if frozen_param_shapes is not None: + if debug: + print(f"Found frozen_param_shapes: {frozen_param_shapes}") + param_names += list(frozen_param_shapes.keys()) + + # handle shared params + shared_params = [[k, v] for k, v in state_dict["shared_params"].items()] + + ds_version = state_dict.get(DS_VERSION, None) + + frozen_param_fragments = state_dict.get(FROZEN_PARAM_FRAGMENTS, None) + + z_model_state = zero_model_state(buffers=buffers, + param_shapes=param_shapes, + shared_params=shared_params, + ds_version=ds_version, + frozen_param_shapes=frozen_param_shapes, + frozen_param_fragments=frozen_param_fragments) + zero_model_states.append(z_model_state) + + return zero_model_states + + +def parse_optim_states(files, ds_checkpoint_dir): + total_files = len(files) + state_dicts = [] + for f in tqdm(files, desc='Loading checkpoint shards'): + state_dict = torch.load(f, map_location=device, mmap=True, weights_only=False) + # immediately discard the potentially huge 2 optimizer states as we only care for fp32 master weights + # and also handle the case where it was already removed by another helper script + state_dict["optimizer_state_dict"].pop("optimizer_state_dict", None) + state_dicts.append(state_dict) + + if ZERO_STAGE not in state_dicts[0][OPTIMIZER_STATE_DICT]: + raise ValueError(f"{files[0]} is not a zero checkpoint") + zero_stage = state_dicts[0][OPTIMIZER_STATE_DICT][ZERO_STAGE] + world_size = state_dicts[0][OPTIMIZER_STATE_DICT][PARTITION_COUNT] + + # For ZeRO-2 each param group can have different partition_count as data parallelism for expert + # parameters can be different from data parallelism for non-expert parameters. So we can just + # use the max of the partition_count to get the dp world_size. + + if type(world_size) is list: + world_size = max(world_size) + + if world_size != total_files: + raise ValueError( + f"Expected {world_size} of '*_optim_states.pt' under '{ds_checkpoint_dir}' but found {total_files} files. " + "Possibly due to an overwrite of an old checkpoint, or a checkpoint didn't get saved by one or more processes." + ) + + # the groups are named differently in each stage + if zero_stage <= 2: + fp32_groups_key = SINGLE_PARTITION_OF_FP32_GROUPS + elif zero_stage == 3: + fp32_groups_key = FP32_FLAT_GROUPS + else: + raise ValueError(f"unknown zero stage {zero_stage}") + + fp32_flat_groups = [state_dicts[i][OPTIMIZER_STATE_DICT][fp32_groups_key] for i in range(len(state_dicts))] + return zero_stage, world_size, fp32_flat_groups + + +def _get_fp32_state_dict_from_zero_checkpoint(ds_checkpoint_dir, exclude_frozen_parameters): + """ + Returns fp32 state_dict reconstructed from ds checkpoint + + Args: + - ``ds_checkpoint_dir``: path to the deepspeed checkpoint folder (where the optimizer files are) + + """ + print(f"Processing zero checkpoint '{ds_checkpoint_dir}'") + + # parse_model_states rejects AutoEP ZeRO-3 partition-native checkpoints + # before the expensive optimizer-shard load below. + model_files = get_model_state_files(ds_checkpoint_dir) + zero_model_states = parse_model_states(model_files) + print(f'Parsing checkpoint created by deepspeed=={zero_model_states[0].ds_version}') + + optim_files = get_optim_files(ds_checkpoint_dir) + zero_stage, world_size, fp32_flat_groups = parse_optim_states(optim_files, ds_checkpoint_dir) + print(f"Detected checkpoint of type zero stage {zero_stage}, world_size: {world_size}") + + if zero_stage <= 2: + return _get_fp32_state_dict_from_zero2_checkpoint(world_size, fp32_flat_groups, zero_model_states, + exclude_frozen_parameters) + elif zero_stage == 3: + return _get_fp32_state_dict_from_zero3_checkpoint(world_size, fp32_flat_groups, zero_model_states, + exclude_frozen_parameters) + + +def _zero2_merge_frozen_params(state_dict, zero_model_states): + if zero_model_states[0].frozen_param_shapes is None or len(zero_model_states[0].frozen_param_shapes) == 0: + return + + frozen_param_shapes = zero_model_states[0].frozen_param_shapes + frozen_param_fragments = zero_model_states[0].frozen_param_fragments + + if debug: + num_elem = sum(s.numel() for s in frozen_param_shapes.values()) + print(f'rank 0: {FROZEN_PARAM_SHAPES}.numel = {num_elem}') + + wanted_params = len(frozen_param_shapes) + wanted_numel = sum(s.numel() for s in frozen_param_shapes.values()) + avail_numel = sum([p.numel() for p in frozen_param_fragments.values()]) + print(f'Frozen params: Have {avail_numel} numels to process.') + print(f'Frozen params: Need {wanted_numel} numels in {wanted_params} params') + + total_params = 0 + total_numel = 0 + for name, shape in frozen_param_shapes.items(): + total_params += 1 + unpartitioned_numel = shape.numel() + total_numel += unpartitioned_numel + + state_dict[name] = frozen_param_fragments[name] + + if debug: + print(f"{name} full shape: {shape} unpartitioned numel {unpartitioned_numel} ") + + print(f"Reconstructed Frozen fp32 state dict with {total_params} params {total_numel} elements") + + +def _has_callable(obj, fn): + attr = getattr(obj, fn, None) + return callable(attr) + + +def _zero2_merge_trainable_params(state_dict, world_size, fp32_flat_groups, zero_model_states): + param_shapes = zero_model_states[0].param_shapes + + # Reconstruction protocol: + # + # XXX: document this + + if debug: + for i in range(world_size): + for j in range(len(fp32_flat_groups[0])): + print(f"{FP32_FLAT_GROUPS}[{i}][{j}].shape={fp32_flat_groups[i][j].shape}") + + # XXX: memory usage doubles here (zero2) + num_param_groups = len(fp32_flat_groups[0]) + merged_single_partition_of_fp32_groups = [] + for i in range(num_param_groups): + merged_partitions = [sd[i] for sd in fp32_flat_groups] + full_single_fp32_vector = torch.cat(merged_partitions, 0) + merged_single_partition_of_fp32_groups.append(full_single_fp32_vector) + avail_numel = sum( + [full_single_fp32_vector.numel() for full_single_fp32_vector in merged_single_partition_of_fp32_groups]) + + if debug: + wanted_params = sum([len(shapes) for shapes in param_shapes]) + wanted_numel = sum([sum(shape.numel() for shape in shapes.values()) for shapes in param_shapes]) + # not asserting if there is a mismatch due to possible padding + print(f"Have {avail_numel} numels to process.") + print(f"Need {wanted_numel} numels in {wanted_params} params.") + + # params + # XXX: for huge models that can't fit into the host's RAM we will have to recode this to support + # out-of-core computing solution + total_numel = 0 + total_params = 0 + for shapes, full_single_fp32_vector in zip(param_shapes, merged_single_partition_of_fp32_groups): + offset = 0 + avail_numel = full_single_fp32_vector.numel() + for name, shape in shapes.items(): + + unpartitioned_numel = shape.numel() if _has_callable(shape, 'numel') else math.prod(shape) + total_numel += unpartitioned_numel + total_params += 1 + + if debug: + print(f"{name} full shape: {shape} unpartitioned numel {unpartitioned_numel} ") + state_dict[name] = full_single_fp32_vector.narrow(0, offset, unpartitioned_numel).view(shape) + offset += unpartitioned_numel + + # Z2 started to align to 2*world_size to improve nccl performance. Therefore both offset and + # avail_numel can differ by anywhere between 0..2*world_size. Due to two unrelated complex + # paddings performed in the code it's almost impossible to predict the exact numbers w/o the + # live optimizer object, so we are checking that the numbers are within the right range + align_to = 2 * world_size + + def zero2_align(x): + return align_to * math.ceil(x / align_to) + + if debug: + print(f"original offset={offset}, avail_numel={avail_numel}") + + offset = zero2_align(offset) + avail_numel = zero2_align(avail_numel) + + if debug: + print(f"aligned offset={offset}, avail_numel={avail_numel}") + + # Sanity check + if offset != avail_numel: + raise ValueError(f"consumed {offset} numels out of {avail_numel} - something is wrong") + + print(f"Reconstructed fp32 state dict with {total_params} params {total_numel} elements") + + +def _get_fp32_state_dict_from_zero2_checkpoint(world_size, fp32_flat_groups, zero_model_states, + exclude_frozen_parameters): + state_dict = OrderedDict() + + # buffers + buffers = zero_model_states[0].buffers + state_dict.update(buffers) + if debug: + print(f"added {len(buffers)} buffers") + + if not exclude_frozen_parameters: + _zero2_merge_frozen_params(state_dict, zero_model_states) + + _zero2_merge_trainable_params(state_dict, world_size, fp32_flat_groups, zero_model_states) + + # recover shared parameters + for pair in zero_model_states[0].shared_params: + if pair[1] in state_dict: + state_dict[pair[0]] = state_dict[pair[1]] + + return state_dict + + +def zero3_partitioned_param_info(unpartitioned_numel, world_size): + remainder = unpartitioned_numel % world_size + padding_numel = (world_size - remainder) if remainder else 0 + partitioned_numel = math.ceil(unpartitioned_numel / world_size) + return partitioned_numel, padding_numel + + +def _zero3_merge_frozen_params(state_dict, world_size, zero_model_states): + if zero_model_states[0].frozen_param_shapes is None or len(zero_model_states[0].frozen_param_shapes) == 0: + return + + if debug: + for i in range(world_size): + num_elem = sum(s.numel() for s in zero_model_states[i].frozen_param_fragments.values()) + print(f'rank {i}: {FROZEN_PARAM_SHAPES}.numel = {num_elem}') + + frozen_param_shapes = zero_model_states[0].frozen_param_shapes + wanted_params = len(frozen_param_shapes) + wanted_numel = sum(s.numel() for s in frozen_param_shapes.values()) + avail_numel = sum([p.numel() for p in zero_model_states[0].frozen_param_fragments.values()]) * world_size + print(f'Frozen params: Have {avail_numel} numels to process.') + print(f'Frozen params: Need {wanted_numel} numels in {wanted_params} params') + + total_params = 0 + total_numel = 0 + for name, shape in zero_model_states[0].frozen_param_shapes.items(): + total_params += 1 + unpartitioned_numel = shape.numel() + total_numel += unpartitioned_numel + + param_frags = tuple(model_state.frozen_param_fragments[name] for model_state in zero_model_states) + state_dict[name] = torch.cat(param_frags, 0).narrow(0, 0, unpartitioned_numel).view(shape) + + partitioned_numel, partitioned_padding_numel = zero3_partitioned_param_info(unpartitioned_numel, world_size) + + if debug: + print( + f"Frozen params: {total_params} {name} full shape: {shape} partition0 numel={partitioned_numel} partitioned_padding_numel={partitioned_padding_numel}" + ) + + print(f"Reconstructed Frozen fp32 state dict with {total_params} params {total_numel} elements") + + +class GatheredTensor: + """ + A pseudo tensor that collects partitioned weights. + It is more memory efficient when there are multiple groups. + """ + + def __init__(self, flat_groups, flat_groups_offset, offset, partitioned_numel, shape): + self.flat_groups = flat_groups + self.flat_groups_offset = flat_groups_offset + self.offset = offset + self.partitioned_numel = partitioned_numel + self.shape = shape + self.dtype = self.flat_groups[0][0].dtype + + def contiguous(self): + """ + Merge partitioned weights from flat_groups into a single tensor. + """ + end_idx = self.offset + self.partitioned_numel + world_size = len(self.flat_groups) + pad_flat_param_chunks = [] + + for rank_i in range(world_size): + # for each rank, we need to collect weights from related group/groups + flat_groups_at_rank_i = self.flat_groups[rank_i] + start_group_id = None + end_group_id = None + for group_id in range(len(self.flat_groups_offset)): + if self.flat_groups_offset[group_id] <= self.offset < self.flat_groups_offset[group_id + 1]: + start_group_id = group_id + if self.flat_groups_offset[group_id] < end_idx <= self.flat_groups_offset[group_id + 1]: + end_group_id = group_id + break + # collect weights from related group/groups + for group_id in range(start_group_id, end_group_id + 1): + flat_tensor = flat_groups_at_rank_i[group_id] + start_offset = self.offset - self.flat_groups_offset[group_id] + end_offset = min(end_idx, self.flat_groups_offset[group_id + 1]) - self.flat_groups_offset[group_id] + pad_flat_param_chunks.append(flat_tensor[start_offset:end_offset]) + + # collect weights from all ranks + pad_flat_param = torch.cat(pad_flat_param_chunks, dim=0) + param = pad_flat_param[:self.shape.numel()].view(self.shape).contiguous() + return param + + +def _zero3_merge_trainable_params(state_dict, world_size, fp32_flat_groups, zero_model_states): + param_shapes = zero_model_states[0].param_shapes + avail_numel = sum([flat_group.numel() for flat_group in fp32_flat_groups[0]]) * world_size + + # Reconstruction protocol: For zero3 we need to zip the partitions together at boundary of each + # param, re-consolidating each param, while dealing with padding if any + + # merge list of dicts, preserving order + param_shapes = {k: v for d in param_shapes for k, v in d.items()} + + if debug: + for i in range(world_size): + print(f"{FP32_FLAT_GROUPS}[{i}].shape={fp32_flat_groups[i].shape}") + + wanted_params = len(param_shapes) + wanted_numel = sum(shape.numel() for shape in param_shapes.values()) + # not asserting if there is a mismatch due to possible padding + avail_numel = fp32_flat_groups[0].numel() * world_size + print(f"Trainable params: Have {avail_numel} numels to process.") + print(f"Trainable params: Need {wanted_numel} numels in {wanted_params} params.") + + # params + # XXX: for huge models that can't fit into the host's RAM we will have to recode this to support + # out-of-core computing solution + offset = 0 + total_numel = 0 + total_params = 0 + flat_groups_offset = [0] + list(np.cumsum([flat_tensor.numel() for flat_tensor in fp32_flat_groups[0]])) + for name, shape in tqdm(param_shapes.items(), desc='Gathering sharded weights'): + unpartitioned_numel = shape.numel() + total_numel += unpartitioned_numel + total_params += 1 + partitioned_numel, partitioned_padding_numel = zero3_partitioned_param_info(unpartitioned_numel, world_size) + + if debug: + print( + f"Trainable params: {total_params} {name} full shape: {shape} partition0 numel={partitioned_numel} partitioned_padding_numel={partitioned_padding_numel}" + ) + + # memory efficient tensor + tensor = GatheredTensor(fp32_flat_groups, flat_groups_offset, offset, partitioned_numel, shape) + state_dict[name] = tensor + offset += partitioned_numel + + offset *= world_size + + # Sanity check + if offset != avail_numel: + raise ValueError(f"consumed {offset} numels out of {avail_numel} - something is wrong") + + print(f"Reconstructed Trainable fp32 state dict with {total_params} params {total_numel} elements") + + +def _get_fp32_state_dict_from_zero3_checkpoint(world_size, fp32_flat_groups, zero_model_states, + exclude_frozen_parameters): + state_dict = OrderedDict() + + # buffers + buffers = zero_model_states[0].buffers + state_dict.update(buffers) + if debug: + print(f"added {len(buffers)} buffers") + + if not exclude_frozen_parameters: + _zero3_merge_frozen_params(state_dict, world_size, zero_model_states) + + _zero3_merge_trainable_params(state_dict, world_size, fp32_flat_groups, zero_model_states) + + # recover shared parameters + for pair in zero_model_states[0].shared_params: + if pair[1] in state_dict: + state_dict[pair[0]] = state_dict[pair[1]] + + return state_dict + + +def to_torch_tensor(state_dict, return_empty_tensor=False): + """ + Convert state_dict of GatheredTensor to torch tensor + """ + torch_state_dict = {} + converted_tensors = {} + for name, tensor in state_dict.items(): + tensor_id = id(tensor) + if tensor_id in converted_tensors: # shared tensors + shared_tensor = torch_state_dict[converted_tensors[tensor_id]] + torch_state_dict[name] = shared_tensor + else: + converted_tensors[tensor_id] = name + if return_empty_tensor: + torch_state_dict[name] = torch.empty(tensor.shape, dtype=tensor.dtype) + else: + torch_state_dict[name] = tensor.contiguous() + return torch_state_dict + + +def get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir, + tag=None, + exclude_frozen_parameters=False, + lazy_mode=False): + """ + Convert ZeRO 2 or 3 checkpoint into a single fp32 consolidated state_dict that can be loaded with + ``load_state_dict()`` and used for training without DeepSpeed or shared with others, for example + via a model hub. + + Args: + - ``checkpoint_dir``: path to the desired checkpoint folder + - ``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`` + - ``exclude_frozen_parameters``: exclude frozen parameters + - ``lazy_mode``: get state_dict in lazy mode. It returns a dict of pesduo tensor instead of torch tensor, which is more memory efficient. + Convert the pesduo tensor to torch tensor by ``.contiguous()`` + + Returns: + - pytorch ``state_dict`` + + A typical usage might be :: + + from deepspeed.utils.zero_to_fp32 import get_fp32_state_dict_from_zero_checkpoint + # do the training and checkpoint saving + state_dict = get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir) # already on cpu + model = model.cpu() # move to cpu + model.load_state_dict(state_dict) + # submit to model hub or save the model to share with others + + In this example the ``model`` will no longer be usable in the deepspeed context of the same + application. i.e. you will need to re-initialize the deepspeed engine, since + ``model.load_state_dict(state_dict)`` will remove all the deepspeed magic from it. + + If you want it all done for you, use ``load_state_dict_from_zero_checkpoint`` instead. + + Note: the above usage may not work if your application doesn't have sufficient free CPU memory. + You may need to use the offline approach using the ``zero_to_fp32.py`` script that is saved with + the checkpoint. Or you can load state_dict in lazy mode :: + + from deepspeed.utils.zero_to_fp32 import get_fp32_state_dict_from_zero_checkpoint + state_dict = get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir, lazy_mode=True) # not on cpu + for name, lazy_tensor in state_dict.item(): + tensor = lazy_tensor.contiguous() # to cpu + print(name, tensor) + # del tensor to release memory if it no longer in use + """ + if tag is None: + latest_path = os.path.join(checkpoint_dir, 'latest') + if os.path.isfile(latest_path): + with open(latest_path, 'r') as fd: + tag = fd.read().strip() + else: + raise ValueError(f"Unable to find 'latest' file at {latest_path}") + + ds_checkpoint_dir = os.path.join(checkpoint_dir, tag) + + if not os.path.isdir(ds_checkpoint_dir): + raise FileNotFoundError(f"Directory '{ds_checkpoint_dir}' doesn't exist") + + state_dict = _get_fp32_state_dict_from_zero_checkpoint(ds_checkpoint_dir, exclude_frozen_parameters) + if lazy_mode: + return state_dict + else: + return to_torch_tensor(state_dict) + + +def convert_zero_checkpoint_to_fp32_state_dict(checkpoint_dir, + output_dir, + max_shard_size="5GB", + safe_serialization=False, + tag=None, + exclude_frozen_parameters=False): + """ + Convert ZeRO 2 or 3 checkpoint into a single fp32 consolidated ``state_dict`` file that can be + loaded with ``torch.load(file)`` + ``load_state_dict()`` and used for training without DeepSpeed. + + Args: + - ``checkpoint_dir``: path to the desired checkpoint folder. (one that contains the tag-folder, like ``global_step14``) + - ``output_dir``: directory to the pytorch fp32 state_dict output files + - ``max_shard_size``: the maximum size for a checkpoint before being sharded, default value is 5GB + - ``safe_serialization``: whether to save the model using `safetensors` or the traditional PyTorch way (that uses `pickle`). + - ``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`` + - ``exclude_frozen_parameters``: exclude frozen parameters + """ + + # Dependency pre-check + if safe_serialization: + try: + from safetensors.torch import save_file + except ImportError: + print('If you want to use `safe_serialization`, please `pip install safetensors`') + raise + if max_shard_size is not None: + try: + from huggingface_hub import split_torch_state_dict_into_shards + except ImportError: + print('If you want to use `max_shard_size`, please `pip install huggingface_hub`') + raise + + # Convert zero checkpoint to state_dict + state_dict = get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir, + tag, + exclude_frozen_parameters, + lazy_mode=True) + + # Shard the model if it is too big. + weights_name = "model.safetensors" if safe_serialization else "pytorch_model.bin" + if max_shard_size is not None: + filename_pattern = weights_name.replace(".bin", "{suffix}.bin").replace(".safetensors", "{suffix}.safetensors") + # an memory-efficient approach for sharding + empty_state_dict = to_torch_tensor(state_dict, return_empty_tensor=True) + state_dict_split = split_torch_state_dict_into_shards(empty_state_dict, + filename_pattern=filename_pattern, + max_shard_size=max_shard_size) + else: + from collections import namedtuple + StateDictSplit = namedtuple("StateDictSplit", ["is_sharded", "filename_to_tensors"]) + state_dict_split = StateDictSplit(is_sharded=False, + filename_to_tensors={weights_name: list(state_dict.keys())}) + + # Save the model by shard + os.makedirs(output_dir, exist_ok=True) + filename_to_tensors = state_dict_split.filename_to_tensors.items() + for shard_file, tensors in tqdm(filename_to_tensors, desc="Saving checkpoint shards"): + shard_state_dict = {tensor_name: state_dict[tensor_name] for tensor_name in tensors} + shard_state_dict = to_torch_tensor(shard_state_dict) + output_path = os.path.join(output_dir, shard_file) + if safe_serialization: + save_file(shard_state_dict, output_path, metadata={"format": "pt"}) + else: + torch.save(shard_state_dict, output_path) + # release the memory of current shard + for tensor_name in list(shard_state_dict.keys()): + del state_dict[tensor_name] + del shard_state_dict[tensor_name] + del shard_state_dict + gc.collect() + + # Save index if sharded + if state_dict_split.is_sharded: + index = { + "metadata": state_dict_split.metadata, + "weight_map": state_dict_split.tensor_to_filename, + } + save_index_file = "model.safetensors.index.json" if safe_serialization else "pytorch_model.bin.index.json" + save_index_file = os.path.join(output_dir, save_index_file) + with open(save_index_file, "w", encoding="utf-8") as f: + content = json.dumps(index, indent=2, sort_keys=True) + "\n" + f.write(content) + + +def load_state_dict_from_zero_checkpoint(model, checkpoint_dir, tag=None): + """ + 1. Put the provided model to cpu + 2. Convert ZeRO 2 or 3 checkpoint into a single fp32 consolidated ``state_dict`` + 3. Load it into the provided model + + Args: + - ``model``: the model object to update + - ``checkpoint_dir``: path to the desired checkpoint folder. (one that contains the tag-folder, like ``global_step14``) + - ``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`` + + Returns: + - ``model`: modified model + + Make sure you have plenty of CPU memory available before you call this function. If you don't + have enough use the ``zero_to_fp32.py`` utility to do the conversion. You will find it + conveniently placed for you in the checkpoint folder. + + A typical usage might be :: + + from deepspeed.utils.zero_to_fp32 import load_state_dict_from_zero_checkpoint + model = load_state_dict_from_zero_checkpoint(trainer.model, checkpoint_dir) + # submit to model hub or save the model to share with others + + Note, that once this was run, the ``model`` will no longer be usable in the deepspeed context + of the same application. i.e. you will need to re-initialize the deepspeed engine, since + ``model.load_state_dict(state_dict)`` will remove all the deepspeed magic from it. + + """ + logger.info("Extracting fp32 weights") + state_dict = get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir, tag) + + logger.info("Overwriting model with fp32 weights") + model = model.cpu() + model.load_state_dict(state_dict, strict=False) + + return model + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument("checkpoint_dir", + type=str, + help="path to the desired checkpoint folder, e.g., path/checkpoint-12") + parser.add_argument("output_dir", + type=str, + help="directory to the pytorch fp32 state_dict output files" + "(e.g. path/checkpoint-12-output/)") + parser.add_argument( + "--max_shard_size", + type=str, + default="5GB", + help="The maximum size for a checkpoint before being sharded. Checkpoints shard will then be each of size" + "lower than this size. If expressed as a string, needs to be digits followed by a unit (like `5MB`" + "We default it to 5GB in order for models to be able to run easily on free-tier google colab instances" + "without CPU OOM issues.") + parser.add_argument( + "--safe_serialization", + default=False, + action='store_true', + help="Whether to save the model using `safetensors` or the traditional PyTorch way (that uses `pickle`).") + parser.add_argument("-t", + "--tag", + type=str, + default=None, + help="checkpoint tag used as a unique identifier for checkpoint. e.g., global_step1") + parser.add_argument("--exclude_frozen_parameters", action='store_true', help="exclude frozen parameters") + parser.add_argument("-d", "--debug", action='store_true', help="enable debug") + args = parser.parse_args() + + debug = args.debug + + convert_zero_checkpoint_to_fp32_state_dict(args.checkpoint_dir, + args.output_dir, + max_shard_size=args.max_shard_size, + safe_serialization=args.safe_serialization, + tag=args.tag, + exclude_frozen_parameters=args.exclude_frozen_parameters) diff --git a/qwen3/distillm_adaptive_sfkl/checkpoint-314/README.md b/qwen3/distillm_adaptive_sfkl/checkpoint-314/README.md new file mode 100644 index 0000000000000000000000000000000000000000..776f98d43659dd923b8c3e5649c5ae66d1f99f3e --- /dev/null +++ b/qwen3/distillm_adaptive_sfkl/checkpoint-314/README.md @@ -0,0 +1,208 @@ +--- +base_model: Qwen/Qwen3-0.6B +library_name: peft +pipeline_tag: text-generation +tags: +- base_model:adapter:Qwen/Qwen3-0.6B +- llama-factory +- lora +- transformers +--- + +# Model Card for Model ID + + + + + +## Model Details + +### Model Description + + + + + +- **Developed by:** [More Information Needed] +- **Funded by [optional]:** [More Information Needed] +- **Shared by [optional]:** [More Information Needed] +- **Model type:** [More Information Needed] +- **Language(s) (NLP):** [More Information Needed] +- **License:** [More Information Needed] +- **Finetuned from model [optional]:** [More Information Needed] + +### Model Sources [optional] + + + +- **Repository:** [More Information Needed] +- **Paper [optional]:** [More Information Needed] +- **Demo [optional]:** [More Information Needed] + +## Uses + + + +### Direct Use + + + +[More Information Needed] + +### Downstream Use [optional] + + + +[More Information Needed] + +### Out-of-Scope Use + + + +[More Information Needed] + +## Bias, Risks, and Limitations + + + +[More Information Needed] + +### Recommendations + + + +Users (both direct and downstream) should be made aware of the risks, biases and limitations of the model. More information needed for further recommendations. + +## How to Get Started with the Model + +Use the code below to get started with the model. + +[More Information Needed] + +## Training Details + +### Training Data + + + +[More Information Needed] + +### Training Procedure + + + +#### Preprocessing [optional] + +[More Information Needed] + + +#### Training Hyperparameters + +- **Training regime:** [More Information Needed] + +#### Speeds, Sizes, Times [optional] + + + +[More Information Needed] + +## Evaluation + + + +### Testing Data, Factors & Metrics + +#### Testing Data + + + +[More Information Needed] + +#### Factors + + + +[More Information Needed] + +#### Metrics + + + +[More Information Needed] + +### Results + +[More Information Needed] + +#### Summary + + + +## Model Examination [optional] + + + +[More Information Needed] + +## Environmental Impact + + + +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). + +- **Hardware Type:** [More Information Needed] +- **Hours used:** [More Information Needed] +- **Cloud Provider:** [More Information Needed] +- **Compute Region:** [More Information Needed] +- **Carbon Emitted:** [More Information Needed] + +## Technical Specifications [optional] + +### Model Architecture and Objective + +[More Information Needed] + +### Compute Infrastructure + +[More Information Needed] + +#### Hardware + +[More Information Needed] + +#### Software + +[More Information Needed] + +## Citation [optional] + + + +**BibTeX:** + +[More Information Needed] + +**APA:** + +[More Information Needed] + +## Glossary [optional] + + + +[More Information Needed] + +## More Information [optional] + +[More Information Needed] + +## Model Card Authors [optional] + +[More Information Needed] + +## Model Card Contact + +[More Information Needed] +### Framework versions + +- PEFT 0.18.1 \ No newline at end of file diff --git a/qwen3/distillm_adaptive_sfkl/checkpoint-314/adapter_config.json b/qwen3/distillm_adaptive_sfkl/checkpoint-314/adapter_config.json new file mode 100644 index 0000000000000000000000000000000000000000..d88d3ddd2a1fe81f4cf32eb7f116cfcaecff483e --- /dev/null +++ b/qwen3/distillm_adaptive_sfkl/checkpoint-314/adapter_config.json @@ -0,0 +1,46 @@ +{ + "alora_invocation_tokens": null, + "alpha_pattern": {}, + "arrow_config": null, + "auto_mapping": null, + "base_model_name_or_path": "Qwen/Qwen3-0.6B", + "bias": "none", + "corda_config": null, + "ensure_weight_tying": false, + "eva_config": null, + "exclude_modules": null, + "fan_in_fan_out": false, + "inference_mode": true, + "init_lora_weights": true, + "layer_replication": null, + "layers_pattern": null, + "layers_to_transform": null, + "loftq_config": {}, + "lora_alpha": 64, + "lora_bias": false, + "lora_dropout": 0.1, + "megatron_config": null, + "megatron_core": "megatron.core", + "modules_to_save": null, + "peft_type": "LORA", + "peft_version": "0.18.1", + "qalora_group_size": 16, + "r": 32, + "rank_pattern": {}, + "revision": null, + "target_modules": [ + "gate_proj", + "o_proj", + "down_proj", + "v_proj", + "q_proj", + "up_proj", + "k_proj" + ], + "target_parameters": null, + "task_type": "CAUSAL_LM", + "trainable_token_indices": null, + "use_dora": false, + "use_qalora": false, + "use_rslora": false +} \ No newline at end of file diff --git a/qwen3/distillm_adaptive_sfkl/checkpoint-314/adapter_model.safetensors b/qwen3/distillm_adaptive_sfkl/checkpoint-314/adapter_model.safetensors new file mode 100644 index 0000000000000000000000000000000000000000..5d32a50fe0b6e1b4144cd92235a437b2c4306cb3 --- /dev/null +++ b/qwen3/distillm_adaptive_sfkl/checkpoint-314/adapter_model.safetensors @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4fd31ad3c06c6ba32fe311104350ef79b3b7f71d978406e20a89363c362ed6b8 +size 40422560 diff --git a/qwen3/distillm_adaptive_sfkl/checkpoint-314/chat_template.jinja b/qwen3/distillm_adaptive_sfkl/checkpoint-314/chat_template.jinja new file mode 100644 index 0000000000000000000000000000000000000000..01be9b307daa2d425f7c168c9fb145a286e0afb4 --- /dev/null +++ b/qwen3/distillm_adaptive_sfkl/checkpoint-314/chat_template.jinja @@ -0,0 +1,89 @@ +{%- if tools %} + {{- '<|im_start|>system\n' }} + {%- if messages[0].role == 'system' %} + {{- messages[0].content + '\n\n' }} + {%- endif %} + {{- "# Tools\n\nYou may call one or more functions to assist with the user query.\n\nYou are provided with function signatures within XML tags:\n" }} + {%- for tool in tools %} + {{- "\n" }} + {{- tool | tojson }} + {%- endfor %} + {{- "\n\n\nFor each function call, return a json object with function name and arguments within XML tags:\n\n{\"name\": , \"arguments\": }\n<|im_end|>\n" }} +{%- else %} + {%- if messages[0].role == 'system' %} + {{- '<|im_start|>system\n' + messages[0].content + '<|im_end|>\n' }} + {%- endif %} +{%- endif %} +{%- set ns = namespace(multi_step_tool=true, last_query_index=messages|length - 1) %} +{%- for message in messages[::-1] %} + {%- set index = (messages|length - 1) - loop.index0 %} + {%- if ns.multi_step_tool and message.role == "user" and message.content is string and not(message.content.startswith('') and message.content.endswith('')) %} + {%- set ns.multi_step_tool = false %} + {%- set ns.last_query_index = index %} + {%- endif %} +{%- endfor %} +{%- for message in messages %} + {%- if message.content is string %} + {%- set content = message.content %} + {%- else %} + {%- set content = '' %} + {%- endif %} + {%- if (message.role == "user") or (message.role == "system" and not loop.first) %} + {{- '<|im_start|>' + message.role + '\n' + content + '<|im_end|>' + '\n' }} + {%- elif message.role == "assistant" %} + {%- set reasoning_content = '' %} + {%- if message.reasoning_content is string %} + {%- set reasoning_content = message.reasoning_content %} + {%- else %} + {%- if '' in content %} + {%- set reasoning_content = content.split('')[0].rstrip('\n').split('')[-1].lstrip('\n') %} + {%- set content = content.split('')[-1].lstrip('\n') %} + {%- endif %} + {%- endif %} + {%- if loop.index0 > ns.last_query_index %} + {%- if loop.last or (not loop.last and reasoning_content) %} + {{- '<|im_start|>' + message.role + '\n\n' + reasoning_content.strip('\n') + '\n\n\n' + content.lstrip('\n') }} + {%- else %} + {{- '<|im_start|>' + message.role + '\n' + content }} + {%- endif %} + {%- else %} + {{- '<|im_start|>' + message.role + '\n' + content }} + {%- endif %} + {%- if message.tool_calls %} + {%- for tool_call in message.tool_calls %} + {%- if (loop.first and content) or (not loop.first) %} + {{- '\n' }} + {%- endif %} + {%- if tool_call.function %} + {%- set tool_call = tool_call.function %} + {%- endif %} + {{- '\n{"name": "' }} + {{- tool_call.name }} + {{- '", "arguments": ' }} + {%- if tool_call.arguments is string %} + {{- tool_call.arguments }} + {%- else %} + {{- tool_call.arguments | tojson }} + {%- endif %} + {{- '}\n' }} + {%- endfor %} + {%- endif %} + {{- '<|im_end|>\n' }} + {%- elif message.role == "tool" %} + {%- if loop.first or (messages[loop.index0 - 1].role != "tool") %} + {{- '<|im_start|>user' }} + {%- endif %} + {{- '\n\n' }} + {{- content }} + {{- '\n' }} + {%- if loop.last or (messages[loop.index0 + 1].role != "tool") %} + {{- '<|im_end|>\n' }} + {%- endif %} + {%- endif %} +{%- endfor %} +{%- if add_generation_prompt %} + {{- '<|im_start|>assistant\n' }} + {%- if enable_thinking is defined and enable_thinking is false %} + {{- '\n\n\n\n' }} + {%- endif %} +{%- endif %} \ No newline at end of file diff --git a/qwen3/distillm_adaptive_sfkl/checkpoint-314/distillm_state_rank0.pt b/qwen3/distillm_adaptive_sfkl/checkpoint-314/distillm_state_rank0.pt new file mode 100644 index 0000000000000000000000000000000000000000..c92ac759103ef6b2a0cb377b030a5ee272ca1dbc --- /dev/null +++ b/qwen3/distillm_adaptive_sfkl/checkpoint-314/distillm_state_rank0.pt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9208c430a8d43fa0e53ede8a6e5eab75fb565f1ad94e1b66dd5a8fad4f2d279d +size 9403 diff --git a/qwen3/distillm_adaptive_sfkl/checkpoint-314/distillm_state_rank1.pt b/qwen3/distillm_adaptive_sfkl/checkpoint-314/distillm_state_rank1.pt new file mode 100644 index 0000000000000000000000000000000000000000..16e0bb3962fa3f007370bb097abbec17d52cdc05 --- /dev/null +++ b/qwen3/distillm_adaptive_sfkl/checkpoint-314/distillm_state_rank1.pt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:06c0f9ff15c6f6d1dc5269643a7219fdaa4612ecfea5313c5b9359e6d4f4e8a3 +size 9339 diff --git a/qwen3/distillm_adaptive_sfkl/checkpoint-314/global_step314/bf16_zero_pp_rank_0_mp_rank_00_optim_states.pt b/qwen3/distillm_adaptive_sfkl/checkpoint-314/global_step314/bf16_zero_pp_rank_0_mp_rank_00_optim_states.pt new file mode 100644 index 0000000000000000000000000000000000000000..014b686c47a8d627fb2d342a3bb19f6c4ce5bf13 --- /dev/null +++ b/qwen3/distillm_adaptive_sfkl/checkpoint-314/global_step314/bf16_zero_pp_rank_0_mp_rank_00_optim_states.pt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1bb7a56206ec184dbcfe3370795df6c6b26b16cfe15e4a5c9d96dcf0ae02e829 +size 121135557 diff --git a/qwen3/distillm_adaptive_sfkl/checkpoint-314/global_step314/bf16_zero_pp_rank_1_mp_rank_00_optim_states.pt b/qwen3/distillm_adaptive_sfkl/checkpoint-314/global_step314/bf16_zero_pp_rank_1_mp_rank_00_optim_states.pt new file mode 100644 index 0000000000000000000000000000000000000000..95f042ba4456ef3e294347567a93e5d6fb71fa21 --- /dev/null +++ b/qwen3/distillm_adaptive_sfkl/checkpoint-314/global_step314/bf16_zero_pp_rank_1_mp_rank_00_optim_states.pt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:40bb47e84ae23c36d478d29a33a002027f11197936156de3c8d0b5aadc1b533d +size 121135749 diff --git a/qwen3/distillm_adaptive_sfkl/checkpoint-314/global_step314/mp_rank_00_model_states.pt b/qwen3/distillm_adaptive_sfkl/checkpoint-314/global_step314/mp_rank_00_model_states.pt new file mode 100644 index 0000000000000000000000000000000000000000..545a097c0a57ff9365f05b2c6d9485eafd8c0ab0 --- /dev/null +++ b/qwen3/distillm_adaptive_sfkl/checkpoint-314/global_step314/mp_rank_00_model_states.pt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b88bce20f8997184325ad4c5820b1f0ba9771b61b725ec98f3f53ed6da5bc319 +size 351841765 diff --git a/qwen3/distillm_adaptive_sfkl/checkpoint-314/latest b/qwen3/distillm_adaptive_sfkl/checkpoint-314/latest new file mode 100644 index 0000000000000000000000000000000000000000..a9786513b1a514db2c3a9da7408844635663d55d --- /dev/null +++ b/qwen3/distillm_adaptive_sfkl/checkpoint-314/latest @@ -0,0 +1 @@ +global_step314 \ No newline at end of file diff --git a/qwen3/distillm_adaptive_sfkl/checkpoint-314/rng_state_0.pth b/qwen3/distillm_adaptive_sfkl/checkpoint-314/rng_state_0.pth new file mode 100644 index 0000000000000000000000000000000000000000..4e26866d298b00dd623ba4a091e965dfa4ed3760 --- /dev/null +++ b/qwen3/distillm_adaptive_sfkl/checkpoint-314/rng_state_0.pth @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:addc9cd09c422791daca0c22561ff8b62387ed0000b8a8d0870193b03682d5ea +size 14917 diff --git a/qwen3/distillm_adaptive_sfkl/checkpoint-314/rng_state_1.pth b/qwen3/distillm_adaptive_sfkl/checkpoint-314/rng_state_1.pth new file mode 100644 index 0000000000000000000000000000000000000000..4b37f01bd6e69f7ee3e287a310189b0b1ed52236 --- /dev/null +++ b/qwen3/distillm_adaptive_sfkl/checkpoint-314/rng_state_1.pth @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:224ceacd3737b01636f96f069023026c038f76b816e103d596860a265f268d13 +size 14917 diff --git a/qwen3/distillm_adaptive_sfkl/checkpoint-314/scheduler.pt b/qwen3/distillm_adaptive_sfkl/checkpoint-314/scheduler.pt new file mode 100644 index 0000000000000000000000000000000000000000..a3cb460802cda03bf0833a98a6f1428a3fd4f585 --- /dev/null +++ b/qwen3/distillm_adaptive_sfkl/checkpoint-314/scheduler.pt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:17e254b5642bb75983fd5105bec79b35376cfbc99d29702287668b8767d46149 +size 1465 diff --git a/qwen3/distillm_adaptive_sfkl/checkpoint-314/tokenizer.json b/qwen3/distillm_adaptive_sfkl/checkpoint-314/tokenizer.json new file mode 100644 index 0000000000000000000000000000000000000000..c7afbed2efcdf019f88ab0572ec29d3bf595dfe2 --- /dev/null +++ b/qwen3/distillm_adaptive_sfkl/checkpoint-314/tokenizer.json @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:be75606093db2094d7cd20f3c2f385c212750648bd6ea4fb2bf507a6a4c55506 +size 11422650 diff --git a/qwen3/distillm_adaptive_sfkl/checkpoint-314/tokenizer_config.json b/qwen3/distillm_adaptive_sfkl/checkpoint-314/tokenizer_config.json new file mode 100644 index 0000000000000000000000000000000000000000..6623da03457d79d2cd4af9557e9f31407cdb835c --- /dev/null +++ b/qwen3/distillm_adaptive_sfkl/checkpoint-314/tokenizer_config.json @@ -0,0 +1,31 @@ +{ + "add_prefix_space": false, + "backend": "tokenizers", + "bos_token": null, + "clean_up_tokenization_spaces": false, + "eos_token": "<|im_end|>", + "errors": "replace", + "extra_special_tokens": [ + "<|im_start|>", + "<|im_end|>", + "<|object_ref_start|>", + "<|object_ref_end|>", + "<|box_start|>", + "<|box_end|>", + "<|quad_start|>", + "<|quad_end|>", + "<|vision_start|>", + "<|vision_end|>", + "<|vision_pad|>", + "<|image_pad|>", + "<|video_pad|>" + ], + "is_local": false, + "local_files_only": false, + "model_max_length": 131072, + "pad_token": "<|endoftext|>", + "padding_side": "right", + "split_special_tokens": false, + "tokenizer_class": "Qwen2Tokenizer", + "unk_token": null +} diff --git a/qwen3/distillm_adaptive_sfkl/checkpoint-314/trainer_state.json b/qwen3/distillm_adaptive_sfkl/checkpoint-314/trainer_state.json new file mode 100644 index 0000000000000000000000000000000000000000..b1518143e28e6df62fb5dfacdb228ea2cdc68e29 --- /dev/null +++ b/qwen3/distillm_adaptive_sfkl/checkpoint-314/trainer_state.json @@ -0,0 +1,169 @@ +{ + "best_global_step": null, + "best_metric": null, + "best_model_checkpoint": null, + "epoch": 1.0, + "eval_steps": 500, + "global_step": 314, + "is_hyper_param_search": false, + "is_local_process_zero": true, + "is_world_process_zero": true, + "log_history": [ + { + "distillm_initial_generator_count": 1712.0, + "distillm_initial_generator_exact_match": 0.0, + "distillm_initial_generator_rouge1": 16.2149, + "distillm_initial_generator_rouge2": 3.2276, + "distillm_initial_generator_rougeL": 11.6725, + "distillm_initial_loss": 2.494271755218506, + "distillm_initial_runtime": 2988.1286, + "distillm_initial_samples_per_second": 1.143, + "distillm_initial_selector_accuracy": 52.278, + "distillm_initial_selector_count": 1712.0, + "distillm_initial_steps_per_second": 0.036, + "epoch": 0, + "step": 0 + }, + { + "epoch": 0.06382130035899482, + "grad_norm": 1.4179933071136475, + "learning_rate": 9.996390385474569e-05, + "loss": 0.360275936126709, + "step": 20 + }, + { + "epoch": 0.12764260071798963, + "grad_norm": 0.6145927309989929, + "learning_rate": 9.984797509888031e-05, + "loss": 0.0921450138092041, + "step": 40 + }, + { + "epoch": 0.19146390107698444, + "grad_norm": 0.949298083782196, + "learning_rate": 9.965229938050925e-05, + "loss": 0.06155582666397095, + "step": 60 + }, + { + "epoch": 0.25528520143597927, + "grad_norm": 0.32781288027763367, + "learning_rate": 9.937719005663432e-05, + "loss": 0.03148526251316071, + "step": 80 + }, + { + "epoch": 0.3191065017949741, + "grad_norm": 0.42831170558929443, + "learning_rate": 9.902308769000724e-05, + "loss": 0.0304107666015625, + "step": 100 + }, + { + "epoch": 0.3829278021539689, + "grad_norm": 0.37467315793037415, + "learning_rate": 9.859055934360789e-05, + "loss": 0.018133948743343353, + "step": 120 + }, + { + "epoch": 0.4467491025129637, + "grad_norm": 0.26231899857521057, + "learning_rate": 9.808029767254437e-05, + "loss": 0.023359841108322142, + "step": 140 + }, + { + "epoch": 0.5105704028719585, + "grad_norm": 0.23304614424705505, + "learning_rate": 9.749311981482817e-05, + "loss": 0.015377765893936158, + "step": 160 + }, + { + "epoch": 0.5743917032309533, + "grad_norm": 4.825753688812256, + "learning_rate": 9.682996608280154e-05, + "loss": 0.0134853795170784, + "step": 180 + }, + { + "epoch": 0.6382130035899481, + "grad_norm": 0.29226061701774597, + "learning_rate": 9.609189845731207e-05, + "loss": 0.022103385627269746, + "step": 200 + }, + { + "epoch": 0.702034303948943, + "grad_norm": 0.1759956330060959, + "learning_rate": 9.52800988870462e-05, + "loss": 0.011787685751914977, + "step": 220 + }, + { + "epoch": 0.7658556043079378, + "grad_norm": 0.18942032754421234, + "learning_rate": 9.439586739574513e-05, + "loss": 0.009058185666799546, + "step": 240 + }, + { + "epoch": 0.8296769046669326, + "grad_norm": 0.2657412886619568, + "learning_rate": 9.344062000033414e-05, + "loss": 0.009212753176689148, + "step": 260 + }, + { + "epoch": 0.8934982050259274, + "grad_norm": 0.28189197182655334, + "learning_rate": 9.241588644329919e-05, + "loss": 0.009374459087848664, + "step": 280 + }, + { + "epoch": 0.9573195053849222, + "grad_norm": 0.22191843390464783, + "learning_rate": 9.132330774294252e-05, + "loss": 0.009671492874622345, + "step": 300 + }, + { + "epoch": 1.0, + "eval_generator_count": 1712.0, + "eval_generator_exact_match": 90.0701, + "eval_generator_rouge1": 99.4297, + "eval_generator_rouge2": 99.1758, + "eval_generator_rougeL": 99.0503, + "eval_loss": 0.007805492263287306, + "eval_runtime": 601.5417, + "eval_samples_per_second": 5.675, + "eval_selector_accuracy": 95.5607, + "eval_selector_count": 1712.0, + "eval_steps_per_second": 0.178, + "step": 314 + } + ], + "logging_steps": 20, + "max_steps": 1570, + "num_input_tokens_seen": 0, + "num_train_epochs": 5, + "save_steps": 500, + "stateful_callbacks": { + "TrainerControl": { + "args": { + "should_epoch_stop": false, + "should_evaluate": false, + "should_log": false, + "should_save": true, + "should_training_stop": false + }, + "attributes": {} + } + }, + "total_flos": 1.172842003562496e+16, + "train_batch_size": 2, + "trial_name": null, + "trial_params": null +} diff --git a/qwen3/distillm_adaptive_sfkl/checkpoint-314/training_args.bin b/qwen3/distillm_adaptive_sfkl/checkpoint-314/training_args.bin new file mode 100644 index 0000000000000000000000000000000000000000..9965b3704c5694d942c823f03f32ef4aa365d5a2 --- /dev/null +++ b/qwen3/distillm_adaptive_sfkl/checkpoint-314/training_args.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4080ce6c122d894dce2a6242fb58ae879822809092a9484cf3c306a91aacf376 +size 7185 diff --git a/qwen3/distillm_adaptive_sfkl/checkpoint-314/zero_to_fp32.py b/qwen3/distillm_adaptive_sfkl/checkpoint-314/zero_to_fp32.py new file mode 100644 index 0000000000000000000000000000000000000000..f40f1f0acbbff30e8e8d29906b56aae4e8b8a138 --- /dev/null +++ b/qwen3/distillm_adaptive_sfkl/checkpoint-314/zero_to_fp32.py @@ -0,0 +1,790 @@ +#!/usr/bin/env python + +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: Apache-2.0 + +# DeepSpeed Team + +# This script extracts fp32 consolidated weights from a zero 1, 2 and 3 DeepSpeed checkpoints. It gets +# copied into the top level checkpoint dir, so the user can easily do the conversion at any point in +# the future. Once extracted, the weights don't require DeepSpeed and can be used in any +# application. +# +# example: +# python zero_to_fp32.py . output_dir/ +# or +# python zero_to_fp32.py . output_dir/ --safe_serialization + +import argparse +import torch +import glob +import math +import os +import re +import gc +import json +import numpy as np +from tqdm import tqdm +from collections import OrderedDict +from dataclasses import dataclass + +# while this script doesn't use deepspeed to recover data, since the checkpoints are pickled with +# DeepSpeed data structures it has to be available in the current python environment. +from deepspeed.utils import logger +from deepspeed.checkpoint.constants import (DS_VERSION, OPTIMIZER_STATE_DICT, SINGLE_PARTITION_OF_FP32_GROUPS, + FP32_FLAT_GROUPS, ZERO_STAGE, PARTITION_COUNT, PARAM_SHAPES, BUFFER_NAMES, + FROZEN_PARAM_SHAPES, FROZEN_PARAM_FRAGMENTS, AUTOEP_LAYERS_KEY, + AUTOEP_LAYERS_KEY_LEGACY, AUTOEP_ZERO3_EXPERT_STATE_FORMAT_KEY, + AUTOEP_ZERO3_PARTITIONED_EXPERT_STATE_FORMAT) + + +@dataclass +class zero_model_state: + buffers: dict() + param_shapes: dict() + shared_params: list + ds_version: int + frozen_param_shapes: dict() + frozen_param_fragments: dict() + + +debug = 0 + +# load to cpu +device = torch.device('cpu') + + +def atoi(text): + return int(text) if text.isdigit() else text + + +def natural_keys(text): + ''' + alist.sort(key=natural_keys) sorts in human order + http://nedbatchelder.com/blog/200712/human_sorting.html + (See Toothy's implementation in the comments) + ''' + return [atoi(c) for c in re.split(r'(\d+)', text)] + + +def get_model_state_file(checkpoint_dir, zero_stage): + if not os.path.isdir(checkpoint_dir): + raise FileNotFoundError(f"Directory '{checkpoint_dir}' doesn't exist") + + # there should be only one file + if zero_stage <= 2: + file = os.path.join(checkpoint_dir, "mp_rank_00_model_states.pt") + elif zero_stage == 3: + file = os.path.join(checkpoint_dir, "zero_pp_rank_0_mp_rank_00_model_states.pt") + + if not os.path.exists(file): + raise FileNotFoundError(f"can't find model states file at '{file}'") + + return file + + +def get_checkpoint_files(checkpoint_dir, glob_pattern): + # XXX: need to test that this simple glob rule works for multi-node setup too + ckpt_files = sorted(glob.glob(os.path.join(checkpoint_dir, glob_pattern)), key=natural_keys) + + if len(ckpt_files) == 0: + raise FileNotFoundError(f"can't find {glob_pattern} files in directory '{checkpoint_dir}'") + + return ckpt_files + + +def get_optim_files(checkpoint_dir): + return get_checkpoint_files(checkpoint_dir, "*_optim_states.pt") + + +def get_model_state_files(checkpoint_dir): + return get_checkpoint_files(checkpoint_dir, "*_model_states.pt") + + +def _has_autoep_zero3_partitioned_metadata(state_dict): + autoep_layers = state_dict.get(AUTOEP_LAYERS_KEY) + if autoep_layers is None: + autoep_layers = state_dict.get(AUTOEP_LAYERS_KEY_LEGACY) + if not isinstance(autoep_layers, list): + return False + return any( + isinstance(entry, dict) + and entry.get(AUTOEP_ZERO3_EXPERT_STATE_FORMAT_KEY) == AUTOEP_ZERO3_PARTITIONED_EXPERT_STATE_FORMAT + for entry in autoep_layers) + + +def _raise_if_autoep_zero3_partitioned_state(state_dict): + if _has_autoep_zero3_partitioned_metadata(state_dict): + raise NotImplementedError("zero_to_fp32 does not support AutoEP ZeRO-3 partition-native checkpoints. " + "AutoEP expert parameters are partitioned over expert replica groups, so " + "global data-parallel consolidation would produce incomplete expert tensors. " + "Use ds_to_universal.py for expert-aware conversion.") + + +def _raise_if_autoep_zero3_partitioned_checkpoint(model_files): + for file in model_files: + state_dict = torch.load(file, map_location=device, weights_only=False) + _raise_if_autoep_zero3_partitioned_state(state_dict) + + +def parse_model_states(files): + zero_model_states = [] + for file in files: + state_dict = torch.load(file, map_location=device, weights_only=False) + _raise_if_autoep_zero3_partitioned_state(state_dict) + + if BUFFER_NAMES not in state_dict: + raise ValueError(f"{file} is not a model state checkpoint") + buffer_names = state_dict[BUFFER_NAMES] + if debug: + print("Found buffers:", buffer_names) + + # recover just the buffers while restoring them to fp32 if they were saved in fp16 + buffers = {k: v.float() for k, v in state_dict["module"].items() if k in buffer_names} + param_shapes = state_dict[PARAM_SHAPES] + + # collect parameters that are included in param_shapes + param_names = [] + for s in param_shapes: + for name in s.keys(): + param_names.append(name) + + # update with frozen parameters + frozen_param_shapes = state_dict.get(FROZEN_PARAM_SHAPES, None) + if frozen_param_shapes is not None: + if debug: + print(f"Found frozen_param_shapes: {frozen_param_shapes}") + param_names += list(frozen_param_shapes.keys()) + + # handle shared params + shared_params = [[k, v] for k, v in state_dict["shared_params"].items()] + + ds_version = state_dict.get(DS_VERSION, None) + + frozen_param_fragments = state_dict.get(FROZEN_PARAM_FRAGMENTS, None) + + z_model_state = zero_model_state(buffers=buffers, + param_shapes=param_shapes, + shared_params=shared_params, + ds_version=ds_version, + frozen_param_shapes=frozen_param_shapes, + frozen_param_fragments=frozen_param_fragments) + zero_model_states.append(z_model_state) + + return zero_model_states + + +def parse_optim_states(files, ds_checkpoint_dir): + total_files = len(files) + state_dicts = [] + for f in tqdm(files, desc='Loading checkpoint shards'): + state_dict = torch.load(f, map_location=device, mmap=True, weights_only=False) + # immediately discard the potentially huge 2 optimizer states as we only care for fp32 master weights + # and also handle the case where it was already removed by another helper script + state_dict["optimizer_state_dict"].pop("optimizer_state_dict", None) + state_dicts.append(state_dict) + + if ZERO_STAGE not in state_dicts[0][OPTIMIZER_STATE_DICT]: + raise ValueError(f"{files[0]} is not a zero checkpoint") + zero_stage = state_dicts[0][OPTIMIZER_STATE_DICT][ZERO_STAGE] + world_size = state_dicts[0][OPTIMIZER_STATE_DICT][PARTITION_COUNT] + + # For ZeRO-2 each param group can have different partition_count as data parallelism for expert + # parameters can be different from data parallelism for non-expert parameters. So we can just + # use the max of the partition_count to get the dp world_size. + + if type(world_size) is list: + world_size = max(world_size) + + if world_size != total_files: + raise ValueError( + f"Expected {world_size} of '*_optim_states.pt' under '{ds_checkpoint_dir}' but found {total_files} files. " + "Possibly due to an overwrite of an old checkpoint, or a checkpoint didn't get saved by one or more processes." + ) + + # the groups are named differently in each stage + if zero_stage <= 2: + fp32_groups_key = SINGLE_PARTITION_OF_FP32_GROUPS + elif zero_stage == 3: + fp32_groups_key = FP32_FLAT_GROUPS + else: + raise ValueError(f"unknown zero stage {zero_stage}") + + fp32_flat_groups = [state_dicts[i][OPTIMIZER_STATE_DICT][fp32_groups_key] for i in range(len(state_dicts))] + return zero_stage, world_size, fp32_flat_groups + + +def _get_fp32_state_dict_from_zero_checkpoint(ds_checkpoint_dir, exclude_frozen_parameters): + """ + Returns fp32 state_dict reconstructed from ds checkpoint + + Args: + - ``ds_checkpoint_dir``: path to the deepspeed checkpoint folder (where the optimizer files are) + + """ + print(f"Processing zero checkpoint '{ds_checkpoint_dir}'") + + # parse_model_states rejects AutoEP ZeRO-3 partition-native checkpoints + # before the expensive optimizer-shard load below. + model_files = get_model_state_files(ds_checkpoint_dir) + zero_model_states = parse_model_states(model_files) + print(f'Parsing checkpoint created by deepspeed=={zero_model_states[0].ds_version}') + + optim_files = get_optim_files(ds_checkpoint_dir) + zero_stage, world_size, fp32_flat_groups = parse_optim_states(optim_files, ds_checkpoint_dir) + print(f"Detected checkpoint of type zero stage {zero_stage}, world_size: {world_size}") + + if zero_stage <= 2: + return _get_fp32_state_dict_from_zero2_checkpoint(world_size, fp32_flat_groups, zero_model_states, + exclude_frozen_parameters) + elif zero_stage == 3: + return _get_fp32_state_dict_from_zero3_checkpoint(world_size, fp32_flat_groups, zero_model_states, + exclude_frozen_parameters) + + +def _zero2_merge_frozen_params(state_dict, zero_model_states): + if zero_model_states[0].frozen_param_shapes is None or len(zero_model_states[0].frozen_param_shapes) == 0: + return + + frozen_param_shapes = zero_model_states[0].frozen_param_shapes + frozen_param_fragments = zero_model_states[0].frozen_param_fragments + + if debug: + num_elem = sum(s.numel() for s in frozen_param_shapes.values()) + print(f'rank 0: {FROZEN_PARAM_SHAPES}.numel = {num_elem}') + + wanted_params = len(frozen_param_shapes) + wanted_numel = sum(s.numel() for s in frozen_param_shapes.values()) + avail_numel = sum([p.numel() for p in frozen_param_fragments.values()]) + print(f'Frozen params: Have {avail_numel} numels to process.') + print(f'Frozen params: Need {wanted_numel} numels in {wanted_params} params') + + total_params = 0 + total_numel = 0 + for name, shape in frozen_param_shapes.items(): + total_params += 1 + unpartitioned_numel = shape.numel() + total_numel += unpartitioned_numel + + state_dict[name] = frozen_param_fragments[name] + + if debug: + print(f"{name} full shape: {shape} unpartitioned numel {unpartitioned_numel} ") + + print(f"Reconstructed Frozen fp32 state dict with {total_params} params {total_numel} elements") + + +def _has_callable(obj, fn): + attr = getattr(obj, fn, None) + return callable(attr) + + +def _zero2_merge_trainable_params(state_dict, world_size, fp32_flat_groups, zero_model_states): + param_shapes = zero_model_states[0].param_shapes + + # Reconstruction protocol: + # + # XXX: document this + + if debug: + for i in range(world_size): + for j in range(len(fp32_flat_groups[0])): + print(f"{FP32_FLAT_GROUPS}[{i}][{j}].shape={fp32_flat_groups[i][j].shape}") + + # XXX: memory usage doubles here (zero2) + num_param_groups = len(fp32_flat_groups[0]) + merged_single_partition_of_fp32_groups = [] + for i in range(num_param_groups): + merged_partitions = [sd[i] for sd in fp32_flat_groups] + full_single_fp32_vector = torch.cat(merged_partitions, 0) + merged_single_partition_of_fp32_groups.append(full_single_fp32_vector) + avail_numel = sum( + [full_single_fp32_vector.numel() for full_single_fp32_vector in merged_single_partition_of_fp32_groups]) + + if debug: + wanted_params = sum([len(shapes) for shapes in param_shapes]) + wanted_numel = sum([sum(shape.numel() for shape in shapes.values()) for shapes in param_shapes]) + # not asserting if there is a mismatch due to possible padding + print(f"Have {avail_numel} numels to process.") + print(f"Need {wanted_numel} numels in {wanted_params} params.") + + # params + # XXX: for huge models that can't fit into the host's RAM we will have to recode this to support + # out-of-core computing solution + total_numel = 0 + total_params = 0 + for shapes, full_single_fp32_vector in zip(param_shapes, merged_single_partition_of_fp32_groups): + offset = 0 + avail_numel = full_single_fp32_vector.numel() + for name, shape in shapes.items(): + + unpartitioned_numel = shape.numel() if _has_callable(shape, 'numel') else math.prod(shape) + total_numel += unpartitioned_numel + total_params += 1 + + if debug: + print(f"{name} full shape: {shape} unpartitioned numel {unpartitioned_numel} ") + state_dict[name] = full_single_fp32_vector.narrow(0, offset, unpartitioned_numel).view(shape) + offset += unpartitioned_numel + + # Z2 started to align to 2*world_size to improve nccl performance. Therefore both offset and + # avail_numel can differ by anywhere between 0..2*world_size. Due to two unrelated complex + # paddings performed in the code it's almost impossible to predict the exact numbers w/o the + # live optimizer object, so we are checking that the numbers are within the right range + align_to = 2 * world_size + + def zero2_align(x): + return align_to * math.ceil(x / align_to) + + if debug: + print(f"original offset={offset}, avail_numel={avail_numel}") + + offset = zero2_align(offset) + avail_numel = zero2_align(avail_numel) + + if debug: + print(f"aligned offset={offset}, avail_numel={avail_numel}") + + # Sanity check + if offset != avail_numel: + raise ValueError(f"consumed {offset} numels out of {avail_numel} - something is wrong") + + print(f"Reconstructed fp32 state dict with {total_params} params {total_numel} elements") + + +def _get_fp32_state_dict_from_zero2_checkpoint(world_size, fp32_flat_groups, zero_model_states, + exclude_frozen_parameters): + state_dict = OrderedDict() + + # buffers + buffers = zero_model_states[0].buffers + state_dict.update(buffers) + if debug: + print(f"added {len(buffers)} buffers") + + if not exclude_frozen_parameters: + _zero2_merge_frozen_params(state_dict, zero_model_states) + + _zero2_merge_trainable_params(state_dict, world_size, fp32_flat_groups, zero_model_states) + + # recover shared parameters + for pair in zero_model_states[0].shared_params: + if pair[1] in state_dict: + state_dict[pair[0]] = state_dict[pair[1]] + + return state_dict + + +def zero3_partitioned_param_info(unpartitioned_numel, world_size): + remainder = unpartitioned_numel % world_size + padding_numel = (world_size - remainder) if remainder else 0 + partitioned_numel = math.ceil(unpartitioned_numel / world_size) + return partitioned_numel, padding_numel + + +def _zero3_merge_frozen_params(state_dict, world_size, zero_model_states): + if zero_model_states[0].frozen_param_shapes is None or len(zero_model_states[0].frozen_param_shapes) == 0: + return + + if debug: + for i in range(world_size): + num_elem = sum(s.numel() for s in zero_model_states[i].frozen_param_fragments.values()) + print(f'rank {i}: {FROZEN_PARAM_SHAPES}.numel = {num_elem}') + + frozen_param_shapes = zero_model_states[0].frozen_param_shapes + wanted_params = len(frozen_param_shapes) + wanted_numel = sum(s.numel() for s in frozen_param_shapes.values()) + avail_numel = sum([p.numel() for p in zero_model_states[0].frozen_param_fragments.values()]) * world_size + print(f'Frozen params: Have {avail_numel} numels to process.') + print(f'Frozen params: Need {wanted_numel} numels in {wanted_params} params') + + total_params = 0 + total_numel = 0 + for name, shape in zero_model_states[0].frozen_param_shapes.items(): + total_params += 1 + unpartitioned_numel = shape.numel() + total_numel += unpartitioned_numel + + param_frags = tuple(model_state.frozen_param_fragments[name] for model_state in zero_model_states) + state_dict[name] = torch.cat(param_frags, 0).narrow(0, 0, unpartitioned_numel).view(shape) + + partitioned_numel, partitioned_padding_numel = zero3_partitioned_param_info(unpartitioned_numel, world_size) + + if debug: + print( + f"Frozen params: {total_params} {name} full shape: {shape} partition0 numel={partitioned_numel} partitioned_padding_numel={partitioned_padding_numel}" + ) + + print(f"Reconstructed Frozen fp32 state dict with {total_params} params {total_numel} elements") + + +class GatheredTensor: + """ + A pseudo tensor that collects partitioned weights. + It is more memory efficient when there are multiple groups. + """ + + def __init__(self, flat_groups, flat_groups_offset, offset, partitioned_numel, shape): + self.flat_groups = flat_groups + self.flat_groups_offset = flat_groups_offset + self.offset = offset + self.partitioned_numel = partitioned_numel + self.shape = shape + self.dtype = self.flat_groups[0][0].dtype + + def contiguous(self): + """ + Merge partitioned weights from flat_groups into a single tensor. + """ + end_idx = self.offset + self.partitioned_numel + world_size = len(self.flat_groups) + pad_flat_param_chunks = [] + + for rank_i in range(world_size): + # for each rank, we need to collect weights from related group/groups + flat_groups_at_rank_i = self.flat_groups[rank_i] + start_group_id = None + end_group_id = None + for group_id in range(len(self.flat_groups_offset)): + if self.flat_groups_offset[group_id] <= self.offset < self.flat_groups_offset[group_id + 1]: + start_group_id = group_id + if self.flat_groups_offset[group_id] < end_idx <= self.flat_groups_offset[group_id + 1]: + end_group_id = group_id + break + # collect weights from related group/groups + for group_id in range(start_group_id, end_group_id + 1): + flat_tensor = flat_groups_at_rank_i[group_id] + start_offset = self.offset - self.flat_groups_offset[group_id] + end_offset = min(end_idx, self.flat_groups_offset[group_id + 1]) - self.flat_groups_offset[group_id] + pad_flat_param_chunks.append(flat_tensor[start_offset:end_offset]) + + # collect weights from all ranks + pad_flat_param = torch.cat(pad_flat_param_chunks, dim=0) + param = pad_flat_param[:self.shape.numel()].view(self.shape).contiguous() + return param + + +def _zero3_merge_trainable_params(state_dict, world_size, fp32_flat_groups, zero_model_states): + param_shapes = zero_model_states[0].param_shapes + avail_numel = sum([flat_group.numel() for flat_group in fp32_flat_groups[0]]) * world_size + + # Reconstruction protocol: For zero3 we need to zip the partitions together at boundary of each + # param, re-consolidating each param, while dealing with padding if any + + # merge list of dicts, preserving order + param_shapes = {k: v for d in param_shapes for k, v in d.items()} + + if debug: + for i in range(world_size): + print(f"{FP32_FLAT_GROUPS}[{i}].shape={fp32_flat_groups[i].shape}") + + wanted_params = len(param_shapes) + wanted_numel = sum(shape.numel() for shape in param_shapes.values()) + # not asserting if there is a mismatch due to possible padding + avail_numel = fp32_flat_groups[0].numel() * world_size + print(f"Trainable params: Have {avail_numel} numels to process.") + print(f"Trainable params: Need {wanted_numel} numels in {wanted_params} params.") + + # params + # XXX: for huge models that can't fit into the host's RAM we will have to recode this to support + # out-of-core computing solution + offset = 0 + total_numel = 0 + total_params = 0 + flat_groups_offset = [0] + list(np.cumsum([flat_tensor.numel() for flat_tensor in fp32_flat_groups[0]])) + for name, shape in tqdm(param_shapes.items(), desc='Gathering sharded weights'): + unpartitioned_numel = shape.numel() + total_numel += unpartitioned_numel + total_params += 1 + partitioned_numel, partitioned_padding_numel = zero3_partitioned_param_info(unpartitioned_numel, world_size) + + if debug: + print( + f"Trainable params: {total_params} {name} full shape: {shape} partition0 numel={partitioned_numel} partitioned_padding_numel={partitioned_padding_numel}" + ) + + # memory efficient tensor + tensor = GatheredTensor(fp32_flat_groups, flat_groups_offset, offset, partitioned_numel, shape) + state_dict[name] = tensor + offset += partitioned_numel + + offset *= world_size + + # Sanity check + if offset != avail_numel: + raise ValueError(f"consumed {offset} numels out of {avail_numel} - something is wrong") + + print(f"Reconstructed Trainable fp32 state dict with {total_params} params {total_numel} elements") + + +def _get_fp32_state_dict_from_zero3_checkpoint(world_size, fp32_flat_groups, zero_model_states, + exclude_frozen_parameters): + state_dict = OrderedDict() + + # buffers + buffers = zero_model_states[0].buffers + state_dict.update(buffers) + if debug: + print(f"added {len(buffers)} buffers") + + if not exclude_frozen_parameters: + _zero3_merge_frozen_params(state_dict, world_size, zero_model_states) + + _zero3_merge_trainable_params(state_dict, world_size, fp32_flat_groups, zero_model_states) + + # recover shared parameters + for pair in zero_model_states[0].shared_params: + if pair[1] in state_dict: + state_dict[pair[0]] = state_dict[pair[1]] + + return state_dict + + +def to_torch_tensor(state_dict, return_empty_tensor=False): + """ + Convert state_dict of GatheredTensor to torch tensor + """ + torch_state_dict = {} + converted_tensors = {} + for name, tensor in state_dict.items(): + tensor_id = id(tensor) + if tensor_id in converted_tensors: # shared tensors + shared_tensor = torch_state_dict[converted_tensors[tensor_id]] + torch_state_dict[name] = shared_tensor + else: + converted_tensors[tensor_id] = name + if return_empty_tensor: + torch_state_dict[name] = torch.empty(tensor.shape, dtype=tensor.dtype) + else: + torch_state_dict[name] = tensor.contiguous() + return torch_state_dict + + +def get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir, + tag=None, + exclude_frozen_parameters=False, + lazy_mode=False): + """ + Convert ZeRO 2 or 3 checkpoint into a single fp32 consolidated state_dict that can be loaded with + ``load_state_dict()`` and used for training without DeepSpeed or shared with others, for example + via a model hub. + + Args: + - ``checkpoint_dir``: path to the desired checkpoint folder + - ``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`` + - ``exclude_frozen_parameters``: exclude frozen parameters + - ``lazy_mode``: get state_dict in lazy mode. It returns a dict of pesduo tensor instead of torch tensor, which is more memory efficient. + Convert the pesduo tensor to torch tensor by ``.contiguous()`` + + Returns: + - pytorch ``state_dict`` + + A typical usage might be :: + + from deepspeed.utils.zero_to_fp32 import get_fp32_state_dict_from_zero_checkpoint + # do the training and checkpoint saving + state_dict = get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir) # already on cpu + model = model.cpu() # move to cpu + model.load_state_dict(state_dict) + # submit to model hub or save the model to share with others + + In this example the ``model`` will no longer be usable in the deepspeed context of the same + application. i.e. you will need to re-initialize the deepspeed engine, since + ``model.load_state_dict(state_dict)`` will remove all the deepspeed magic from it. + + If you want it all done for you, use ``load_state_dict_from_zero_checkpoint`` instead. + + Note: the above usage may not work if your application doesn't have sufficient free CPU memory. + You may need to use the offline approach using the ``zero_to_fp32.py`` script that is saved with + the checkpoint. Or you can load state_dict in lazy mode :: + + from deepspeed.utils.zero_to_fp32 import get_fp32_state_dict_from_zero_checkpoint + state_dict = get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir, lazy_mode=True) # not on cpu + for name, lazy_tensor in state_dict.item(): + tensor = lazy_tensor.contiguous() # to cpu + print(name, tensor) + # del tensor to release memory if it no longer in use + """ + if tag is None: + latest_path = os.path.join(checkpoint_dir, 'latest') + if os.path.isfile(latest_path): + with open(latest_path, 'r') as fd: + tag = fd.read().strip() + else: + raise ValueError(f"Unable to find 'latest' file at {latest_path}") + + ds_checkpoint_dir = os.path.join(checkpoint_dir, tag) + + if not os.path.isdir(ds_checkpoint_dir): + raise FileNotFoundError(f"Directory '{ds_checkpoint_dir}' doesn't exist") + + state_dict = _get_fp32_state_dict_from_zero_checkpoint(ds_checkpoint_dir, exclude_frozen_parameters) + if lazy_mode: + return state_dict + else: + return to_torch_tensor(state_dict) + + +def convert_zero_checkpoint_to_fp32_state_dict(checkpoint_dir, + output_dir, + max_shard_size="5GB", + safe_serialization=False, + tag=None, + exclude_frozen_parameters=False): + """ + Convert ZeRO 2 or 3 checkpoint into a single fp32 consolidated ``state_dict`` file that can be + loaded with ``torch.load(file)`` + ``load_state_dict()`` and used for training without DeepSpeed. + + Args: + - ``checkpoint_dir``: path to the desired checkpoint folder. (one that contains the tag-folder, like ``global_step14``) + - ``output_dir``: directory to the pytorch fp32 state_dict output files + - ``max_shard_size``: the maximum size for a checkpoint before being sharded, default value is 5GB + - ``safe_serialization``: whether to save the model using `safetensors` or the traditional PyTorch way (that uses `pickle`). + - ``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`` + - ``exclude_frozen_parameters``: exclude frozen parameters + """ + + # Dependency pre-check + if safe_serialization: + try: + from safetensors.torch import save_file + except ImportError: + print('If you want to use `safe_serialization`, please `pip install safetensors`') + raise + if max_shard_size is not None: + try: + from huggingface_hub import split_torch_state_dict_into_shards + except ImportError: + print('If you want to use `max_shard_size`, please `pip install huggingface_hub`') + raise + + # Convert zero checkpoint to state_dict + state_dict = get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir, + tag, + exclude_frozen_parameters, + lazy_mode=True) + + # Shard the model if it is too big. + weights_name = "model.safetensors" if safe_serialization else "pytorch_model.bin" + if max_shard_size is not None: + filename_pattern = weights_name.replace(".bin", "{suffix}.bin").replace(".safetensors", "{suffix}.safetensors") + # an memory-efficient approach for sharding + empty_state_dict = to_torch_tensor(state_dict, return_empty_tensor=True) + state_dict_split = split_torch_state_dict_into_shards(empty_state_dict, + filename_pattern=filename_pattern, + max_shard_size=max_shard_size) + else: + from collections import namedtuple + StateDictSplit = namedtuple("StateDictSplit", ["is_sharded", "filename_to_tensors"]) + state_dict_split = StateDictSplit(is_sharded=False, + filename_to_tensors={weights_name: list(state_dict.keys())}) + + # Save the model by shard + os.makedirs(output_dir, exist_ok=True) + filename_to_tensors = state_dict_split.filename_to_tensors.items() + for shard_file, tensors in tqdm(filename_to_tensors, desc="Saving checkpoint shards"): + shard_state_dict = {tensor_name: state_dict[tensor_name] for tensor_name in tensors} + shard_state_dict = to_torch_tensor(shard_state_dict) + output_path = os.path.join(output_dir, shard_file) + if safe_serialization: + save_file(shard_state_dict, output_path, metadata={"format": "pt"}) + else: + torch.save(shard_state_dict, output_path) + # release the memory of current shard + for tensor_name in list(shard_state_dict.keys()): + del state_dict[tensor_name] + del shard_state_dict[tensor_name] + del shard_state_dict + gc.collect() + + # Save index if sharded + if state_dict_split.is_sharded: + index = { + "metadata": state_dict_split.metadata, + "weight_map": state_dict_split.tensor_to_filename, + } + save_index_file = "model.safetensors.index.json" if safe_serialization else "pytorch_model.bin.index.json" + save_index_file = os.path.join(output_dir, save_index_file) + with open(save_index_file, "w", encoding="utf-8") as f: + content = json.dumps(index, indent=2, sort_keys=True) + "\n" + f.write(content) + + +def load_state_dict_from_zero_checkpoint(model, checkpoint_dir, tag=None): + """ + 1. Put the provided model to cpu + 2. Convert ZeRO 2 or 3 checkpoint into a single fp32 consolidated ``state_dict`` + 3. Load it into the provided model + + Args: + - ``model``: the model object to update + - ``checkpoint_dir``: path to the desired checkpoint folder. (one that contains the tag-folder, like ``global_step14``) + - ``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`` + + Returns: + - ``model`: modified model + + Make sure you have plenty of CPU memory available before you call this function. If you don't + have enough use the ``zero_to_fp32.py`` utility to do the conversion. You will find it + conveniently placed for you in the checkpoint folder. + + A typical usage might be :: + + from deepspeed.utils.zero_to_fp32 import load_state_dict_from_zero_checkpoint + model = load_state_dict_from_zero_checkpoint(trainer.model, checkpoint_dir) + # submit to model hub or save the model to share with others + + Note, that once this was run, the ``model`` will no longer be usable in the deepspeed context + of the same application. i.e. you will need to re-initialize the deepspeed engine, since + ``model.load_state_dict(state_dict)`` will remove all the deepspeed magic from it. + + """ + logger.info("Extracting fp32 weights") + state_dict = get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir, tag) + + logger.info("Overwriting model with fp32 weights") + model = model.cpu() + model.load_state_dict(state_dict, strict=False) + + return model + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument("checkpoint_dir", + type=str, + help="path to the desired checkpoint folder, e.g., path/checkpoint-12") + parser.add_argument("output_dir", + type=str, + help="directory to the pytorch fp32 state_dict output files" + "(e.g. path/checkpoint-12-output/)") + parser.add_argument( + "--max_shard_size", + type=str, + default="5GB", + help="The maximum size for a checkpoint before being sharded. Checkpoints shard will then be each of size" + "lower than this size. If expressed as a string, needs to be digits followed by a unit (like `5MB`" + "We default it to 5GB in order for models to be able to run easily on free-tier google colab instances" + "without CPU OOM issues.") + parser.add_argument( + "--safe_serialization", + default=False, + action='store_true', + help="Whether to save the model using `safetensors` or the traditional PyTorch way (that uses `pickle`).") + parser.add_argument("-t", + "--tag", + type=str, + default=None, + help="checkpoint tag used as a unique identifier for checkpoint. e.g., global_step1") + parser.add_argument("--exclude_frozen_parameters", action='store_true', help="exclude frozen parameters") + parser.add_argument("-d", "--debug", action='store_true', help="enable debug") + args = parser.parse_args() + + debug = args.debug + + convert_zero_checkpoint_to_fp32_state_dict(args.checkpoint_dir, + args.output_dir, + max_shard_size=args.max_shard_size, + safe_serialization=args.safe_serialization, + tag=args.tag, + exclude_frozen_parameters=args.exclude_frozen_parameters) diff --git a/qwen3/distillm_adaptive_sfkl/checkpoint-628/README.md b/qwen3/distillm_adaptive_sfkl/checkpoint-628/README.md new file mode 100644 index 0000000000000000000000000000000000000000..776f98d43659dd923b8c3e5649c5ae66d1f99f3e --- /dev/null +++ b/qwen3/distillm_adaptive_sfkl/checkpoint-628/README.md @@ -0,0 +1,208 @@ +--- +base_model: Qwen/Qwen3-0.6B +library_name: peft +pipeline_tag: text-generation +tags: +- base_model:adapter:Qwen/Qwen3-0.6B +- llama-factory +- lora +- transformers +--- + +# Model Card for Model ID + + + + + +## Model Details + +### Model Description + + + + + +- **Developed by:** [More Information Needed] +- **Funded by [optional]:** [More Information Needed] +- **Shared by [optional]:** [More Information Needed] +- **Model type:** [More Information Needed] +- **Language(s) (NLP):** [More Information Needed] +- **License:** [More Information Needed] +- **Finetuned from model [optional]:** [More Information Needed] + +### Model Sources [optional] + + + +- **Repository:** [More Information Needed] +- **Paper [optional]:** [More Information Needed] +- **Demo [optional]:** [More Information Needed] + +## Uses + + + +### Direct Use + + + +[More Information Needed] + +### Downstream Use [optional] + + + +[More Information Needed] + +### Out-of-Scope Use + + + +[More Information Needed] + +## Bias, Risks, and Limitations + + + +[More Information Needed] + +### Recommendations + + + +Users (both direct and downstream) should be made aware of the risks, biases and limitations of the model. More information needed for further recommendations. + +## How to Get Started with the Model + +Use the code below to get started with the model. + +[More Information Needed] + +## Training Details + +### Training Data + + + +[More Information Needed] + +### Training Procedure + + + +#### Preprocessing [optional] + +[More Information Needed] + + +#### Training Hyperparameters + +- **Training regime:** [More Information Needed] + +#### Speeds, Sizes, Times [optional] + + + +[More Information Needed] + +## Evaluation + + + +### Testing Data, Factors & Metrics + +#### Testing Data + + + +[More Information Needed] + +#### Factors + + + +[More Information Needed] + +#### Metrics + + + +[More Information Needed] + +### Results + +[More Information Needed] + +#### Summary + + + +## Model Examination [optional] + + + +[More Information Needed] + +## Environmental Impact + + + +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). + +- **Hardware Type:** [More Information Needed] +- **Hours used:** [More Information Needed] +- **Cloud Provider:** [More Information Needed] +- **Compute Region:** [More Information Needed] +- **Carbon Emitted:** [More Information Needed] + +## Technical Specifications [optional] + +### Model Architecture and Objective + +[More Information Needed] + +### Compute Infrastructure + +[More Information Needed] + +#### Hardware + +[More Information Needed] + +#### Software + +[More Information Needed] + +## Citation [optional] + + + +**BibTeX:** + +[More Information Needed] + +**APA:** + +[More Information Needed] + +## Glossary [optional] + + + +[More Information Needed] + +## More Information [optional] + +[More Information Needed] + +## Model Card Authors [optional] + +[More Information Needed] + +## Model Card Contact + +[More Information Needed] +### Framework versions + +- PEFT 0.18.1 \ No newline at end of file diff --git a/qwen3/distillm_adaptive_sfkl/checkpoint-628/adapter_config.json b/qwen3/distillm_adaptive_sfkl/checkpoint-628/adapter_config.json new file mode 100644 index 0000000000000000000000000000000000000000..d88d3ddd2a1fe81f4cf32eb7f116cfcaecff483e --- /dev/null +++ b/qwen3/distillm_adaptive_sfkl/checkpoint-628/adapter_config.json @@ -0,0 +1,46 @@ +{ + "alora_invocation_tokens": null, + "alpha_pattern": {}, + "arrow_config": null, + "auto_mapping": null, + "base_model_name_or_path": "Qwen/Qwen3-0.6B", + "bias": "none", + "corda_config": null, + "ensure_weight_tying": false, + "eva_config": null, + "exclude_modules": null, + "fan_in_fan_out": false, + "inference_mode": true, + "init_lora_weights": true, + "layer_replication": null, + "layers_pattern": null, + "layers_to_transform": null, + "loftq_config": {}, + "lora_alpha": 64, + "lora_bias": false, + "lora_dropout": 0.1, + "megatron_config": null, + "megatron_core": "megatron.core", + "modules_to_save": null, + "peft_type": "LORA", + "peft_version": "0.18.1", + "qalora_group_size": 16, + "r": 32, + "rank_pattern": {}, + "revision": null, + "target_modules": [ + "gate_proj", + "o_proj", + "down_proj", + "v_proj", + "q_proj", + "up_proj", + "k_proj" + ], + "target_parameters": null, + "task_type": "CAUSAL_LM", + "trainable_token_indices": null, + "use_dora": false, + "use_qalora": false, + "use_rslora": false +} \ No newline at end of file diff --git a/qwen3/distillm_adaptive_sfkl/checkpoint-628/adapter_model.safetensors b/qwen3/distillm_adaptive_sfkl/checkpoint-628/adapter_model.safetensors new file mode 100644 index 0000000000000000000000000000000000000000..3a587664cabe2cd3c49db2e6ef31d40fb9cdb05a --- /dev/null +++ b/qwen3/distillm_adaptive_sfkl/checkpoint-628/adapter_model.safetensors @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:25185e10cd53d2e1d7ac55987d0e84b185172802124cf27164ddebc2678aaa66 +size 40422560 diff --git a/qwen3/distillm_adaptive_sfkl/checkpoint-628/chat_template.jinja b/qwen3/distillm_adaptive_sfkl/checkpoint-628/chat_template.jinja new file mode 100644 index 0000000000000000000000000000000000000000..01be9b307daa2d425f7c168c9fb145a286e0afb4 --- /dev/null +++ b/qwen3/distillm_adaptive_sfkl/checkpoint-628/chat_template.jinja @@ -0,0 +1,89 @@ +{%- if tools %} + {{- '<|im_start|>system\n' }} + {%- if messages[0].role == 'system' %} + {{- messages[0].content + '\n\n' }} + {%- endif %} + {{- "# Tools\n\nYou may call one or more functions to assist with the user query.\n\nYou are provided with function signatures within XML tags:\n" }} + {%- for tool in tools %} + {{- "\n" }} + {{- tool | tojson }} + {%- endfor %} + {{- "\n\n\nFor each function call, return a json object with function name and arguments within XML tags:\n\n{\"name\": , \"arguments\": }\n<|im_end|>\n" }} +{%- else %} + {%- if messages[0].role == 'system' %} + {{- '<|im_start|>system\n' + messages[0].content + '<|im_end|>\n' }} + {%- endif %} +{%- endif %} +{%- set ns = namespace(multi_step_tool=true, last_query_index=messages|length - 1) %} +{%- for message in messages[::-1] %} + {%- set index = (messages|length - 1) - loop.index0 %} + {%- if ns.multi_step_tool and message.role == "user" and message.content is string and not(message.content.startswith('') and message.content.endswith('')) %} + {%- set ns.multi_step_tool = false %} + {%- set ns.last_query_index = index %} + {%- endif %} +{%- endfor %} +{%- for message in messages %} + {%- if message.content is string %} + {%- set content = message.content %} + {%- else %} + {%- set content = '' %} + {%- endif %} + {%- if (message.role == "user") or (message.role == "system" and not loop.first) %} + {{- '<|im_start|>' + message.role + '\n' + content + '<|im_end|>' + '\n' }} + {%- elif message.role == "assistant" %} + {%- set reasoning_content = '' %} + {%- if message.reasoning_content is string %} + {%- set reasoning_content = message.reasoning_content %} + {%- else %} + {%- if '' in content %} + {%- set reasoning_content = content.split('')[0].rstrip('\n').split('')[-1].lstrip('\n') %} + {%- set content = content.split('')[-1].lstrip('\n') %} + {%- endif %} + {%- endif %} + {%- if loop.index0 > ns.last_query_index %} + {%- if loop.last or (not loop.last and reasoning_content) %} + {{- '<|im_start|>' + message.role + '\n\n' + reasoning_content.strip('\n') + '\n\n\n' + content.lstrip('\n') }} + {%- else %} + {{- '<|im_start|>' + message.role + '\n' + content }} + {%- endif %} + {%- else %} + {{- '<|im_start|>' + message.role + '\n' + content }} + {%- endif %} + {%- if message.tool_calls %} + {%- for tool_call in message.tool_calls %} + {%- if (loop.first and content) or (not loop.first) %} + {{- '\n' }} + {%- endif %} + {%- if tool_call.function %} + {%- set tool_call = tool_call.function %} + {%- endif %} + {{- '\n{"name": "' }} + {{- tool_call.name }} + {{- '", "arguments": ' }} + {%- if tool_call.arguments is string %} + {{- tool_call.arguments }} + {%- else %} + {{- tool_call.arguments | tojson }} + {%- endif %} + {{- '}\n' }} + {%- endfor %} + {%- endif %} + {{- '<|im_end|>\n' }} + {%- elif message.role == "tool" %} + {%- if loop.first or (messages[loop.index0 - 1].role != "tool") %} + {{- '<|im_start|>user' }} + {%- endif %} + {{- '\n\n' }} + {{- content }} + {{- '\n' }} + {%- if loop.last or (messages[loop.index0 + 1].role != "tool") %} + {{- '<|im_end|>\n' }} + {%- endif %} + {%- endif %} +{%- endfor %} +{%- if add_generation_prompt %} + {{- '<|im_start|>assistant\n' }} + {%- if enable_thinking is defined and enable_thinking is false %} + {{- '\n\n\n\n' }} + {%- endif %} +{%- endif %} \ No newline at end of file diff --git a/qwen3/distillm_adaptive_sfkl/checkpoint-628/distillm_state_rank0.pt b/qwen3/distillm_adaptive_sfkl/checkpoint-628/distillm_state_rank0.pt new file mode 100644 index 0000000000000000000000000000000000000000..a9bffbbbd85eed6d205abf4ba497b58a9c2ab686 --- /dev/null +++ b/qwen3/distillm_adaptive_sfkl/checkpoint-628/distillm_state_rank0.pt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9083bb0185b673b3026a71a4e1b07808667f534cb608256c2f138888949155e4 +size 9403 diff --git a/qwen3/distillm_adaptive_sfkl/checkpoint-628/distillm_state_rank1.pt b/qwen3/distillm_adaptive_sfkl/checkpoint-628/distillm_state_rank1.pt new file mode 100644 index 0000000000000000000000000000000000000000..cb46275912c78d8615a32230c877ae737b79e87d --- /dev/null +++ b/qwen3/distillm_adaptive_sfkl/checkpoint-628/distillm_state_rank1.pt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4ade08e81abc31e53e5fa43cc5e43d33641c8cb156fb645f56ff2473327d9a0d +size 9339 diff --git a/qwen3/distillm_adaptive_sfkl/checkpoint-628/global_step628/bf16_zero_pp_rank_0_mp_rank_00_optim_states.pt b/qwen3/distillm_adaptive_sfkl/checkpoint-628/global_step628/bf16_zero_pp_rank_0_mp_rank_00_optim_states.pt new file mode 100644 index 0000000000000000000000000000000000000000..3c1cf86e1a1a6c8cc5c07b40e8d1d801e5fe50c2 --- /dev/null +++ b/qwen3/distillm_adaptive_sfkl/checkpoint-628/global_step628/bf16_zero_pp_rank_0_mp_rank_00_optim_states.pt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:becf8dbf056d2918d68224f88e165a67737125ccb57bf085549418cf2348d419 +size 121135557 diff --git a/qwen3/distillm_adaptive_sfkl/checkpoint-628/global_step628/bf16_zero_pp_rank_1_mp_rank_00_optim_states.pt b/qwen3/distillm_adaptive_sfkl/checkpoint-628/global_step628/bf16_zero_pp_rank_1_mp_rank_00_optim_states.pt new file mode 100644 index 0000000000000000000000000000000000000000..7bfd77c468e563a6e19658f7aaf9ac4651e830a3 --- /dev/null +++ b/qwen3/distillm_adaptive_sfkl/checkpoint-628/global_step628/bf16_zero_pp_rank_1_mp_rank_00_optim_states.pt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:851ff806acb5365b9157d74e461ed2c106e766cbcfe17f279f195e0ffec76520 +size 121135749 diff --git a/qwen3/distillm_adaptive_sfkl/checkpoint-628/global_step628/mp_rank_00_model_states.pt b/qwen3/distillm_adaptive_sfkl/checkpoint-628/global_step628/mp_rank_00_model_states.pt new file mode 100644 index 0000000000000000000000000000000000000000..f41cbda545d04506eaa0b3ff3498b13a1ca5dbb0 --- /dev/null +++ b/qwen3/distillm_adaptive_sfkl/checkpoint-628/global_step628/mp_rank_00_model_states.pt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6b7109baa0ea62e4c188d495711855d5589a88cf6ff9e8a19c40f7056aa5dd69 +size 351841765