diff --git a/checkpoint-100/README.md b/checkpoint-100/README.md new file mode 100644 index 0000000000000000000000000000000000000000..e7d4f706aeefc6bb2aa84e963870f345a14c4af9 --- /dev/null +++ b/checkpoint-100/README.md @@ -0,0 +1,202 @@ +--- +library_name: peft +base_model: ../ckpts/Meta-Llama-3-8B-Instruct +--- + +# 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.11.1 \ No newline at end of file diff --git a/checkpoint-100/adapter_config.json b/checkpoint-100/adapter_config.json new file mode 100644 index 0000000000000000000000000000000000000000..ad16c073ed8946d227350e8fe4e99d689a8ede54 --- /dev/null +++ b/checkpoint-100/adapter_config.json @@ -0,0 +1,35 @@ +{ + "alpha_pattern": {}, + "auto_mapping": null, + "base_model_name_or_path": "../ckpts/Meta-Llama-3-8B-Instruct", + "bias": "none", + "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": 32, + "lora_dropout": 0.1, + "megatron_config": null, + "megatron_core": "megatron.core", + "modules_to_save": null, + "peft_type": "LORA", + "r": 16, + "rank_pattern": {}, + "revision": null, + "target_modules": [ + "down_proj", + "gate_proj", + "q_proj", + "lm_head", + "o_proj", + "v_proj", + "up_proj", + "k_proj" + ], + "task_type": "CAUSAL_LM", + "use_dora": false, + "use_rslora": false +} \ No newline at end of file diff --git a/checkpoint-100/adapter_model.safetensors b/checkpoint-100/adapter_model.safetensors new file mode 100644 index 0000000000000000000000000000000000000000..1a2473ee58d5209b28e8a00f8e330e31ce259574 --- /dev/null +++ b/checkpoint-100/adapter_model.safetensors @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:baca06cc42b3510c3c3bf848f73f79b72b1baea5a4f963941e134e37b3ab777d +size 1138856856 diff --git a/checkpoint-100/global_step100/bf16_zero_pp_rank_0_mp_rank_00_optim_states.pt b/checkpoint-100/global_step100/bf16_zero_pp_rank_0_mp_rank_00_optim_states.pt new file mode 100644 index 0000000000000000000000000000000000000000..b5c76794e67be718271ed6e69c8658a4f1f9bdb1 --- /dev/null +++ b/checkpoint-100/global_step100/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:808ab758e2efff532198a64b20a7f9c499ac3216290ea2598de18360f006e24c +size 528781328 diff --git a/checkpoint-100/global_step100/mp_rank_00_model_states.pt b/checkpoint-100/global_step100/mp_rank_00_model_states.pt new file mode 100644 index 0000000000000000000000000000000000000000..bad4b0b42fdf8faa0e3313ccca8475b6cba6a7be --- /dev/null +++ b/checkpoint-100/global_step100/mp_rank_00_model_states.pt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cba7f894e1d634e3bd3acbb30c43a7817dcd9bbc30549de0142cf5b4970bdd25 +size 199905337 diff --git a/checkpoint-100/latest b/checkpoint-100/latest new file mode 100644 index 0000000000000000000000000000000000000000..744ae7dbad571b6f37ec6c7066549494261bb59e --- /dev/null +++ b/checkpoint-100/latest @@ -0,0 +1 @@ +global_step100 \ No newline at end of file diff --git a/checkpoint-100/rng_state.pth b/checkpoint-100/rng_state.pth new file mode 100644 index 0000000000000000000000000000000000000000..7bf5862c14e4daf3b373f7fc1969da8616b4035b --- /dev/null +++ b/checkpoint-100/rng_state.pth @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1a2d9af3fcfc54434e74034cabf1cd700dd64663d32e5f7d97b79b71b2284409 +size 14244 diff --git a/checkpoint-100/trainer_state.json b/checkpoint-100/trainer_state.json new file mode 100644 index 0000000000000000000000000000000000000000..06634638d4c911f70bea701ef4ca483d8d376221 --- /dev/null +++ b/checkpoint-100/trainer_state.json @@ -0,0 +1,733 @@ +{ + "best_metric": null, + "best_model_checkpoint": null, + "epoch": 0.8533333333333334, + "eval_steps": 500, + "global_step": 100, + "is_hyper_param_search": false, + "is_local_process_zero": true, + "is_world_process_zero": true, + "log_history": [ + { + "epoch": 0.008533333333333334, + "grad_norm": 100.21848203113535, + "learning_rate": 0.0, + "loss": 7.1962, + "step": 1 + }, + { + "epoch": 0.017066666666666667, + "grad_norm": 96.43006188910957, + "learning_rate": 3.0102999566398115e-06, + "loss": 6.9414, + "step": 2 + }, + { + "epoch": 0.0256, + "grad_norm": 97.35803466618715, + "learning_rate": 4.771212547196624e-06, + "loss": 7.0102, + "step": 3 + }, + { + "epoch": 0.034133333333333335, + "grad_norm": 95.14837816372646, + "learning_rate": 6.020599913279623e-06, + "loss": 6.5295, + "step": 4 + }, + { + "epoch": 0.042666666666666665, + "grad_norm": 91.76544275692784, + "learning_rate": 6.989700043360187e-06, + "loss": 6.4806, + "step": 5 + }, + { + "epoch": 0.0512, + "grad_norm": 84.4494318688335, + "learning_rate": 7.781512503836437e-06, + "loss": 6.4194, + "step": 6 + }, + { + "epoch": 0.05973333333333333, + "grad_norm": 71.37977490595638, + "learning_rate": 8.450980400142568e-06, + "loss": 5.4953, + "step": 7 + }, + { + "epoch": 0.06826666666666667, + "grad_norm": 49.31153456754566, + "learning_rate": 9.030899869919434e-06, + "loss": 5.4123, + "step": 8 + }, + { + "epoch": 0.0768, + "grad_norm": 20.37296364560341, + "learning_rate": 9.542425094393249e-06, + "loss": 5.2334, + "step": 9 + }, + { + "epoch": 0.08533333333333333, + "grad_norm": 7.968467079076881, + "learning_rate": 9.999999999999999e-06, + "loss": 5.0282, + "step": 10 + }, + { + "epoch": 0.09386666666666667, + "grad_norm": 3.559446532055649, + "learning_rate": 1.041392685158225e-05, + "loss": 4.612, + "step": 11 + }, + { + "epoch": 0.1024, + "grad_norm": 3.5528846947995674, + "learning_rate": 1.0791812460476248e-05, + "loss": 4.9475, + "step": 12 + }, + { + "epoch": 0.11093333333333333, + "grad_norm": 3.541968897471334, + "learning_rate": 1.1139433523068365e-05, + "loss": 4.2777, + "step": 13 + }, + { + "epoch": 0.11946666666666667, + "grad_norm": 3.54718070036198, + "learning_rate": 1.1461280356782378e-05, + "loss": 4.3507, + "step": 14 + }, + { + "epoch": 0.128, + "grad_norm": 3.8632334830606747, + "learning_rate": 1.1760912590556813e-05, + "loss": 4.5364, + "step": 15 + }, + { + "epoch": 0.13653333333333334, + "grad_norm": 3.6637424744054004, + "learning_rate": 1.2041199826559246e-05, + "loss": 3.9672, + "step": 16 + }, + { + "epoch": 0.14506666666666668, + "grad_norm": 3.919802904818311, + "learning_rate": 1.230448921378274e-05, + "loss": 4.0618, + "step": 17 + }, + { + "epoch": 0.1536, + "grad_norm": 4.71904950738746, + "learning_rate": 1.2552725051033058e-05, + "loss": 4.6656, + "step": 18 + }, + { + "epoch": 0.16213333333333332, + "grad_norm": 4.6656317698690835, + "learning_rate": 1.2787536009528288e-05, + "loss": 4.1131, + "step": 19 + }, + { + "epoch": 0.17066666666666666, + "grad_norm": 5.145138692367417, + "learning_rate": 1.301029995663981e-05, + "loss": 4.0989, + "step": 20 + }, + { + "epoch": 0.1792, + "grad_norm": 5.923538014759818, + "learning_rate": 1.3222192947339192e-05, + "loss": 4.4991, + "step": 21 + }, + { + "epoch": 0.18773333333333334, + "grad_norm": 5.941056962941364, + "learning_rate": 1.3424226808222062e-05, + "loss": 4.0836, + "step": 22 + }, + { + "epoch": 0.19626666666666667, + "grad_norm": 6.171026012117947, + "learning_rate": 1.3617278360175927e-05, + "loss": 3.6861, + "step": 23 + }, + { + "epoch": 0.2048, + "grad_norm": 7.130542138930838, + "learning_rate": 1.380211241711606e-05, + "loss": 4.0958, + "step": 24 + }, + { + "epoch": 0.21333333333333335, + "grad_norm": 7.328837606110418, + "learning_rate": 1.3979400086720374e-05, + "loss": 3.9524, + "step": 25 + }, + { + "epoch": 0.22186666666666666, + "grad_norm": 6.923489005711429, + "learning_rate": 1.4149733479708178e-05, + "loss": 3.6062, + "step": 26 + }, + { + "epoch": 0.2304, + "grad_norm": 6.409498926059221, + "learning_rate": 1.4313637641589872e-05, + "loss": 3.2034, + "step": 27 + }, + { + "epoch": 0.23893333333333333, + "grad_norm": 5.781628405584682, + "learning_rate": 1.4471580313422191e-05, + "loss": 2.8158, + "step": 28 + }, + { + "epoch": 0.24746666666666667, + "grad_norm": 6.2927590068243315, + "learning_rate": 1.4623979978989559e-05, + "loss": 2.9803, + "step": 29 + }, + { + "epoch": 0.256, + "grad_norm": 6.103844678630006, + "learning_rate": 1.4771212547196623e-05, + "loss": 2.847, + "step": 30 + }, + { + "epoch": 0.26453333333333334, + "grad_norm": 7.656341925867144, + "learning_rate": 1.4913616938342726e-05, + "loss": 3.0907, + "step": 31 + }, + { + "epoch": 0.2730666666666667, + "grad_norm": 6.324242877501844, + "learning_rate": 1.5051499783199059e-05, + "loss": 2.3467, + "step": 32 + }, + { + "epoch": 0.2816, + "grad_norm": 7.606313101162739, + "learning_rate": 1.5185139398778874e-05, + "loss": 2.5292, + "step": 33 + }, + { + "epoch": 0.29013333333333335, + "grad_norm": 8.553792493849265, + "learning_rate": 1.531478917042255e-05, + "loss": 2.4547, + "step": 34 + }, + { + "epoch": 0.2986666666666667, + "grad_norm": 8.483368703272543, + "learning_rate": 1.5440680443502753e-05, + "loss": 2.1956, + "step": 35 + }, + { + "epoch": 0.3072, + "grad_norm": 8.364739352838077, + "learning_rate": 1.5563025007672873e-05, + "loss": 1.8552, + "step": 36 + }, + { + "epoch": 0.3157333333333333, + "grad_norm": 9.37663682000104, + "learning_rate": 1.5682017240669948e-05, + "loss": 1.9228, + "step": 37 + }, + { + "epoch": 0.32426666666666665, + "grad_norm": 9.823047193440066, + "learning_rate": 1.57978359661681e-05, + "loss": 1.7033, + "step": 38 + }, + { + "epoch": 0.3328, + "grad_norm": 9.692618512955894, + "learning_rate": 1.591064607026499e-05, + "loss": 1.3768, + "step": 39 + }, + { + "epoch": 0.3413333333333333, + "grad_norm": 9.08889021911031, + "learning_rate": 1.6020599913279622e-05, + "loss": 1.3015, + "step": 40 + }, + { + "epoch": 0.34986666666666666, + "grad_norm": 8.081534221516058, + "learning_rate": 1.6127838567197353e-05, + "loss": 0.9228, + "step": 41 + }, + { + "epoch": 0.3584, + "grad_norm": 6.238638048950311, + "learning_rate": 1.6232492903979005e-05, + "loss": 0.7267, + "step": 42 + }, + { + "epoch": 0.36693333333333333, + "grad_norm": 3.4058036861773604, + "learning_rate": 1.6334684555795865e-05, + "loss": 0.5875, + "step": 43 + }, + { + "epoch": 0.37546666666666667, + "grad_norm": 2.079163829467713, + "learning_rate": 1.6434526764861872e-05, + "loss": 0.6355, + "step": 44 + }, + { + "epoch": 0.384, + "grad_norm": 1.5597487833024746, + "learning_rate": 1.6532125137753435e-05, + "loss": 0.5106, + "step": 45 + }, + { + "epoch": 0.39253333333333335, + "grad_norm": 2.491689602375256, + "learning_rate": 1.662757831681574e-05, + "loss": 0.6454, + "step": 46 + }, + { + "epoch": 0.4010666666666667, + "grad_norm": 2.010880438195854, + "learning_rate": 1.672097857935717e-05, + "loss": 0.4757, + "step": 47 + }, + { + "epoch": 0.4096, + "grad_norm": 1.9452805114322096, + "learning_rate": 1.681241237375587e-05, + "loss": 0.4133, + "step": 48 + }, + { + "epoch": 0.41813333333333336, + "grad_norm": 1.7620848552306103, + "learning_rate": 1.6901960800285137e-05, + "loss": 0.4004, + "step": 49 + }, + { + "epoch": 0.4266666666666667, + "grad_norm": 1.278224489774809, + "learning_rate": 1.6989700043360187e-05, + "loss": 0.3523, + "step": 50 + }, + { + "epoch": 0.4352, + "grad_norm": 1.6151354758303231, + "learning_rate": 1.7075701760979363e-05, + "loss": 0.4317, + "step": 51 + }, + { + "epoch": 0.4437333333333333, + "grad_norm": 1.3451396055695035, + "learning_rate": 1.716003343634799e-05, + "loss": 0.3474, + "step": 52 + }, + { + "epoch": 0.45226666666666665, + "grad_norm": 1.6814977782362666, + "learning_rate": 1.724275869600789e-05, + "loss": 0.3706, + "step": 53 + }, + { + "epoch": 0.4608, + "grad_norm": 1.1682442432688667, + "learning_rate": 1.7323937598229687e-05, + "loss": 0.3488, + "step": 54 + }, + { + "epoch": 0.4693333333333333, + "grad_norm": 0.8839814540462471, + "learning_rate": 1.7403626894942437e-05, + "loss": 0.293, + "step": 55 + }, + { + "epoch": 0.47786666666666666, + "grad_norm": 0.7974304806295485, + "learning_rate": 1.7481880270062003e-05, + "loss": 0.2717, + "step": 56 + }, + { + "epoch": 0.4864, + "grad_norm": 0.6232203657585239, + "learning_rate": 1.7558748556724913e-05, + "loss": 0.1741, + "step": 57 + }, + { + "epoch": 0.49493333333333334, + "grad_norm": 0.6850688604563008, + "learning_rate": 1.763427993562937e-05, + "loss": 0.228, + "step": 58 + }, + { + "epoch": 0.5034666666666666, + "grad_norm": 0.5923826384300431, + "learning_rate": 1.7708520116421443e-05, + "loss": 0.2131, + "step": 59 + }, + { + "epoch": 0.512, + "grad_norm": 0.489754430485032, + "learning_rate": 1.7781512503836432e-05, + "loss": 0.165, + "step": 60 + }, + { + "epoch": 0.5205333333333333, + "grad_norm": 0.5280940052395061, + "learning_rate": 1.7853298350107667e-05, + "loss": 0.1658, + "step": 61 + }, + { + "epoch": 0.5290666666666667, + "grad_norm": 0.4750905992036739, + "learning_rate": 1.7923916894982537e-05, + "loss": 0.1438, + "step": 62 + }, + { + "epoch": 0.5376, + "grad_norm": 0.4162998392722401, + "learning_rate": 1.7993405494535815e-05, + "loss": 0.1555, + "step": 63 + }, + { + "epoch": 0.5461333333333334, + "grad_norm": 0.26863266246370443, + "learning_rate": 1.806179973983887e-05, + "loss": 0.1323, + "step": 64 + }, + { + "epoch": 0.5546666666666666, + "grad_norm": 0.26534221125601215, + "learning_rate": 1.8129133566428553e-05, + "loss": 0.1671, + "step": 65 + }, + { + "epoch": 0.5632, + "grad_norm": 0.2548662962257576, + "learning_rate": 1.8195439355418686e-05, + "loss": 0.1308, + "step": 66 + }, + { + "epoch": 0.5717333333333333, + "grad_norm": 0.18045394638578796, + "learning_rate": 1.8260748027008263e-05, + "loss": 0.1262, + "step": 67 + }, + { + "epoch": 0.5802666666666667, + "grad_norm": 0.17070388073612064, + "learning_rate": 1.8325089127062364e-05, + "loss": 0.1192, + "step": 68 + }, + { + "epoch": 0.5888, + "grad_norm": 0.1531381679244776, + "learning_rate": 1.8388490907372553e-05, + "loss": 0.1274, + "step": 69 + }, + { + "epoch": 0.5973333333333334, + "grad_norm": 0.18196434993687946, + "learning_rate": 1.8450980400142568e-05, + "loss": 0.1375, + "step": 70 + }, + { + "epoch": 0.6058666666666667, + "grad_norm": 0.15324416972951205, + "learning_rate": 1.8512583487190752e-05, + "loss": 0.1599, + "step": 71 + }, + { + "epoch": 0.6144, + "grad_norm": 0.10884462064503801, + "learning_rate": 1.857332496431268e-05, + "loss": 0.1041, + "step": 72 + }, + { + "epoch": 0.6229333333333333, + "grad_norm": 0.12915133528192668, + "learning_rate": 1.8633228601204555e-05, + "loss": 0.1406, + "step": 73 + }, + { + "epoch": 0.6314666666666666, + "grad_norm": 0.12553425699952878, + "learning_rate": 1.8692317197309763e-05, + "loss": 0.1256, + "step": 74 + }, + { + "epoch": 0.64, + "grad_norm": 0.11976960918968543, + "learning_rate": 1.8750612633916997e-05, + "loss": 0.1144, + "step": 75 + }, + { + "epoch": 0.6485333333333333, + "grad_norm": 0.115805998298789, + "learning_rate": 1.8808135922807914e-05, + "loss": 0.1528, + "step": 76 + }, + { + "epoch": 0.6570666666666667, + "grad_norm": 0.10325948496697443, + "learning_rate": 1.8864907251724818e-05, + "loss": 0.1044, + "step": 77 + }, + { + "epoch": 0.6656, + "grad_norm": 0.09595064346541006, + "learning_rate": 1.8920946026904802e-05, + "loss": 0.1534, + "step": 78 + }, + { + "epoch": 0.6741333333333334, + "grad_norm": 0.08796742845240496, + "learning_rate": 1.8976270912904414e-05, + "loss": 0.1155, + "step": 79 + }, + { + "epoch": 0.6826666666666666, + "grad_norm": 0.08218991738379527, + "learning_rate": 1.9030899869919434e-05, + "loss": 0.1311, + "step": 80 + }, + { + "epoch": 0.6912, + "grad_norm": 0.08290815261109215, + "learning_rate": 1.9084850188786497e-05, + "loss": 0.11, + "step": 81 + }, + { + "epoch": 0.6997333333333333, + "grad_norm": 0.0794132180176064, + "learning_rate": 1.9138138523837165e-05, + "loss": 0.1135, + "step": 82 + }, + { + "epoch": 0.7082666666666667, + "grad_norm": 0.06934410705255296, + "learning_rate": 1.919078092376074e-05, + "loss": 0.109, + "step": 83 + }, + { + "epoch": 0.7168, + "grad_norm": 0.09000563031870593, + "learning_rate": 1.9242792860618813e-05, + "loss": 0.12, + "step": 84 + }, + { + "epoch": 0.7253333333333334, + "grad_norm": 0.1134042277879818, + "learning_rate": 1.929418925714293e-05, + "loss": 0.1223, + "step": 85 + }, + { + "epoch": 0.7338666666666667, + "grad_norm": 0.09118764690233076, + "learning_rate": 1.9344984512435673e-05, + "loss": 0.1459, + "step": 86 + }, + { + "epoch": 0.7424, + "grad_norm": 0.07873016754353963, + "learning_rate": 1.9395192526186183e-05, + "loss": 0.1422, + "step": 87 + }, + { + "epoch": 0.7509333333333333, + "grad_norm": 0.1796495874463076, + "learning_rate": 1.9444826721501687e-05, + "loss": 0.1291, + "step": 88 + }, + { + "epoch": 0.7594666666666666, + "grad_norm": 0.0679589944174269, + "learning_rate": 1.9493900066449125e-05, + "loss": 0.108, + "step": 89 + }, + { + "epoch": 0.768, + "grad_norm": 0.08174688574235538, + "learning_rate": 1.9542425094393246e-05, + "loss": 0.1081, + "step": 90 + }, + { + "epoch": 0.7765333333333333, + "grad_norm": 0.057137370501406756, + "learning_rate": 1.9590413923210934e-05, + "loss": 0.0934, + "step": 91 + }, + { + "epoch": 0.7850666666666667, + "grad_norm": 0.06578111924908255, + "learning_rate": 1.9637878273455555e-05, + "loss": 0.1085, + "step": 92 + }, + { + "epoch": 0.7936, + "grad_norm": 0.08945990540906254, + "learning_rate": 1.968482948553935e-05, + "loss": 0.1747, + "step": 93 + }, + { + "epoch": 0.8021333333333334, + "grad_norm": 0.06183863311044229, + "learning_rate": 1.9731278535996986e-05, + "loss": 0.1136, + "step": 94 + }, + { + "epoch": 0.8106666666666666, + "grad_norm": 0.05777899602544702, + "learning_rate": 1.9777236052888476e-05, + "loss": 0.0984, + "step": 95 + }, + { + "epoch": 0.8192, + "grad_norm": 0.08130851607693534, + "learning_rate": 1.9822712330395683e-05, + "loss": 0.187, + "step": 96 + }, + { + "epoch": 0.8277333333333333, + "grad_norm": 0.06426546202002927, + "learning_rate": 1.986771734266245e-05, + "loss": 0.1296, + "step": 97 + }, + { + "epoch": 0.8362666666666667, + "grad_norm": 0.069692313707994, + "learning_rate": 1.991226075692495e-05, + "loss": 0.1404, + "step": 98 + }, + { + "epoch": 0.8448, + "grad_norm": 0.05494542266886729, + "learning_rate": 1.9956351945975496e-05, + "loss": 0.116, + "step": 99 + }, + { + "epoch": 0.8533333333333334, + "grad_norm": 0.07571686966840627, + "learning_rate": 1.9999999999999998e-05, + "loss": 0.1539, + "step": 100 + } + ], + "logging_steps": 1, + "max_steps": 351, + "num_input_tokens_seen": 0, + "num_train_epochs": 3, + "save_steps": 20, + "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.4183197916633498e+18, + "train_batch_size": 16, + "trial_name": null, + "trial_params": null +} diff --git a/checkpoint-100/training_args.bin b/checkpoint-100/training_args.bin new file mode 100644 index 0000000000000000000000000000000000000000..8ac842d29fc6ad3e132cb7208dda5b61dd1079ee --- /dev/null +++ b/checkpoint-100/training_args.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:aa4edad1da5557fcd52a6da980443588016cead6f0444a3562cfa68029c66a04 +size 6840 diff --git a/checkpoint-100/zero_to_fp32.py b/checkpoint-100/zero_to_fp32.py new file mode 100644 index 0000000000000000000000000000000000000000..49b846633d6eb1e836e34681e44033581f4edb7b --- /dev/null +++ b/checkpoint-100/zero_to_fp32.py @@ -0,0 +1,592 @@ +#!/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 . pytorch_model.bin + +import argparse +import torch +import glob +import math +import os +import re +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) + + +@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 parse_model_states(files): + zero_model_states = [] + for file in files: + state_dict = torch.load(file, map_location=device) + + 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 files: + state_dict = torch.load(f, map_location=device) + # 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 not ZERO_STAGE 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}") + + if zero_stage <= 2: + fp32_flat_groups = [state_dicts[i][OPTIMIZER_STATE_DICT][fp32_groups_key] for i in range(len(state_dicts))] + elif zero_stage == 3: + # if there is more than one param group, there will be multiple flattened tensors - one + # flattened tensor per group - for simplicity merge them into a single tensor + # + # XXX: could make the script more memory efficient for when there are multiple groups - it + # will require matching the sub-lists of param_shapes for each param group flattened tensor + + fp32_flat_groups = [ + torch.cat(state_dicts[i][OPTIMIZER_STATE_DICT][fp32_groups_key], 0) 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): + """ + 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}'") + + 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}") + + 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}') + + if zero_stage <= 2: + return _get_fp32_state_dict_from_zero2_checkpoint(world_size, fp32_flat_groups, zero_model_states) + elif zero_stage == 3: + return _get_fp32_state_dict_from_zero3_checkpoint(world_size, fp32_flat_groups, zero_model_states) + + +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): + state_dict = OrderedDict() + + # buffers + buffers = zero_model_states[0].buffers + state_dict.update(buffers) + if debug: + print(f"added {len(buffers)} buffers") + + _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") + + +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 = fp32_flat_groups[0].numel() * 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 + for name, shape in param_shapes.items(): + + 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}" + ) + + # XXX: memory usage doubles here + state_dict[name] = torch.cat( + tuple(fp32_flat_groups[i].narrow(0, offset, partitioned_numel) for i in range(world_size)), + 0).narrow(0, 0, unpartitioned_numel).view(shape) + 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): + state_dict = OrderedDict() + + # buffers + buffers = zero_model_states[0].buffers + state_dict.update(buffers) + if debug: + print(f"added {len(buffers)} buffers") + + _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 get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir, tag=None): + """ + 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`` + + Returns: + - pytorch ``state_dict`` + + Note: this approach may not work if your application doesn't have sufficient free CPU memory and + you may need to use the offline approach using the ``zero_to_fp32.py`` script that is saved with + the checkpoint. + + 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. + + """ + 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") + + return _get_fp32_state_dict_from_zero_checkpoint(ds_checkpoint_dir) + + +def convert_zero_checkpoint_to_fp32_state_dict(checkpoint_dir, output_file, tag=None): + """ + 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_file``: path to the pytorch fp32 state_dict output file (e.g. path/pytorch_model.bin) + - ``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`` + """ + + state_dict = get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir, tag) + print(f"Saving fp32 state dict to {output_file}") + torch.save(state_dict, output_file) + + +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(f"Extracting fp32 weights") + state_dict = get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir, tag) + + logger.info(f"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_file", + type=str, + help="path to the pytorch fp32 state_dict output file (e.g. path/checkpoint-12/pytorch_model.bin)") + 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("-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_file, tag=args.tag) diff --git a/checkpoint-120/README.md b/checkpoint-120/README.md new file mode 100644 index 0000000000000000000000000000000000000000..e7d4f706aeefc6bb2aa84e963870f345a14c4af9 --- /dev/null +++ b/checkpoint-120/README.md @@ -0,0 +1,202 @@ +--- +library_name: peft +base_model: ../ckpts/Meta-Llama-3-8B-Instruct +--- + +# 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.11.1 \ No newline at end of file diff --git a/checkpoint-120/adapter_config.json b/checkpoint-120/adapter_config.json new file mode 100644 index 0000000000000000000000000000000000000000..ad16c073ed8946d227350e8fe4e99d689a8ede54 --- /dev/null +++ b/checkpoint-120/adapter_config.json @@ -0,0 +1,35 @@ +{ + "alpha_pattern": {}, + "auto_mapping": null, + "base_model_name_or_path": "../ckpts/Meta-Llama-3-8B-Instruct", + "bias": "none", + "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": 32, + "lora_dropout": 0.1, + "megatron_config": null, + "megatron_core": "megatron.core", + "modules_to_save": null, + "peft_type": "LORA", + "r": 16, + "rank_pattern": {}, + "revision": null, + "target_modules": [ + "down_proj", + "gate_proj", + "q_proj", + "lm_head", + "o_proj", + "v_proj", + "up_proj", + "k_proj" + ], + "task_type": "CAUSAL_LM", + "use_dora": false, + "use_rslora": false +} \ No newline at end of file diff --git a/checkpoint-120/adapter_model.safetensors b/checkpoint-120/adapter_model.safetensors new file mode 100644 index 0000000000000000000000000000000000000000..9493442001d73e61f62fce764c9b35b520637662 --- /dev/null +++ b/checkpoint-120/adapter_model.safetensors @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:33e6839258702615da06d8aa30c9fd67b2657cce43937f62cf3927f85b0a8362 +size 1138856856 diff --git a/checkpoint-120/global_step120/bf16_zero_pp_rank_0_mp_rank_00_optim_states.pt b/checkpoint-120/global_step120/bf16_zero_pp_rank_0_mp_rank_00_optim_states.pt new file mode 100644 index 0000000000000000000000000000000000000000..4283e37a935e0b67841c3e3e74b279dbc27fbb4e --- /dev/null +++ b/checkpoint-120/global_step120/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:11b436ebd244ff8f8485f00d23b9c863c009715ce5d24e64a356edf305f17b6e +size 528781328 diff --git a/checkpoint-120/global_step120/mp_rank_00_model_states.pt b/checkpoint-120/global_step120/mp_rank_00_model_states.pt new file mode 100644 index 0000000000000000000000000000000000000000..d29971694e7a6b321cc8175a2ddc958f767579f3 --- /dev/null +++ b/checkpoint-120/global_step120/mp_rank_00_model_states.pt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2c17e1cbdbbc34d79755357fd83899cf1a03c70d31c45b9c5104634809569283 +size 199905337 diff --git a/checkpoint-120/latest b/checkpoint-120/latest new file mode 100644 index 0000000000000000000000000000000000000000..0e13e0563ec45a863d519305a1251d3e72b9e3e4 --- /dev/null +++ b/checkpoint-120/latest @@ -0,0 +1 @@ +global_step120 \ No newline at end of file diff --git a/checkpoint-120/rng_state.pth b/checkpoint-120/rng_state.pth new file mode 100644 index 0000000000000000000000000000000000000000..07287c645140a43d7c9c2d0aa6ee90520966e222 --- /dev/null +++ b/checkpoint-120/rng_state.pth @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9ae17b05257a556f53e7168228629d1bb3ae5e5c9000a8d7dd9d2cc833ef3948 +size 14244 diff --git a/checkpoint-120/trainer_state.json b/checkpoint-120/trainer_state.json new file mode 100644 index 0000000000000000000000000000000000000000..8fa28c6e36ab8566052930f668692e15e2519237 --- /dev/null +++ b/checkpoint-120/trainer_state.json @@ -0,0 +1,873 @@ +{ + "best_metric": null, + "best_model_checkpoint": null, + "epoch": 1.024, + "eval_steps": 500, + "global_step": 120, + "is_hyper_param_search": false, + "is_local_process_zero": true, + "is_world_process_zero": true, + "log_history": [ + { + "epoch": 0.008533333333333334, + "grad_norm": 100.21848203113535, + "learning_rate": 0.0, + "loss": 7.1962, + "step": 1 + }, + { + "epoch": 0.017066666666666667, + "grad_norm": 96.43006188910957, + "learning_rate": 3.0102999566398115e-06, + "loss": 6.9414, + "step": 2 + }, + { + "epoch": 0.0256, + "grad_norm": 97.35803466618715, + "learning_rate": 4.771212547196624e-06, + "loss": 7.0102, + "step": 3 + }, + { + "epoch": 0.034133333333333335, + "grad_norm": 95.14837816372646, + "learning_rate": 6.020599913279623e-06, + "loss": 6.5295, + "step": 4 + }, + { + "epoch": 0.042666666666666665, + "grad_norm": 91.76544275692784, + "learning_rate": 6.989700043360187e-06, + "loss": 6.4806, + "step": 5 + }, + { + "epoch": 0.0512, + "grad_norm": 84.4494318688335, + "learning_rate": 7.781512503836437e-06, + "loss": 6.4194, + "step": 6 + }, + { + "epoch": 0.05973333333333333, + "grad_norm": 71.37977490595638, + "learning_rate": 8.450980400142568e-06, + "loss": 5.4953, + "step": 7 + }, + { + "epoch": 0.06826666666666667, + "grad_norm": 49.31153456754566, + "learning_rate": 9.030899869919434e-06, + "loss": 5.4123, + "step": 8 + }, + { + "epoch": 0.0768, + "grad_norm": 20.37296364560341, + "learning_rate": 9.542425094393249e-06, + "loss": 5.2334, + "step": 9 + }, + { + "epoch": 0.08533333333333333, + "grad_norm": 7.968467079076881, + "learning_rate": 9.999999999999999e-06, + "loss": 5.0282, + "step": 10 + }, + { + "epoch": 0.09386666666666667, + "grad_norm": 3.559446532055649, + "learning_rate": 1.041392685158225e-05, + "loss": 4.612, + "step": 11 + }, + { + "epoch": 0.1024, + "grad_norm": 3.5528846947995674, + "learning_rate": 1.0791812460476248e-05, + "loss": 4.9475, + "step": 12 + }, + { + "epoch": 0.11093333333333333, + "grad_norm": 3.541968897471334, + "learning_rate": 1.1139433523068365e-05, + "loss": 4.2777, + "step": 13 + }, + { + "epoch": 0.11946666666666667, + "grad_norm": 3.54718070036198, + "learning_rate": 1.1461280356782378e-05, + "loss": 4.3507, + "step": 14 + }, + { + "epoch": 0.128, + "grad_norm": 3.8632334830606747, + "learning_rate": 1.1760912590556813e-05, + "loss": 4.5364, + "step": 15 + }, + { + "epoch": 0.13653333333333334, + "grad_norm": 3.6637424744054004, + "learning_rate": 1.2041199826559246e-05, + "loss": 3.9672, + "step": 16 + }, + { + "epoch": 0.14506666666666668, + "grad_norm": 3.919802904818311, + "learning_rate": 1.230448921378274e-05, + "loss": 4.0618, + "step": 17 + }, + { + "epoch": 0.1536, + "grad_norm": 4.71904950738746, + "learning_rate": 1.2552725051033058e-05, + "loss": 4.6656, + "step": 18 + }, + { + "epoch": 0.16213333333333332, + "grad_norm": 4.6656317698690835, + "learning_rate": 1.2787536009528288e-05, + "loss": 4.1131, + "step": 19 + }, + { + "epoch": 0.17066666666666666, + "grad_norm": 5.145138692367417, + "learning_rate": 1.301029995663981e-05, + "loss": 4.0989, + "step": 20 + }, + { + "epoch": 0.1792, + "grad_norm": 5.923538014759818, + "learning_rate": 1.3222192947339192e-05, + "loss": 4.4991, + "step": 21 + }, + { + "epoch": 0.18773333333333334, + "grad_norm": 5.941056962941364, + "learning_rate": 1.3424226808222062e-05, + "loss": 4.0836, + "step": 22 + }, + { + "epoch": 0.19626666666666667, + "grad_norm": 6.171026012117947, + "learning_rate": 1.3617278360175927e-05, + "loss": 3.6861, + "step": 23 + }, + { + "epoch": 0.2048, + "grad_norm": 7.130542138930838, + "learning_rate": 1.380211241711606e-05, + "loss": 4.0958, + "step": 24 + }, + { + "epoch": 0.21333333333333335, + "grad_norm": 7.328837606110418, + "learning_rate": 1.3979400086720374e-05, + "loss": 3.9524, + "step": 25 + }, + { + "epoch": 0.22186666666666666, + "grad_norm": 6.923489005711429, + "learning_rate": 1.4149733479708178e-05, + "loss": 3.6062, + "step": 26 + }, + { + "epoch": 0.2304, + "grad_norm": 6.409498926059221, + "learning_rate": 1.4313637641589872e-05, + "loss": 3.2034, + "step": 27 + }, + { + "epoch": 0.23893333333333333, + "grad_norm": 5.781628405584682, + "learning_rate": 1.4471580313422191e-05, + "loss": 2.8158, + "step": 28 + }, + { + "epoch": 0.24746666666666667, + "grad_norm": 6.2927590068243315, + "learning_rate": 1.4623979978989559e-05, + "loss": 2.9803, + "step": 29 + }, + { + "epoch": 0.256, + "grad_norm": 6.103844678630006, + "learning_rate": 1.4771212547196623e-05, + "loss": 2.847, + "step": 30 + }, + { + "epoch": 0.26453333333333334, + "grad_norm": 7.656341925867144, + "learning_rate": 1.4913616938342726e-05, + "loss": 3.0907, + "step": 31 + }, + { + "epoch": 0.2730666666666667, + "grad_norm": 6.324242877501844, + "learning_rate": 1.5051499783199059e-05, + "loss": 2.3467, + "step": 32 + }, + { + "epoch": 0.2816, + "grad_norm": 7.606313101162739, + "learning_rate": 1.5185139398778874e-05, + "loss": 2.5292, + "step": 33 + }, + { + "epoch": 0.29013333333333335, + "grad_norm": 8.553792493849265, + "learning_rate": 1.531478917042255e-05, + "loss": 2.4547, + "step": 34 + }, + { + "epoch": 0.2986666666666667, + "grad_norm": 8.483368703272543, + "learning_rate": 1.5440680443502753e-05, + "loss": 2.1956, + "step": 35 + }, + { + "epoch": 0.3072, + "grad_norm": 8.364739352838077, + "learning_rate": 1.5563025007672873e-05, + "loss": 1.8552, + "step": 36 + }, + { + "epoch": 0.3157333333333333, + "grad_norm": 9.37663682000104, + "learning_rate": 1.5682017240669948e-05, + "loss": 1.9228, + "step": 37 + }, + { + "epoch": 0.32426666666666665, + "grad_norm": 9.823047193440066, + "learning_rate": 1.57978359661681e-05, + "loss": 1.7033, + "step": 38 + }, + { + "epoch": 0.3328, + "grad_norm": 9.692618512955894, + "learning_rate": 1.591064607026499e-05, + "loss": 1.3768, + "step": 39 + }, + { + "epoch": 0.3413333333333333, + "grad_norm": 9.08889021911031, + "learning_rate": 1.6020599913279622e-05, + "loss": 1.3015, + "step": 40 + }, + { + "epoch": 0.34986666666666666, + "grad_norm": 8.081534221516058, + "learning_rate": 1.6127838567197353e-05, + "loss": 0.9228, + "step": 41 + }, + { + "epoch": 0.3584, + "grad_norm": 6.238638048950311, + "learning_rate": 1.6232492903979005e-05, + "loss": 0.7267, + "step": 42 + }, + { + "epoch": 0.36693333333333333, + "grad_norm": 3.4058036861773604, + "learning_rate": 1.6334684555795865e-05, + "loss": 0.5875, + "step": 43 + }, + { + "epoch": 0.37546666666666667, + "grad_norm": 2.079163829467713, + "learning_rate": 1.6434526764861872e-05, + "loss": 0.6355, + "step": 44 + }, + { + "epoch": 0.384, + "grad_norm": 1.5597487833024746, + "learning_rate": 1.6532125137753435e-05, + "loss": 0.5106, + "step": 45 + }, + { + "epoch": 0.39253333333333335, + "grad_norm": 2.491689602375256, + "learning_rate": 1.662757831681574e-05, + "loss": 0.6454, + "step": 46 + }, + { + "epoch": 0.4010666666666667, + "grad_norm": 2.010880438195854, + "learning_rate": 1.672097857935717e-05, + "loss": 0.4757, + "step": 47 + }, + { + "epoch": 0.4096, + "grad_norm": 1.9452805114322096, + "learning_rate": 1.681241237375587e-05, + "loss": 0.4133, + "step": 48 + }, + { + "epoch": 0.41813333333333336, + "grad_norm": 1.7620848552306103, + "learning_rate": 1.6901960800285137e-05, + "loss": 0.4004, + "step": 49 + }, + { + "epoch": 0.4266666666666667, + "grad_norm": 1.278224489774809, + "learning_rate": 1.6989700043360187e-05, + "loss": 0.3523, + "step": 50 + }, + { + "epoch": 0.4352, + "grad_norm": 1.6151354758303231, + "learning_rate": 1.7075701760979363e-05, + "loss": 0.4317, + "step": 51 + }, + { + "epoch": 0.4437333333333333, + "grad_norm": 1.3451396055695035, + "learning_rate": 1.716003343634799e-05, + "loss": 0.3474, + "step": 52 + }, + { + "epoch": 0.45226666666666665, + "grad_norm": 1.6814977782362666, + "learning_rate": 1.724275869600789e-05, + "loss": 0.3706, + "step": 53 + }, + { + "epoch": 0.4608, + "grad_norm": 1.1682442432688667, + "learning_rate": 1.7323937598229687e-05, + "loss": 0.3488, + "step": 54 + }, + { + "epoch": 0.4693333333333333, + "grad_norm": 0.8839814540462471, + "learning_rate": 1.7403626894942437e-05, + "loss": 0.293, + "step": 55 + }, + { + "epoch": 0.47786666666666666, + "grad_norm": 0.7974304806295485, + "learning_rate": 1.7481880270062003e-05, + "loss": 0.2717, + "step": 56 + }, + { + "epoch": 0.4864, + "grad_norm": 0.6232203657585239, + "learning_rate": 1.7558748556724913e-05, + "loss": 0.1741, + "step": 57 + }, + { + "epoch": 0.49493333333333334, + "grad_norm": 0.6850688604563008, + "learning_rate": 1.763427993562937e-05, + "loss": 0.228, + "step": 58 + }, + { + "epoch": 0.5034666666666666, + "grad_norm": 0.5923826384300431, + "learning_rate": 1.7708520116421443e-05, + "loss": 0.2131, + "step": 59 + }, + { + "epoch": 0.512, + "grad_norm": 0.489754430485032, + "learning_rate": 1.7781512503836432e-05, + "loss": 0.165, + "step": 60 + }, + { + "epoch": 0.5205333333333333, + "grad_norm": 0.5280940052395061, + "learning_rate": 1.7853298350107667e-05, + "loss": 0.1658, + "step": 61 + }, + { + "epoch": 0.5290666666666667, + "grad_norm": 0.4750905992036739, + "learning_rate": 1.7923916894982537e-05, + "loss": 0.1438, + "step": 62 + }, + { + "epoch": 0.5376, + "grad_norm": 0.4162998392722401, + "learning_rate": 1.7993405494535815e-05, + "loss": 0.1555, + "step": 63 + }, + { + "epoch": 0.5461333333333334, + "grad_norm": 0.26863266246370443, + "learning_rate": 1.806179973983887e-05, + "loss": 0.1323, + "step": 64 + }, + { + "epoch": 0.5546666666666666, + "grad_norm": 0.26534221125601215, + "learning_rate": 1.8129133566428553e-05, + "loss": 0.1671, + "step": 65 + }, + { + "epoch": 0.5632, + "grad_norm": 0.2548662962257576, + "learning_rate": 1.8195439355418686e-05, + "loss": 0.1308, + "step": 66 + }, + { + "epoch": 0.5717333333333333, + "grad_norm": 0.18045394638578796, + "learning_rate": 1.8260748027008263e-05, + "loss": 0.1262, + "step": 67 + }, + { + "epoch": 0.5802666666666667, + "grad_norm": 0.17070388073612064, + "learning_rate": 1.8325089127062364e-05, + "loss": 0.1192, + "step": 68 + }, + { + "epoch": 0.5888, + "grad_norm": 0.1531381679244776, + "learning_rate": 1.8388490907372553e-05, + "loss": 0.1274, + "step": 69 + }, + { + "epoch": 0.5973333333333334, + "grad_norm": 0.18196434993687946, + "learning_rate": 1.8450980400142568e-05, + "loss": 0.1375, + "step": 70 + }, + { + "epoch": 0.6058666666666667, + "grad_norm": 0.15324416972951205, + "learning_rate": 1.8512583487190752e-05, + "loss": 0.1599, + "step": 71 + }, + { + "epoch": 0.6144, + "grad_norm": 0.10884462064503801, + "learning_rate": 1.857332496431268e-05, + "loss": 0.1041, + "step": 72 + }, + { + "epoch": 0.6229333333333333, + "grad_norm": 0.12915133528192668, + "learning_rate": 1.8633228601204555e-05, + "loss": 0.1406, + "step": 73 + }, + { + "epoch": 0.6314666666666666, + "grad_norm": 0.12553425699952878, + "learning_rate": 1.8692317197309763e-05, + "loss": 0.1256, + "step": 74 + }, + { + "epoch": 0.64, + "grad_norm": 0.11976960918968543, + "learning_rate": 1.8750612633916997e-05, + "loss": 0.1144, + "step": 75 + }, + { + "epoch": 0.6485333333333333, + "grad_norm": 0.115805998298789, + "learning_rate": 1.8808135922807914e-05, + "loss": 0.1528, + "step": 76 + }, + { + "epoch": 0.6570666666666667, + "grad_norm": 0.10325948496697443, + "learning_rate": 1.8864907251724818e-05, + "loss": 0.1044, + "step": 77 + }, + { + "epoch": 0.6656, + "grad_norm": 0.09595064346541006, + "learning_rate": 1.8920946026904802e-05, + "loss": 0.1534, + "step": 78 + }, + { + "epoch": 0.6741333333333334, + "grad_norm": 0.08796742845240496, + "learning_rate": 1.8976270912904414e-05, + "loss": 0.1155, + "step": 79 + }, + { + "epoch": 0.6826666666666666, + "grad_norm": 0.08218991738379527, + "learning_rate": 1.9030899869919434e-05, + "loss": 0.1311, + "step": 80 + }, + { + "epoch": 0.6912, + "grad_norm": 0.08290815261109215, + "learning_rate": 1.9084850188786497e-05, + "loss": 0.11, + "step": 81 + }, + { + "epoch": 0.6997333333333333, + "grad_norm": 0.0794132180176064, + "learning_rate": 1.9138138523837165e-05, + "loss": 0.1135, + "step": 82 + }, + { + "epoch": 0.7082666666666667, + "grad_norm": 0.06934410705255296, + "learning_rate": 1.919078092376074e-05, + "loss": 0.109, + "step": 83 + }, + { + "epoch": 0.7168, + "grad_norm": 0.09000563031870593, + "learning_rate": 1.9242792860618813e-05, + "loss": 0.12, + "step": 84 + }, + { + "epoch": 0.7253333333333334, + "grad_norm": 0.1134042277879818, + "learning_rate": 1.929418925714293e-05, + "loss": 0.1223, + "step": 85 + }, + { + "epoch": 0.7338666666666667, + "grad_norm": 0.09118764690233076, + "learning_rate": 1.9344984512435673e-05, + "loss": 0.1459, + "step": 86 + }, + { + "epoch": 0.7424, + "grad_norm": 0.07873016754353963, + "learning_rate": 1.9395192526186183e-05, + "loss": 0.1422, + "step": 87 + }, + { + "epoch": 0.7509333333333333, + "grad_norm": 0.1796495874463076, + "learning_rate": 1.9444826721501687e-05, + "loss": 0.1291, + "step": 88 + }, + { + "epoch": 0.7594666666666666, + "grad_norm": 0.0679589944174269, + "learning_rate": 1.9493900066449125e-05, + "loss": 0.108, + "step": 89 + }, + { + "epoch": 0.768, + "grad_norm": 0.08174688574235538, + "learning_rate": 1.9542425094393246e-05, + "loss": 0.1081, + "step": 90 + }, + { + "epoch": 0.7765333333333333, + "grad_norm": 0.057137370501406756, + "learning_rate": 1.9590413923210934e-05, + "loss": 0.0934, + "step": 91 + }, + { + "epoch": 0.7850666666666667, + "grad_norm": 0.06578111924908255, + "learning_rate": 1.9637878273455555e-05, + "loss": 0.1085, + "step": 92 + }, + { + "epoch": 0.7936, + "grad_norm": 0.08945990540906254, + "learning_rate": 1.968482948553935e-05, + "loss": 0.1747, + "step": 93 + }, + { + "epoch": 0.8021333333333334, + "grad_norm": 0.06183863311044229, + "learning_rate": 1.9731278535996986e-05, + "loss": 0.1136, + "step": 94 + }, + { + "epoch": 0.8106666666666666, + "grad_norm": 0.05777899602544702, + "learning_rate": 1.9777236052888476e-05, + "loss": 0.0984, + "step": 95 + }, + { + "epoch": 0.8192, + "grad_norm": 0.08130851607693534, + "learning_rate": 1.9822712330395683e-05, + "loss": 0.187, + "step": 96 + }, + { + "epoch": 0.8277333333333333, + "grad_norm": 0.06426546202002927, + "learning_rate": 1.986771734266245e-05, + "loss": 0.1296, + "step": 97 + }, + { + "epoch": 0.8362666666666667, + "grad_norm": 0.069692313707994, + "learning_rate": 1.991226075692495e-05, + "loss": 0.1404, + "step": 98 + }, + { + "epoch": 0.8448, + "grad_norm": 0.05494542266886729, + "learning_rate": 1.9956351945975496e-05, + "loss": 0.116, + "step": 99 + }, + { + "epoch": 0.8533333333333334, + "grad_norm": 0.07571686966840627, + "learning_rate": 1.9999999999999998e-05, + "loss": 0.1539, + "step": 100 + }, + { + "epoch": 0.8618666666666667, + "grad_norm": 0.054351059117603705, + "learning_rate": 2e-05, + "loss": 0.1037, + "step": 101 + }, + { + "epoch": 0.8704, + "grad_norm": 0.06531899611551092, + "learning_rate": 2e-05, + "loss": 0.0827, + "step": 102 + }, + { + "epoch": 0.8789333333333333, + "grad_norm": 0.06131678646504652, + "learning_rate": 2e-05, + "loss": 0.1266, + "step": 103 + }, + { + "epoch": 0.8874666666666666, + "grad_norm": 0.06850220540661824, + "learning_rate": 2e-05, + "loss": 0.1456, + "step": 104 + }, + { + "epoch": 0.896, + "grad_norm": 0.05806908951252483, + "learning_rate": 2e-05, + "loss": 0.0954, + "step": 105 + }, + { + "epoch": 0.9045333333333333, + "grad_norm": 0.06503642452033717, + "learning_rate": 2e-05, + "loss": 0.1417, + "step": 106 + }, + { + "epoch": 0.9130666666666667, + "grad_norm": 0.050486271853277066, + "learning_rate": 2e-05, + "loss": 0.0959, + "step": 107 + }, + { + "epoch": 0.9216, + "grad_norm": 0.07746063813802379, + "learning_rate": 2e-05, + "loss": 0.1256, + "step": 108 + }, + { + "epoch": 0.9301333333333334, + "grad_norm": 0.051231172380840004, + "learning_rate": 2e-05, + "loss": 0.1116, + "step": 109 + }, + { + "epoch": 0.9386666666666666, + "grad_norm": 0.056296443557859455, + "learning_rate": 2e-05, + "loss": 0.1056, + "step": 110 + }, + { + "epoch": 0.9472, + "grad_norm": 0.05058663240713958, + "learning_rate": 2e-05, + "loss": 0.0971, + "step": 111 + }, + { + "epoch": 0.9557333333333333, + "grad_norm": 0.05532886570130611, + "learning_rate": 2e-05, + "loss": 0.1086, + "step": 112 + }, + { + "epoch": 0.9642666666666667, + "grad_norm": 0.05327811326654907, + "learning_rate": 2e-05, + "loss": 0.0989, + "step": 113 + }, + { + "epoch": 0.9728, + "grad_norm": 0.05663279364147864, + "learning_rate": 2e-05, + "loss": 0.0958, + "step": 114 + }, + { + "epoch": 0.9813333333333333, + "grad_norm": 0.04930904541225805, + "learning_rate": 2e-05, + "loss": 0.0887, + "step": 115 + }, + { + "epoch": 0.9898666666666667, + "grad_norm": 0.06096947951115022, + "learning_rate": 2e-05, + "loss": 0.106, + "step": 116 + }, + { + "epoch": 0.9984, + "grad_norm": 0.050092322361182495, + "learning_rate": 2e-05, + "loss": 0.0931, + "step": 117 + }, + { + "epoch": 1.0069333333333332, + "grad_norm": 0.04980408443758999, + "learning_rate": 2e-05, + "loss": 0.0955, + "step": 118 + }, + { + "epoch": 1.0154666666666667, + "grad_norm": 0.051183082721834305, + "learning_rate": 2e-05, + "loss": 0.1049, + "step": 119 + }, + { + "epoch": 1.024, + "grad_norm": 0.04332220265802814, + "learning_rate": 2e-05, + "loss": 0.0983, + "step": 120 + } + ], + "logging_steps": 1, + "max_steps": 351, + "num_input_tokens_seen": 0, + "num_train_epochs": 3, + "save_steps": 20, + "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.7047845829953454e+18, + "train_batch_size": 16, + "trial_name": null, + "trial_params": null +} diff --git a/checkpoint-120/training_args.bin b/checkpoint-120/training_args.bin new file mode 100644 index 0000000000000000000000000000000000000000..8ac842d29fc6ad3e132cb7208dda5b61dd1079ee --- /dev/null +++ b/checkpoint-120/training_args.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:aa4edad1da5557fcd52a6da980443588016cead6f0444a3562cfa68029c66a04 +size 6840 diff --git a/checkpoint-120/zero_to_fp32.py b/checkpoint-120/zero_to_fp32.py new file mode 100644 index 0000000000000000000000000000000000000000..49b846633d6eb1e836e34681e44033581f4edb7b --- /dev/null +++ b/checkpoint-120/zero_to_fp32.py @@ -0,0 +1,592 @@ +#!/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 . pytorch_model.bin + +import argparse +import torch +import glob +import math +import os +import re +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) + + +@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 parse_model_states(files): + zero_model_states = [] + for file in files: + state_dict = torch.load(file, map_location=device) + + 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 files: + state_dict = torch.load(f, map_location=device) + # 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 not ZERO_STAGE 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}") + + if zero_stage <= 2: + fp32_flat_groups = [state_dicts[i][OPTIMIZER_STATE_DICT][fp32_groups_key] for i in range(len(state_dicts))] + elif zero_stage == 3: + # if there is more than one param group, there will be multiple flattened tensors - one + # flattened tensor per group - for simplicity merge them into a single tensor + # + # XXX: could make the script more memory efficient for when there are multiple groups - it + # will require matching the sub-lists of param_shapes for each param group flattened tensor + + fp32_flat_groups = [ + torch.cat(state_dicts[i][OPTIMIZER_STATE_DICT][fp32_groups_key], 0) 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): + """ + 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}'") + + 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}") + + 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}') + + if zero_stage <= 2: + return _get_fp32_state_dict_from_zero2_checkpoint(world_size, fp32_flat_groups, zero_model_states) + elif zero_stage == 3: + return _get_fp32_state_dict_from_zero3_checkpoint(world_size, fp32_flat_groups, zero_model_states) + + +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): + state_dict = OrderedDict() + + # buffers + buffers = zero_model_states[0].buffers + state_dict.update(buffers) + if debug: + print(f"added {len(buffers)} buffers") + + _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") + + +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 = fp32_flat_groups[0].numel() * 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 + for name, shape in param_shapes.items(): + + 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}" + ) + + # XXX: memory usage doubles here + state_dict[name] = torch.cat( + tuple(fp32_flat_groups[i].narrow(0, offset, partitioned_numel) for i in range(world_size)), + 0).narrow(0, 0, unpartitioned_numel).view(shape) + 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): + state_dict = OrderedDict() + + # buffers + buffers = zero_model_states[0].buffers + state_dict.update(buffers) + if debug: + print(f"added {len(buffers)} buffers") + + _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 get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir, tag=None): + """ + 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`` + + Returns: + - pytorch ``state_dict`` + + Note: this approach may not work if your application doesn't have sufficient free CPU memory and + you may need to use the offline approach using the ``zero_to_fp32.py`` script that is saved with + the checkpoint. + + 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. + + """ + 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") + + return _get_fp32_state_dict_from_zero_checkpoint(ds_checkpoint_dir) + + +def convert_zero_checkpoint_to_fp32_state_dict(checkpoint_dir, output_file, tag=None): + """ + 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_file``: path to the pytorch fp32 state_dict output file (e.g. path/pytorch_model.bin) + - ``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`` + """ + + state_dict = get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir, tag) + print(f"Saving fp32 state dict to {output_file}") + torch.save(state_dict, output_file) + + +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(f"Extracting fp32 weights") + state_dict = get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir, tag) + + logger.info(f"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_file", + type=str, + help="path to the pytorch fp32 state_dict output file (e.g. path/checkpoint-12/pytorch_model.bin)") + 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("-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_file, tag=args.tag) diff --git a/checkpoint-140/README.md b/checkpoint-140/README.md new file mode 100644 index 0000000000000000000000000000000000000000..e7d4f706aeefc6bb2aa84e963870f345a14c4af9 --- /dev/null +++ b/checkpoint-140/README.md @@ -0,0 +1,202 @@ +--- +library_name: peft +base_model: ../ckpts/Meta-Llama-3-8B-Instruct +--- + +# 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.11.1 \ No newline at end of file diff --git a/checkpoint-140/adapter_config.json b/checkpoint-140/adapter_config.json new file mode 100644 index 0000000000000000000000000000000000000000..ad16c073ed8946d227350e8fe4e99d689a8ede54 --- /dev/null +++ b/checkpoint-140/adapter_config.json @@ -0,0 +1,35 @@ +{ + "alpha_pattern": {}, + "auto_mapping": null, + "base_model_name_or_path": "../ckpts/Meta-Llama-3-8B-Instruct", + "bias": "none", + "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": 32, + "lora_dropout": 0.1, + "megatron_config": null, + "megatron_core": "megatron.core", + "modules_to_save": null, + "peft_type": "LORA", + "r": 16, + "rank_pattern": {}, + "revision": null, + "target_modules": [ + "down_proj", + "gate_proj", + "q_proj", + "lm_head", + "o_proj", + "v_proj", + "up_proj", + "k_proj" + ], + "task_type": "CAUSAL_LM", + "use_dora": false, + "use_rslora": false +} \ No newline at end of file diff --git a/checkpoint-140/adapter_model.safetensors b/checkpoint-140/adapter_model.safetensors new file mode 100644 index 0000000000000000000000000000000000000000..f90ce0829cbffa6e09b32434bd4cff5e73374710 --- /dev/null +++ b/checkpoint-140/adapter_model.safetensors @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b12f85af7122bcce5f6997bec8d9a8a845cf9ab8d2c4f241d37562051e34c216 +size 1138856856 diff --git a/checkpoint-140/global_step140/bf16_zero_pp_rank_0_mp_rank_00_optim_states.pt b/checkpoint-140/global_step140/bf16_zero_pp_rank_0_mp_rank_00_optim_states.pt new file mode 100644 index 0000000000000000000000000000000000000000..9bf4b0bdf91ea891ccefd945807690103d866a32 --- /dev/null +++ b/checkpoint-140/global_step140/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:8993927bbec291df7a8a041058bc3762b88d9ca9fcfbdccdabc686717c9c5f5d +size 528781328 diff --git a/checkpoint-140/global_step140/mp_rank_00_model_states.pt b/checkpoint-140/global_step140/mp_rank_00_model_states.pt new file mode 100644 index 0000000000000000000000000000000000000000..ab1a0d5e2b82ed338fe9cc9f94bd2806ec8ca2cb --- /dev/null +++ b/checkpoint-140/global_step140/mp_rank_00_model_states.pt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a4dca3099b75369d573830bab987eb6f984e58440ba145f2f47df24a9212b7c4 +size 199905337 diff --git a/checkpoint-140/latest b/checkpoint-140/latest new file mode 100644 index 0000000000000000000000000000000000000000..fd2b9aef86529798137c2868d556e873a23c785c --- /dev/null +++ b/checkpoint-140/latest @@ -0,0 +1 @@ +global_step140 \ No newline at end of file diff --git a/checkpoint-140/rng_state.pth b/checkpoint-140/rng_state.pth new file mode 100644 index 0000000000000000000000000000000000000000..180e748a0f61603af87ab992e933142ff04a6b93 --- /dev/null +++ b/checkpoint-140/rng_state.pth @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cb5b9188bbc87bb2ff7dba4844a90c5c236962fc66f3da23e5af9ee0eda34a1b +size 14244 diff --git a/checkpoint-140/trainer_state.json b/checkpoint-140/trainer_state.json new file mode 100644 index 0000000000000000000000000000000000000000..d3c8bcf3579b682d1042be3748a2d489e81fb7ed --- /dev/null +++ b/checkpoint-140/trainer_state.json @@ -0,0 +1,1013 @@ +{ + "best_metric": null, + "best_model_checkpoint": null, + "epoch": 1.1946666666666665, + "eval_steps": 500, + "global_step": 140, + "is_hyper_param_search": false, + "is_local_process_zero": true, + "is_world_process_zero": true, + "log_history": [ + { + "epoch": 0.008533333333333334, + "grad_norm": 100.21848203113535, + "learning_rate": 0.0, + "loss": 7.1962, + "step": 1 + }, + { + "epoch": 0.017066666666666667, + "grad_norm": 96.43006188910957, + "learning_rate": 3.0102999566398115e-06, + "loss": 6.9414, + "step": 2 + }, + { + "epoch": 0.0256, + "grad_norm": 97.35803466618715, + "learning_rate": 4.771212547196624e-06, + "loss": 7.0102, + "step": 3 + }, + { + "epoch": 0.034133333333333335, + "grad_norm": 95.14837816372646, + "learning_rate": 6.020599913279623e-06, + "loss": 6.5295, + "step": 4 + }, + { + "epoch": 0.042666666666666665, + "grad_norm": 91.76544275692784, + "learning_rate": 6.989700043360187e-06, + "loss": 6.4806, + "step": 5 + }, + { + "epoch": 0.0512, + "grad_norm": 84.4494318688335, + "learning_rate": 7.781512503836437e-06, + "loss": 6.4194, + "step": 6 + }, + { + "epoch": 0.05973333333333333, + "grad_norm": 71.37977490595638, + "learning_rate": 8.450980400142568e-06, + "loss": 5.4953, + "step": 7 + }, + { + "epoch": 0.06826666666666667, + "grad_norm": 49.31153456754566, + "learning_rate": 9.030899869919434e-06, + "loss": 5.4123, + "step": 8 + }, + { + "epoch": 0.0768, + "grad_norm": 20.37296364560341, + "learning_rate": 9.542425094393249e-06, + "loss": 5.2334, + "step": 9 + }, + { + "epoch": 0.08533333333333333, + "grad_norm": 7.968467079076881, + "learning_rate": 9.999999999999999e-06, + "loss": 5.0282, + "step": 10 + }, + { + "epoch": 0.09386666666666667, + "grad_norm": 3.559446532055649, + "learning_rate": 1.041392685158225e-05, + "loss": 4.612, + "step": 11 + }, + { + "epoch": 0.1024, + "grad_norm": 3.5528846947995674, + "learning_rate": 1.0791812460476248e-05, + "loss": 4.9475, + "step": 12 + }, + { + "epoch": 0.11093333333333333, + "grad_norm": 3.541968897471334, + "learning_rate": 1.1139433523068365e-05, + "loss": 4.2777, + "step": 13 + }, + { + "epoch": 0.11946666666666667, + "grad_norm": 3.54718070036198, + "learning_rate": 1.1461280356782378e-05, + "loss": 4.3507, + "step": 14 + }, + { + "epoch": 0.128, + "grad_norm": 3.8632334830606747, + "learning_rate": 1.1760912590556813e-05, + "loss": 4.5364, + "step": 15 + }, + { + "epoch": 0.13653333333333334, + "grad_norm": 3.6637424744054004, + "learning_rate": 1.2041199826559246e-05, + "loss": 3.9672, + "step": 16 + }, + { + "epoch": 0.14506666666666668, + "grad_norm": 3.919802904818311, + "learning_rate": 1.230448921378274e-05, + "loss": 4.0618, + "step": 17 + }, + { + "epoch": 0.1536, + "grad_norm": 4.71904950738746, + "learning_rate": 1.2552725051033058e-05, + "loss": 4.6656, + "step": 18 + }, + { + "epoch": 0.16213333333333332, + "grad_norm": 4.6656317698690835, + "learning_rate": 1.2787536009528288e-05, + "loss": 4.1131, + "step": 19 + }, + { + "epoch": 0.17066666666666666, + "grad_norm": 5.145138692367417, + "learning_rate": 1.301029995663981e-05, + "loss": 4.0989, + "step": 20 + }, + { + "epoch": 0.1792, + "grad_norm": 5.923538014759818, + "learning_rate": 1.3222192947339192e-05, + "loss": 4.4991, + "step": 21 + }, + { + "epoch": 0.18773333333333334, + "grad_norm": 5.941056962941364, + "learning_rate": 1.3424226808222062e-05, + "loss": 4.0836, + "step": 22 + }, + { + "epoch": 0.19626666666666667, + "grad_norm": 6.171026012117947, + "learning_rate": 1.3617278360175927e-05, + "loss": 3.6861, + "step": 23 + }, + { + "epoch": 0.2048, + "grad_norm": 7.130542138930838, + "learning_rate": 1.380211241711606e-05, + "loss": 4.0958, + "step": 24 + }, + { + "epoch": 0.21333333333333335, + "grad_norm": 7.328837606110418, + "learning_rate": 1.3979400086720374e-05, + "loss": 3.9524, + "step": 25 + }, + { + "epoch": 0.22186666666666666, + "grad_norm": 6.923489005711429, + "learning_rate": 1.4149733479708178e-05, + "loss": 3.6062, + "step": 26 + }, + { + "epoch": 0.2304, + "grad_norm": 6.409498926059221, + "learning_rate": 1.4313637641589872e-05, + "loss": 3.2034, + "step": 27 + }, + { + "epoch": 0.23893333333333333, + "grad_norm": 5.781628405584682, + "learning_rate": 1.4471580313422191e-05, + "loss": 2.8158, + "step": 28 + }, + { + "epoch": 0.24746666666666667, + "grad_norm": 6.2927590068243315, + "learning_rate": 1.4623979978989559e-05, + "loss": 2.9803, + "step": 29 + }, + { + "epoch": 0.256, + "grad_norm": 6.103844678630006, + "learning_rate": 1.4771212547196623e-05, + "loss": 2.847, + "step": 30 + }, + { + "epoch": 0.26453333333333334, + "grad_norm": 7.656341925867144, + "learning_rate": 1.4913616938342726e-05, + "loss": 3.0907, + "step": 31 + }, + { + "epoch": 0.2730666666666667, + "grad_norm": 6.324242877501844, + "learning_rate": 1.5051499783199059e-05, + "loss": 2.3467, + "step": 32 + }, + { + "epoch": 0.2816, + "grad_norm": 7.606313101162739, + "learning_rate": 1.5185139398778874e-05, + "loss": 2.5292, + "step": 33 + }, + { + "epoch": 0.29013333333333335, + "grad_norm": 8.553792493849265, + "learning_rate": 1.531478917042255e-05, + "loss": 2.4547, + "step": 34 + }, + { + "epoch": 0.2986666666666667, + "grad_norm": 8.483368703272543, + "learning_rate": 1.5440680443502753e-05, + "loss": 2.1956, + "step": 35 + }, + { + "epoch": 0.3072, + "grad_norm": 8.364739352838077, + "learning_rate": 1.5563025007672873e-05, + "loss": 1.8552, + "step": 36 + }, + { + "epoch": 0.3157333333333333, + "grad_norm": 9.37663682000104, + "learning_rate": 1.5682017240669948e-05, + "loss": 1.9228, + "step": 37 + }, + { + "epoch": 0.32426666666666665, + "grad_norm": 9.823047193440066, + "learning_rate": 1.57978359661681e-05, + "loss": 1.7033, + "step": 38 + }, + { + "epoch": 0.3328, + "grad_norm": 9.692618512955894, + "learning_rate": 1.591064607026499e-05, + "loss": 1.3768, + "step": 39 + }, + { + "epoch": 0.3413333333333333, + "grad_norm": 9.08889021911031, + "learning_rate": 1.6020599913279622e-05, + "loss": 1.3015, + "step": 40 + }, + { + "epoch": 0.34986666666666666, + "grad_norm": 8.081534221516058, + "learning_rate": 1.6127838567197353e-05, + "loss": 0.9228, + "step": 41 + }, + { + "epoch": 0.3584, + "grad_norm": 6.238638048950311, + "learning_rate": 1.6232492903979005e-05, + "loss": 0.7267, + "step": 42 + }, + { + "epoch": 0.36693333333333333, + "grad_norm": 3.4058036861773604, + "learning_rate": 1.6334684555795865e-05, + "loss": 0.5875, + "step": 43 + }, + { + "epoch": 0.37546666666666667, + "grad_norm": 2.079163829467713, + "learning_rate": 1.6434526764861872e-05, + "loss": 0.6355, + "step": 44 + }, + { + "epoch": 0.384, + "grad_norm": 1.5597487833024746, + "learning_rate": 1.6532125137753435e-05, + "loss": 0.5106, + "step": 45 + }, + { + "epoch": 0.39253333333333335, + "grad_norm": 2.491689602375256, + "learning_rate": 1.662757831681574e-05, + "loss": 0.6454, + "step": 46 + }, + { + "epoch": 0.4010666666666667, + "grad_norm": 2.010880438195854, + "learning_rate": 1.672097857935717e-05, + "loss": 0.4757, + "step": 47 + }, + { + "epoch": 0.4096, + "grad_norm": 1.9452805114322096, + "learning_rate": 1.681241237375587e-05, + "loss": 0.4133, + "step": 48 + }, + { + "epoch": 0.41813333333333336, + "grad_norm": 1.7620848552306103, + "learning_rate": 1.6901960800285137e-05, + "loss": 0.4004, + "step": 49 + }, + { + "epoch": 0.4266666666666667, + "grad_norm": 1.278224489774809, + "learning_rate": 1.6989700043360187e-05, + "loss": 0.3523, + "step": 50 + }, + { + "epoch": 0.4352, + "grad_norm": 1.6151354758303231, + "learning_rate": 1.7075701760979363e-05, + "loss": 0.4317, + "step": 51 + }, + { + "epoch": 0.4437333333333333, + "grad_norm": 1.3451396055695035, + "learning_rate": 1.716003343634799e-05, + "loss": 0.3474, + "step": 52 + }, + { + "epoch": 0.45226666666666665, + "grad_norm": 1.6814977782362666, + "learning_rate": 1.724275869600789e-05, + "loss": 0.3706, + "step": 53 + }, + { + "epoch": 0.4608, + "grad_norm": 1.1682442432688667, + "learning_rate": 1.7323937598229687e-05, + "loss": 0.3488, + "step": 54 + }, + { + "epoch": 0.4693333333333333, + "grad_norm": 0.8839814540462471, + "learning_rate": 1.7403626894942437e-05, + "loss": 0.293, + "step": 55 + }, + { + "epoch": 0.47786666666666666, + "grad_norm": 0.7974304806295485, + "learning_rate": 1.7481880270062003e-05, + "loss": 0.2717, + "step": 56 + }, + { + "epoch": 0.4864, + "grad_norm": 0.6232203657585239, + "learning_rate": 1.7558748556724913e-05, + "loss": 0.1741, + "step": 57 + }, + { + "epoch": 0.49493333333333334, + "grad_norm": 0.6850688604563008, + "learning_rate": 1.763427993562937e-05, + "loss": 0.228, + "step": 58 + }, + { + "epoch": 0.5034666666666666, + "grad_norm": 0.5923826384300431, + "learning_rate": 1.7708520116421443e-05, + "loss": 0.2131, + "step": 59 + }, + { + "epoch": 0.512, + "grad_norm": 0.489754430485032, + "learning_rate": 1.7781512503836432e-05, + "loss": 0.165, + "step": 60 + }, + { + "epoch": 0.5205333333333333, + "grad_norm": 0.5280940052395061, + "learning_rate": 1.7853298350107667e-05, + "loss": 0.1658, + "step": 61 + }, + { + "epoch": 0.5290666666666667, + "grad_norm": 0.4750905992036739, + "learning_rate": 1.7923916894982537e-05, + "loss": 0.1438, + "step": 62 + }, + { + "epoch": 0.5376, + "grad_norm": 0.4162998392722401, + "learning_rate": 1.7993405494535815e-05, + "loss": 0.1555, + "step": 63 + }, + { + "epoch": 0.5461333333333334, + "grad_norm": 0.26863266246370443, + "learning_rate": 1.806179973983887e-05, + "loss": 0.1323, + "step": 64 + }, + { + "epoch": 0.5546666666666666, + "grad_norm": 0.26534221125601215, + "learning_rate": 1.8129133566428553e-05, + "loss": 0.1671, + "step": 65 + }, + { + "epoch": 0.5632, + "grad_norm": 0.2548662962257576, + "learning_rate": 1.8195439355418686e-05, + "loss": 0.1308, + "step": 66 + }, + { + "epoch": 0.5717333333333333, + "grad_norm": 0.18045394638578796, + "learning_rate": 1.8260748027008263e-05, + "loss": 0.1262, + "step": 67 + }, + { + "epoch": 0.5802666666666667, + "grad_norm": 0.17070388073612064, + "learning_rate": 1.8325089127062364e-05, + "loss": 0.1192, + "step": 68 + }, + { + "epoch": 0.5888, + "grad_norm": 0.1531381679244776, + "learning_rate": 1.8388490907372553e-05, + "loss": 0.1274, + "step": 69 + }, + { + "epoch": 0.5973333333333334, + "grad_norm": 0.18196434993687946, + "learning_rate": 1.8450980400142568e-05, + "loss": 0.1375, + "step": 70 + }, + { + "epoch": 0.6058666666666667, + "grad_norm": 0.15324416972951205, + "learning_rate": 1.8512583487190752e-05, + "loss": 0.1599, + "step": 71 + }, + { + "epoch": 0.6144, + "grad_norm": 0.10884462064503801, + "learning_rate": 1.857332496431268e-05, + "loss": 0.1041, + "step": 72 + }, + { + "epoch": 0.6229333333333333, + "grad_norm": 0.12915133528192668, + "learning_rate": 1.8633228601204555e-05, + "loss": 0.1406, + "step": 73 + }, + { + "epoch": 0.6314666666666666, + "grad_norm": 0.12553425699952878, + "learning_rate": 1.8692317197309763e-05, + "loss": 0.1256, + "step": 74 + }, + { + "epoch": 0.64, + "grad_norm": 0.11976960918968543, + "learning_rate": 1.8750612633916997e-05, + "loss": 0.1144, + "step": 75 + }, + { + "epoch": 0.6485333333333333, + "grad_norm": 0.115805998298789, + "learning_rate": 1.8808135922807914e-05, + "loss": 0.1528, + "step": 76 + }, + { + "epoch": 0.6570666666666667, + "grad_norm": 0.10325948496697443, + "learning_rate": 1.8864907251724818e-05, + "loss": 0.1044, + "step": 77 + }, + { + "epoch": 0.6656, + "grad_norm": 0.09595064346541006, + "learning_rate": 1.8920946026904802e-05, + "loss": 0.1534, + "step": 78 + }, + { + "epoch": 0.6741333333333334, + "grad_norm": 0.08796742845240496, + "learning_rate": 1.8976270912904414e-05, + "loss": 0.1155, + "step": 79 + }, + { + "epoch": 0.6826666666666666, + "grad_norm": 0.08218991738379527, + "learning_rate": 1.9030899869919434e-05, + "loss": 0.1311, + "step": 80 + }, + { + "epoch": 0.6912, + "grad_norm": 0.08290815261109215, + "learning_rate": 1.9084850188786497e-05, + "loss": 0.11, + "step": 81 + }, + { + "epoch": 0.6997333333333333, + "grad_norm": 0.0794132180176064, + "learning_rate": 1.9138138523837165e-05, + "loss": 0.1135, + "step": 82 + }, + { + "epoch": 0.7082666666666667, + "grad_norm": 0.06934410705255296, + "learning_rate": 1.919078092376074e-05, + "loss": 0.109, + "step": 83 + }, + { + "epoch": 0.7168, + "grad_norm": 0.09000563031870593, + "learning_rate": 1.9242792860618813e-05, + "loss": 0.12, + "step": 84 + }, + { + "epoch": 0.7253333333333334, + "grad_norm": 0.1134042277879818, + "learning_rate": 1.929418925714293e-05, + "loss": 0.1223, + "step": 85 + }, + { + "epoch": 0.7338666666666667, + "grad_norm": 0.09118764690233076, + "learning_rate": 1.9344984512435673e-05, + "loss": 0.1459, + "step": 86 + }, + { + "epoch": 0.7424, + "grad_norm": 0.07873016754353963, + "learning_rate": 1.9395192526186183e-05, + "loss": 0.1422, + "step": 87 + }, + { + "epoch": 0.7509333333333333, + "grad_norm": 0.1796495874463076, + "learning_rate": 1.9444826721501687e-05, + "loss": 0.1291, + "step": 88 + }, + { + "epoch": 0.7594666666666666, + "grad_norm": 0.0679589944174269, + "learning_rate": 1.9493900066449125e-05, + "loss": 0.108, + "step": 89 + }, + { + "epoch": 0.768, + "grad_norm": 0.08174688574235538, + "learning_rate": 1.9542425094393246e-05, + "loss": 0.1081, + "step": 90 + }, + { + "epoch": 0.7765333333333333, + "grad_norm": 0.057137370501406756, + "learning_rate": 1.9590413923210934e-05, + "loss": 0.0934, + "step": 91 + }, + { + "epoch": 0.7850666666666667, + "grad_norm": 0.06578111924908255, + "learning_rate": 1.9637878273455555e-05, + "loss": 0.1085, + "step": 92 + }, + { + "epoch": 0.7936, + "grad_norm": 0.08945990540906254, + "learning_rate": 1.968482948553935e-05, + "loss": 0.1747, + "step": 93 + }, + { + "epoch": 0.8021333333333334, + "grad_norm": 0.06183863311044229, + "learning_rate": 1.9731278535996986e-05, + "loss": 0.1136, + "step": 94 + }, + { + "epoch": 0.8106666666666666, + "grad_norm": 0.05777899602544702, + "learning_rate": 1.9777236052888476e-05, + "loss": 0.0984, + "step": 95 + }, + { + "epoch": 0.8192, + "grad_norm": 0.08130851607693534, + "learning_rate": 1.9822712330395683e-05, + "loss": 0.187, + "step": 96 + }, + { + "epoch": 0.8277333333333333, + "grad_norm": 0.06426546202002927, + "learning_rate": 1.986771734266245e-05, + "loss": 0.1296, + "step": 97 + }, + { + "epoch": 0.8362666666666667, + "grad_norm": 0.069692313707994, + "learning_rate": 1.991226075692495e-05, + "loss": 0.1404, + "step": 98 + }, + { + "epoch": 0.8448, + "grad_norm": 0.05494542266886729, + "learning_rate": 1.9956351945975496e-05, + "loss": 0.116, + "step": 99 + }, + { + "epoch": 0.8533333333333334, + "grad_norm": 0.07571686966840627, + "learning_rate": 1.9999999999999998e-05, + "loss": 0.1539, + "step": 100 + }, + { + "epoch": 0.8618666666666667, + "grad_norm": 0.054351059117603705, + "learning_rate": 2e-05, + "loss": 0.1037, + "step": 101 + }, + { + "epoch": 0.8704, + "grad_norm": 0.06531899611551092, + "learning_rate": 2e-05, + "loss": 0.0827, + "step": 102 + }, + { + "epoch": 0.8789333333333333, + "grad_norm": 0.06131678646504652, + "learning_rate": 2e-05, + "loss": 0.1266, + "step": 103 + }, + { + "epoch": 0.8874666666666666, + "grad_norm": 0.06850220540661824, + "learning_rate": 2e-05, + "loss": 0.1456, + "step": 104 + }, + { + "epoch": 0.896, + "grad_norm": 0.05806908951252483, + "learning_rate": 2e-05, + "loss": 0.0954, + "step": 105 + }, + { + "epoch": 0.9045333333333333, + "grad_norm": 0.06503642452033717, + "learning_rate": 2e-05, + "loss": 0.1417, + "step": 106 + }, + { + "epoch": 0.9130666666666667, + "grad_norm": 0.050486271853277066, + "learning_rate": 2e-05, + "loss": 0.0959, + "step": 107 + }, + { + "epoch": 0.9216, + "grad_norm": 0.07746063813802379, + "learning_rate": 2e-05, + "loss": 0.1256, + "step": 108 + }, + { + "epoch": 0.9301333333333334, + "grad_norm": 0.051231172380840004, + "learning_rate": 2e-05, + "loss": 0.1116, + "step": 109 + }, + { + "epoch": 0.9386666666666666, + "grad_norm": 0.056296443557859455, + "learning_rate": 2e-05, + "loss": 0.1056, + "step": 110 + }, + { + "epoch": 0.9472, + "grad_norm": 0.05058663240713958, + "learning_rate": 2e-05, + "loss": 0.0971, + "step": 111 + }, + { + "epoch": 0.9557333333333333, + "grad_norm": 0.05532886570130611, + "learning_rate": 2e-05, + "loss": 0.1086, + "step": 112 + }, + { + "epoch": 0.9642666666666667, + "grad_norm": 0.05327811326654907, + "learning_rate": 2e-05, + "loss": 0.0989, + "step": 113 + }, + { + "epoch": 0.9728, + "grad_norm": 0.05663279364147864, + "learning_rate": 2e-05, + "loss": 0.0958, + "step": 114 + }, + { + "epoch": 0.9813333333333333, + "grad_norm": 0.04930904541225805, + "learning_rate": 2e-05, + "loss": 0.0887, + "step": 115 + }, + { + "epoch": 0.9898666666666667, + "grad_norm": 0.06096947951115022, + "learning_rate": 2e-05, + "loss": 0.106, + "step": 116 + }, + { + "epoch": 0.9984, + "grad_norm": 0.050092322361182495, + "learning_rate": 2e-05, + "loss": 0.0931, + "step": 117 + }, + { + "epoch": 1.0069333333333332, + "grad_norm": 0.04980408443758999, + "learning_rate": 2e-05, + "loss": 0.0955, + "step": 118 + }, + { + "epoch": 1.0154666666666667, + "grad_norm": 0.051183082721834305, + "learning_rate": 2e-05, + "loss": 0.1049, + "step": 119 + }, + { + "epoch": 1.024, + "grad_norm": 0.04332220265802814, + "learning_rate": 2e-05, + "loss": 0.0983, + "step": 120 + }, + { + "epoch": 1.0325333333333333, + "grad_norm": 0.07211731499677299, + "learning_rate": 2e-05, + "loss": 0.1386, + "step": 121 + }, + { + "epoch": 1.0410666666666666, + "grad_norm": 0.06550870223740553, + "learning_rate": 2e-05, + "loss": 0.1334, + "step": 122 + }, + { + "epoch": 1.0496, + "grad_norm": 0.05331839690767287, + "learning_rate": 2e-05, + "loss": 0.1014, + "step": 123 + }, + { + "epoch": 1.0581333333333334, + "grad_norm": 0.05227685628767905, + "learning_rate": 2e-05, + "loss": 0.1098, + "step": 124 + }, + { + "epoch": 1.0666666666666667, + "grad_norm": 0.07641693882491171, + "learning_rate": 2e-05, + "loss": 0.1127, + "step": 125 + }, + { + "epoch": 1.0752, + "grad_norm": 0.052835367770791786, + "learning_rate": 2e-05, + "loss": 0.1231, + "step": 126 + }, + { + "epoch": 1.0837333333333334, + "grad_norm": 0.07520329755025788, + "learning_rate": 2e-05, + "loss": 0.085, + "step": 127 + }, + { + "epoch": 1.0922666666666667, + "grad_norm": 0.07670066152157425, + "learning_rate": 2e-05, + "loss": 0.1071, + "step": 128 + }, + { + "epoch": 1.1008, + "grad_norm": 0.052832906560645154, + "learning_rate": 2e-05, + "loss": 0.1093, + "step": 129 + }, + { + "epoch": 1.1093333333333333, + "grad_norm": 0.06573889037311398, + "learning_rate": 2e-05, + "loss": 0.1193, + "step": 130 + }, + { + "epoch": 1.1178666666666666, + "grad_norm": 0.05175471296566334, + "learning_rate": 2e-05, + "loss": 0.1184, + "step": 131 + }, + { + "epoch": 1.1264, + "grad_norm": 0.05912231419793496, + "learning_rate": 2e-05, + "loss": 0.1154, + "step": 132 + }, + { + "epoch": 1.1349333333333333, + "grad_norm": 0.04899140475981105, + "learning_rate": 2e-05, + "loss": 0.0957, + "step": 133 + }, + { + "epoch": 1.1434666666666666, + "grad_norm": 0.05939916939142137, + "learning_rate": 2e-05, + "loss": 0.0979, + "step": 134 + }, + { + "epoch": 1.152, + "grad_norm": 0.0516819217599706, + "learning_rate": 2e-05, + "loss": 0.0834, + "step": 135 + }, + { + "epoch": 1.1605333333333334, + "grad_norm": 0.05456440346454737, + "learning_rate": 2e-05, + "loss": 0.1183, + "step": 136 + }, + { + "epoch": 1.1690666666666667, + "grad_norm": 0.059906464476343235, + "learning_rate": 2e-05, + "loss": 0.1048, + "step": 137 + }, + { + "epoch": 1.1776, + "grad_norm": 0.0720112680204319, + "learning_rate": 2e-05, + "loss": 0.1168, + "step": 138 + }, + { + "epoch": 1.1861333333333333, + "grad_norm": 0.04940202805828527, + "learning_rate": 2e-05, + "loss": 0.0948, + "step": 139 + }, + { + "epoch": 1.1946666666666665, + "grad_norm": 0.060088609545130046, + "learning_rate": 2e-05, + "loss": 0.0952, + "step": 140 + } + ], + "logging_steps": 1, + "max_steps": 351, + "num_input_tokens_seen": 0, + "num_train_epochs": 3, + "save_steps": 20, + "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.9872207486907843e+18, + "train_batch_size": 16, + "trial_name": null, + "trial_params": null +} diff --git a/checkpoint-140/training_args.bin b/checkpoint-140/training_args.bin new file mode 100644 index 0000000000000000000000000000000000000000..8ac842d29fc6ad3e132cb7208dda5b61dd1079ee --- /dev/null +++ b/checkpoint-140/training_args.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:aa4edad1da5557fcd52a6da980443588016cead6f0444a3562cfa68029c66a04 +size 6840 diff --git a/checkpoint-140/zero_to_fp32.py b/checkpoint-140/zero_to_fp32.py new file mode 100644 index 0000000000000000000000000000000000000000..49b846633d6eb1e836e34681e44033581f4edb7b --- /dev/null +++ b/checkpoint-140/zero_to_fp32.py @@ -0,0 +1,592 @@ +#!/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 . pytorch_model.bin + +import argparse +import torch +import glob +import math +import os +import re +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) + + +@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 parse_model_states(files): + zero_model_states = [] + for file in files: + state_dict = torch.load(file, map_location=device) + + 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 files: + state_dict = torch.load(f, map_location=device) + # 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 not ZERO_STAGE 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}") + + if zero_stage <= 2: + fp32_flat_groups = [state_dicts[i][OPTIMIZER_STATE_DICT][fp32_groups_key] for i in range(len(state_dicts))] + elif zero_stage == 3: + # if there is more than one param group, there will be multiple flattened tensors - one + # flattened tensor per group - for simplicity merge them into a single tensor + # + # XXX: could make the script more memory efficient for when there are multiple groups - it + # will require matching the sub-lists of param_shapes for each param group flattened tensor + + fp32_flat_groups = [ + torch.cat(state_dicts[i][OPTIMIZER_STATE_DICT][fp32_groups_key], 0) 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): + """ + 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}'") + + 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}") + + 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}') + + if zero_stage <= 2: + return _get_fp32_state_dict_from_zero2_checkpoint(world_size, fp32_flat_groups, zero_model_states) + elif zero_stage == 3: + return _get_fp32_state_dict_from_zero3_checkpoint(world_size, fp32_flat_groups, zero_model_states) + + +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): + state_dict = OrderedDict() + + # buffers + buffers = zero_model_states[0].buffers + state_dict.update(buffers) + if debug: + print(f"added {len(buffers)} buffers") + + _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") + + +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 = fp32_flat_groups[0].numel() * 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 + for name, shape in param_shapes.items(): + + 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}" + ) + + # XXX: memory usage doubles here + state_dict[name] = torch.cat( + tuple(fp32_flat_groups[i].narrow(0, offset, partitioned_numel) for i in range(world_size)), + 0).narrow(0, 0, unpartitioned_numel).view(shape) + 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): + state_dict = OrderedDict() + + # buffers + buffers = zero_model_states[0].buffers + state_dict.update(buffers) + if debug: + print(f"added {len(buffers)} buffers") + + _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 get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir, tag=None): + """ + 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`` + + Returns: + - pytorch ``state_dict`` + + Note: this approach may not work if your application doesn't have sufficient free CPU memory and + you may need to use the offline approach using the ``zero_to_fp32.py`` script that is saved with + the checkpoint. + + 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. + + """ + 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") + + return _get_fp32_state_dict_from_zero_checkpoint(ds_checkpoint_dir) + + +def convert_zero_checkpoint_to_fp32_state_dict(checkpoint_dir, output_file, tag=None): + """ + 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_file``: path to the pytorch fp32 state_dict output file (e.g. path/pytorch_model.bin) + - ``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`` + """ + + state_dict = get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir, tag) + print(f"Saving fp32 state dict to {output_file}") + torch.save(state_dict, output_file) + + +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(f"Extracting fp32 weights") + state_dict = get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir, tag) + + logger.info(f"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_file", + type=str, + help="path to the pytorch fp32 state_dict output file (e.g. path/checkpoint-12/pytorch_model.bin)") + 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("-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_file, tag=args.tag) diff --git a/checkpoint-160/README.md b/checkpoint-160/README.md new file mode 100644 index 0000000000000000000000000000000000000000..e7d4f706aeefc6bb2aa84e963870f345a14c4af9 --- /dev/null +++ b/checkpoint-160/README.md @@ -0,0 +1,202 @@ +--- +library_name: peft +base_model: ../ckpts/Meta-Llama-3-8B-Instruct +--- + +# 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.11.1 \ No newline at end of file diff --git a/checkpoint-160/adapter_config.json b/checkpoint-160/adapter_config.json new file mode 100644 index 0000000000000000000000000000000000000000..ad16c073ed8946d227350e8fe4e99d689a8ede54 --- /dev/null +++ b/checkpoint-160/adapter_config.json @@ -0,0 +1,35 @@ +{ + "alpha_pattern": {}, + "auto_mapping": null, + "base_model_name_or_path": "../ckpts/Meta-Llama-3-8B-Instruct", + "bias": "none", + "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": 32, + "lora_dropout": 0.1, + "megatron_config": null, + "megatron_core": "megatron.core", + "modules_to_save": null, + "peft_type": "LORA", + "r": 16, + "rank_pattern": {}, + "revision": null, + "target_modules": [ + "down_proj", + "gate_proj", + "q_proj", + "lm_head", + "o_proj", + "v_proj", + "up_proj", + "k_proj" + ], + "task_type": "CAUSAL_LM", + "use_dora": false, + "use_rslora": false +} \ No newline at end of file diff --git a/checkpoint-160/adapter_model.safetensors b/checkpoint-160/adapter_model.safetensors new file mode 100644 index 0000000000000000000000000000000000000000..813aaf9317a1f1800e56036b6f520e6aa25eafda --- /dev/null +++ b/checkpoint-160/adapter_model.safetensors @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6b6b5a540a8357ce98d65b484037f08c6e0295863490398dfd6671ec06a2916b +size 1138856856 diff --git a/checkpoint-160/global_step160/bf16_zero_pp_rank_0_mp_rank_00_optim_states.pt b/checkpoint-160/global_step160/bf16_zero_pp_rank_0_mp_rank_00_optim_states.pt new file mode 100644 index 0000000000000000000000000000000000000000..6617b79eaaaa719a52a57a9e3d16913739827008 --- /dev/null +++ b/checkpoint-160/global_step160/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:f1a136bd5515088baf044edf425835b86e73f43dc41097181483574d0a3ec311 +size 528781328 diff --git a/checkpoint-160/global_step160/mp_rank_00_model_states.pt b/checkpoint-160/global_step160/mp_rank_00_model_states.pt new file mode 100644 index 0000000000000000000000000000000000000000..f5d86ace886f802632302817ee6f555ea016c2f8 --- /dev/null +++ b/checkpoint-160/global_step160/mp_rank_00_model_states.pt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e64b47cf0673bd0721e3b682a0e4fd592936923b3a1fc6966a1236c9b9f1a4ec +size 199905337 diff --git a/checkpoint-160/latest b/checkpoint-160/latest new file mode 100644 index 0000000000000000000000000000000000000000..3df30ded267d950ff3ca04cffb9660be12079ca6 --- /dev/null +++ b/checkpoint-160/latest @@ -0,0 +1 @@ +global_step160 \ No newline at end of file diff --git a/checkpoint-160/rng_state.pth b/checkpoint-160/rng_state.pth new file mode 100644 index 0000000000000000000000000000000000000000..809cc01625a9fe2af3abe387e6eeb078e560a412 --- /dev/null +++ b/checkpoint-160/rng_state.pth @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cefbcec9b3679fcdb9b96cdb9ed85fb37b575748c126094c451cc80787e18e73 +size 14244 diff --git a/checkpoint-160/trainer_state.json b/checkpoint-160/trainer_state.json new file mode 100644 index 0000000000000000000000000000000000000000..8bbf024f29df623a4b6c5971930774e7d6804c77 --- /dev/null +++ b/checkpoint-160/trainer_state.json @@ -0,0 +1,1153 @@ +{ + "best_metric": null, + "best_model_checkpoint": null, + "epoch": 1.3653333333333333, + "eval_steps": 500, + "global_step": 160, + "is_hyper_param_search": false, + "is_local_process_zero": true, + "is_world_process_zero": true, + "log_history": [ + { + "epoch": 0.008533333333333334, + "grad_norm": 100.21848203113535, + "learning_rate": 0.0, + "loss": 7.1962, + "step": 1 + }, + { + "epoch": 0.017066666666666667, + "grad_norm": 96.43006188910957, + "learning_rate": 3.0102999566398115e-06, + "loss": 6.9414, + "step": 2 + }, + { + "epoch": 0.0256, + "grad_norm": 97.35803466618715, + "learning_rate": 4.771212547196624e-06, + "loss": 7.0102, + "step": 3 + }, + { + "epoch": 0.034133333333333335, + "grad_norm": 95.14837816372646, + "learning_rate": 6.020599913279623e-06, + "loss": 6.5295, + "step": 4 + }, + { + "epoch": 0.042666666666666665, + "grad_norm": 91.76544275692784, + "learning_rate": 6.989700043360187e-06, + "loss": 6.4806, + "step": 5 + }, + { + "epoch": 0.0512, + "grad_norm": 84.4494318688335, + "learning_rate": 7.781512503836437e-06, + "loss": 6.4194, + "step": 6 + }, + { + "epoch": 0.05973333333333333, + "grad_norm": 71.37977490595638, + "learning_rate": 8.450980400142568e-06, + "loss": 5.4953, + "step": 7 + }, + { + "epoch": 0.06826666666666667, + "grad_norm": 49.31153456754566, + "learning_rate": 9.030899869919434e-06, + "loss": 5.4123, + "step": 8 + }, + { + "epoch": 0.0768, + "grad_norm": 20.37296364560341, + "learning_rate": 9.542425094393249e-06, + "loss": 5.2334, + "step": 9 + }, + { + "epoch": 0.08533333333333333, + "grad_norm": 7.968467079076881, + "learning_rate": 9.999999999999999e-06, + "loss": 5.0282, + "step": 10 + }, + { + "epoch": 0.09386666666666667, + "grad_norm": 3.559446532055649, + "learning_rate": 1.041392685158225e-05, + "loss": 4.612, + "step": 11 + }, + { + "epoch": 0.1024, + "grad_norm": 3.5528846947995674, + "learning_rate": 1.0791812460476248e-05, + "loss": 4.9475, + "step": 12 + }, + { + "epoch": 0.11093333333333333, + "grad_norm": 3.541968897471334, + "learning_rate": 1.1139433523068365e-05, + "loss": 4.2777, + "step": 13 + }, + { + "epoch": 0.11946666666666667, + "grad_norm": 3.54718070036198, + "learning_rate": 1.1461280356782378e-05, + "loss": 4.3507, + "step": 14 + }, + { + "epoch": 0.128, + "grad_norm": 3.8632334830606747, + "learning_rate": 1.1760912590556813e-05, + "loss": 4.5364, + "step": 15 + }, + { + "epoch": 0.13653333333333334, + "grad_norm": 3.6637424744054004, + "learning_rate": 1.2041199826559246e-05, + "loss": 3.9672, + "step": 16 + }, + { + "epoch": 0.14506666666666668, + "grad_norm": 3.919802904818311, + "learning_rate": 1.230448921378274e-05, + "loss": 4.0618, + "step": 17 + }, + { + "epoch": 0.1536, + "grad_norm": 4.71904950738746, + "learning_rate": 1.2552725051033058e-05, + "loss": 4.6656, + "step": 18 + }, + { + "epoch": 0.16213333333333332, + "grad_norm": 4.6656317698690835, + "learning_rate": 1.2787536009528288e-05, + "loss": 4.1131, + "step": 19 + }, + { + "epoch": 0.17066666666666666, + "grad_norm": 5.145138692367417, + "learning_rate": 1.301029995663981e-05, + "loss": 4.0989, + "step": 20 + }, + { + "epoch": 0.1792, + "grad_norm": 5.923538014759818, + "learning_rate": 1.3222192947339192e-05, + "loss": 4.4991, + "step": 21 + }, + { + "epoch": 0.18773333333333334, + "grad_norm": 5.941056962941364, + "learning_rate": 1.3424226808222062e-05, + "loss": 4.0836, + "step": 22 + }, + { + "epoch": 0.19626666666666667, + "grad_norm": 6.171026012117947, + "learning_rate": 1.3617278360175927e-05, + "loss": 3.6861, + "step": 23 + }, + { + "epoch": 0.2048, + "grad_norm": 7.130542138930838, + "learning_rate": 1.380211241711606e-05, + "loss": 4.0958, + "step": 24 + }, + { + "epoch": 0.21333333333333335, + "grad_norm": 7.328837606110418, + "learning_rate": 1.3979400086720374e-05, + "loss": 3.9524, + "step": 25 + }, + { + "epoch": 0.22186666666666666, + "grad_norm": 6.923489005711429, + "learning_rate": 1.4149733479708178e-05, + "loss": 3.6062, + "step": 26 + }, + { + "epoch": 0.2304, + "grad_norm": 6.409498926059221, + "learning_rate": 1.4313637641589872e-05, + "loss": 3.2034, + "step": 27 + }, + { + "epoch": 0.23893333333333333, + "grad_norm": 5.781628405584682, + "learning_rate": 1.4471580313422191e-05, + "loss": 2.8158, + "step": 28 + }, + { + "epoch": 0.24746666666666667, + "grad_norm": 6.2927590068243315, + "learning_rate": 1.4623979978989559e-05, + "loss": 2.9803, + "step": 29 + }, + { + "epoch": 0.256, + "grad_norm": 6.103844678630006, + "learning_rate": 1.4771212547196623e-05, + "loss": 2.847, + "step": 30 + }, + { + "epoch": 0.26453333333333334, + "grad_norm": 7.656341925867144, + "learning_rate": 1.4913616938342726e-05, + "loss": 3.0907, + "step": 31 + }, + { + "epoch": 0.2730666666666667, + "grad_norm": 6.324242877501844, + "learning_rate": 1.5051499783199059e-05, + "loss": 2.3467, + "step": 32 + }, + { + "epoch": 0.2816, + "grad_norm": 7.606313101162739, + "learning_rate": 1.5185139398778874e-05, + "loss": 2.5292, + "step": 33 + }, + { + "epoch": 0.29013333333333335, + "grad_norm": 8.553792493849265, + "learning_rate": 1.531478917042255e-05, + "loss": 2.4547, + "step": 34 + }, + { + "epoch": 0.2986666666666667, + "grad_norm": 8.483368703272543, + "learning_rate": 1.5440680443502753e-05, + "loss": 2.1956, + "step": 35 + }, + { + "epoch": 0.3072, + "grad_norm": 8.364739352838077, + "learning_rate": 1.5563025007672873e-05, + "loss": 1.8552, + "step": 36 + }, + { + "epoch": 0.3157333333333333, + "grad_norm": 9.37663682000104, + "learning_rate": 1.5682017240669948e-05, + "loss": 1.9228, + "step": 37 + }, + { + "epoch": 0.32426666666666665, + "grad_norm": 9.823047193440066, + "learning_rate": 1.57978359661681e-05, + "loss": 1.7033, + "step": 38 + }, + { + "epoch": 0.3328, + "grad_norm": 9.692618512955894, + "learning_rate": 1.591064607026499e-05, + "loss": 1.3768, + "step": 39 + }, + { + "epoch": 0.3413333333333333, + "grad_norm": 9.08889021911031, + "learning_rate": 1.6020599913279622e-05, + "loss": 1.3015, + "step": 40 + }, + { + "epoch": 0.34986666666666666, + "grad_norm": 8.081534221516058, + "learning_rate": 1.6127838567197353e-05, + "loss": 0.9228, + "step": 41 + }, + { + "epoch": 0.3584, + "grad_norm": 6.238638048950311, + "learning_rate": 1.6232492903979005e-05, + "loss": 0.7267, + "step": 42 + }, + { + "epoch": 0.36693333333333333, + "grad_norm": 3.4058036861773604, + "learning_rate": 1.6334684555795865e-05, + "loss": 0.5875, + "step": 43 + }, + { + "epoch": 0.37546666666666667, + "grad_norm": 2.079163829467713, + "learning_rate": 1.6434526764861872e-05, + "loss": 0.6355, + "step": 44 + }, + { + "epoch": 0.384, + "grad_norm": 1.5597487833024746, + "learning_rate": 1.6532125137753435e-05, + "loss": 0.5106, + "step": 45 + }, + { + "epoch": 0.39253333333333335, + "grad_norm": 2.491689602375256, + "learning_rate": 1.662757831681574e-05, + "loss": 0.6454, + "step": 46 + }, + { + "epoch": 0.4010666666666667, + "grad_norm": 2.010880438195854, + "learning_rate": 1.672097857935717e-05, + "loss": 0.4757, + "step": 47 + }, + { + "epoch": 0.4096, + "grad_norm": 1.9452805114322096, + "learning_rate": 1.681241237375587e-05, + "loss": 0.4133, + "step": 48 + }, + { + "epoch": 0.41813333333333336, + "grad_norm": 1.7620848552306103, + "learning_rate": 1.6901960800285137e-05, + "loss": 0.4004, + "step": 49 + }, + { + "epoch": 0.4266666666666667, + "grad_norm": 1.278224489774809, + "learning_rate": 1.6989700043360187e-05, + "loss": 0.3523, + "step": 50 + }, + { + "epoch": 0.4352, + "grad_norm": 1.6151354758303231, + "learning_rate": 1.7075701760979363e-05, + "loss": 0.4317, + "step": 51 + }, + { + "epoch": 0.4437333333333333, + "grad_norm": 1.3451396055695035, + "learning_rate": 1.716003343634799e-05, + "loss": 0.3474, + "step": 52 + }, + { + "epoch": 0.45226666666666665, + "grad_norm": 1.6814977782362666, + "learning_rate": 1.724275869600789e-05, + "loss": 0.3706, + "step": 53 + }, + { + "epoch": 0.4608, + "grad_norm": 1.1682442432688667, + "learning_rate": 1.7323937598229687e-05, + "loss": 0.3488, + "step": 54 + }, + { + "epoch": 0.4693333333333333, + "grad_norm": 0.8839814540462471, + "learning_rate": 1.7403626894942437e-05, + "loss": 0.293, + "step": 55 + }, + { + "epoch": 0.47786666666666666, + "grad_norm": 0.7974304806295485, + "learning_rate": 1.7481880270062003e-05, + "loss": 0.2717, + "step": 56 + }, + { + "epoch": 0.4864, + "grad_norm": 0.6232203657585239, + "learning_rate": 1.7558748556724913e-05, + "loss": 0.1741, + "step": 57 + }, + { + "epoch": 0.49493333333333334, + "grad_norm": 0.6850688604563008, + "learning_rate": 1.763427993562937e-05, + "loss": 0.228, + "step": 58 + }, + { + "epoch": 0.5034666666666666, + "grad_norm": 0.5923826384300431, + "learning_rate": 1.7708520116421443e-05, + "loss": 0.2131, + "step": 59 + }, + { + "epoch": 0.512, + "grad_norm": 0.489754430485032, + "learning_rate": 1.7781512503836432e-05, + "loss": 0.165, + "step": 60 + }, + { + "epoch": 0.5205333333333333, + "grad_norm": 0.5280940052395061, + "learning_rate": 1.7853298350107667e-05, + "loss": 0.1658, + "step": 61 + }, + { + "epoch": 0.5290666666666667, + "grad_norm": 0.4750905992036739, + "learning_rate": 1.7923916894982537e-05, + "loss": 0.1438, + "step": 62 + }, + { + "epoch": 0.5376, + "grad_norm": 0.4162998392722401, + "learning_rate": 1.7993405494535815e-05, + "loss": 0.1555, + "step": 63 + }, + { + "epoch": 0.5461333333333334, + "grad_norm": 0.26863266246370443, + "learning_rate": 1.806179973983887e-05, + "loss": 0.1323, + "step": 64 + }, + { + "epoch": 0.5546666666666666, + "grad_norm": 0.26534221125601215, + "learning_rate": 1.8129133566428553e-05, + "loss": 0.1671, + "step": 65 + }, + { + "epoch": 0.5632, + "grad_norm": 0.2548662962257576, + "learning_rate": 1.8195439355418686e-05, + "loss": 0.1308, + "step": 66 + }, + { + "epoch": 0.5717333333333333, + "grad_norm": 0.18045394638578796, + "learning_rate": 1.8260748027008263e-05, + "loss": 0.1262, + "step": 67 + }, + { + "epoch": 0.5802666666666667, + "grad_norm": 0.17070388073612064, + "learning_rate": 1.8325089127062364e-05, + "loss": 0.1192, + "step": 68 + }, + { + "epoch": 0.5888, + "grad_norm": 0.1531381679244776, + "learning_rate": 1.8388490907372553e-05, + "loss": 0.1274, + "step": 69 + }, + { + "epoch": 0.5973333333333334, + "grad_norm": 0.18196434993687946, + "learning_rate": 1.8450980400142568e-05, + "loss": 0.1375, + "step": 70 + }, + { + "epoch": 0.6058666666666667, + "grad_norm": 0.15324416972951205, + "learning_rate": 1.8512583487190752e-05, + "loss": 0.1599, + "step": 71 + }, + { + "epoch": 0.6144, + "grad_norm": 0.10884462064503801, + "learning_rate": 1.857332496431268e-05, + "loss": 0.1041, + "step": 72 + }, + { + "epoch": 0.6229333333333333, + "grad_norm": 0.12915133528192668, + "learning_rate": 1.8633228601204555e-05, + "loss": 0.1406, + "step": 73 + }, + { + "epoch": 0.6314666666666666, + "grad_norm": 0.12553425699952878, + "learning_rate": 1.8692317197309763e-05, + "loss": 0.1256, + "step": 74 + }, + { + "epoch": 0.64, + "grad_norm": 0.11976960918968543, + "learning_rate": 1.8750612633916997e-05, + "loss": 0.1144, + "step": 75 + }, + { + "epoch": 0.6485333333333333, + "grad_norm": 0.115805998298789, + "learning_rate": 1.8808135922807914e-05, + "loss": 0.1528, + "step": 76 + }, + { + "epoch": 0.6570666666666667, + "grad_norm": 0.10325948496697443, + "learning_rate": 1.8864907251724818e-05, + "loss": 0.1044, + "step": 77 + }, + { + "epoch": 0.6656, + "grad_norm": 0.09595064346541006, + "learning_rate": 1.8920946026904802e-05, + "loss": 0.1534, + "step": 78 + }, + { + "epoch": 0.6741333333333334, + "grad_norm": 0.08796742845240496, + "learning_rate": 1.8976270912904414e-05, + "loss": 0.1155, + "step": 79 + }, + { + "epoch": 0.6826666666666666, + "grad_norm": 0.08218991738379527, + "learning_rate": 1.9030899869919434e-05, + "loss": 0.1311, + "step": 80 + }, + { + "epoch": 0.6912, + "grad_norm": 0.08290815261109215, + "learning_rate": 1.9084850188786497e-05, + "loss": 0.11, + "step": 81 + }, + { + "epoch": 0.6997333333333333, + "grad_norm": 0.0794132180176064, + "learning_rate": 1.9138138523837165e-05, + "loss": 0.1135, + "step": 82 + }, + { + "epoch": 0.7082666666666667, + "grad_norm": 0.06934410705255296, + "learning_rate": 1.919078092376074e-05, + "loss": 0.109, + "step": 83 + }, + { + "epoch": 0.7168, + "grad_norm": 0.09000563031870593, + "learning_rate": 1.9242792860618813e-05, + "loss": 0.12, + "step": 84 + }, + { + "epoch": 0.7253333333333334, + "grad_norm": 0.1134042277879818, + "learning_rate": 1.929418925714293e-05, + "loss": 0.1223, + "step": 85 + }, + { + "epoch": 0.7338666666666667, + "grad_norm": 0.09118764690233076, + "learning_rate": 1.9344984512435673e-05, + "loss": 0.1459, + "step": 86 + }, + { + "epoch": 0.7424, + "grad_norm": 0.07873016754353963, + "learning_rate": 1.9395192526186183e-05, + "loss": 0.1422, + "step": 87 + }, + { + "epoch": 0.7509333333333333, + "grad_norm": 0.1796495874463076, + "learning_rate": 1.9444826721501687e-05, + "loss": 0.1291, + "step": 88 + }, + { + "epoch": 0.7594666666666666, + "grad_norm": 0.0679589944174269, + "learning_rate": 1.9493900066449125e-05, + "loss": 0.108, + "step": 89 + }, + { + "epoch": 0.768, + "grad_norm": 0.08174688574235538, + "learning_rate": 1.9542425094393246e-05, + "loss": 0.1081, + "step": 90 + }, + { + "epoch": 0.7765333333333333, + "grad_norm": 0.057137370501406756, + "learning_rate": 1.9590413923210934e-05, + "loss": 0.0934, + "step": 91 + }, + { + "epoch": 0.7850666666666667, + "grad_norm": 0.06578111924908255, + "learning_rate": 1.9637878273455555e-05, + "loss": 0.1085, + "step": 92 + }, + { + "epoch": 0.7936, + "grad_norm": 0.08945990540906254, + "learning_rate": 1.968482948553935e-05, + "loss": 0.1747, + "step": 93 + }, + { + "epoch": 0.8021333333333334, + "grad_norm": 0.06183863311044229, + "learning_rate": 1.9731278535996986e-05, + "loss": 0.1136, + "step": 94 + }, + { + "epoch": 0.8106666666666666, + "grad_norm": 0.05777899602544702, + "learning_rate": 1.9777236052888476e-05, + "loss": 0.0984, + "step": 95 + }, + { + "epoch": 0.8192, + "grad_norm": 0.08130851607693534, + "learning_rate": 1.9822712330395683e-05, + "loss": 0.187, + "step": 96 + }, + { + "epoch": 0.8277333333333333, + "grad_norm": 0.06426546202002927, + "learning_rate": 1.986771734266245e-05, + "loss": 0.1296, + "step": 97 + }, + { + "epoch": 0.8362666666666667, + "grad_norm": 0.069692313707994, + "learning_rate": 1.991226075692495e-05, + "loss": 0.1404, + "step": 98 + }, + { + "epoch": 0.8448, + "grad_norm": 0.05494542266886729, + "learning_rate": 1.9956351945975496e-05, + "loss": 0.116, + "step": 99 + }, + { + "epoch": 0.8533333333333334, + "grad_norm": 0.07571686966840627, + "learning_rate": 1.9999999999999998e-05, + "loss": 0.1539, + "step": 100 + }, + { + "epoch": 0.8618666666666667, + "grad_norm": 0.054351059117603705, + "learning_rate": 2e-05, + "loss": 0.1037, + "step": 101 + }, + { + "epoch": 0.8704, + "grad_norm": 0.06531899611551092, + "learning_rate": 2e-05, + "loss": 0.0827, + "step": 102 + }, + { + "epoch": 0.8789333333333333, + "grad_norm": 0.06131678646504652, + "learning_rate": 2e-05, + "loss": 0.1266, + "step": 103 + }, + { + "epoch": 0.8874666666666666, + "grad_norm": 0.06850220540661824, + "learning_rate": 2e-05, + "loss": 0.1456, + "step": 104 + }, + { + "epoch": 0.896, + "grad_norm": 0.05806908951252483, + "learning_rate": 2e-05, + "loss": 0.0954, + "step": 105 + }, + { + "epoch": 0.9045333333333333, + "grad_norm": 0.06503642452033717, + "learning_rate": 2e-05, + "loss": 0.1417, + "step": 106 + }, + { + "epoch": 0.9130666666666667, + "grad_norm": 0.050486271853277066, + "learning_rate": 2e-05, + "loss": 0.0959, + "step": 107 + }, + { + "epoch": 0.9216, + "grad_norm": 0.07746063813802379, + "learning_rate": 2e-05, + "loss": 0.1256, + "step": 108 + }, + { + "epoch": 0.9301333333333334, + "grad_norm": 0.051231172380840004, + "learning_rate": 2e-05, + "loss": 0.1116, + "step": 109 + }, + { + "epoch": 0.9386666666666666, + "grad_norm": 0.056296443557859455, + "learning_rate": 2e-05, + "loss": 0.1056, + "step": 110 + }, + { + "epoch": 0.9472, + "grad_norm": 0.05058663240713958, + "learning_rate": 2e-05, + "loss": 0.0971, + "step": 111 + }, + { + "epoch": 0.9557333333333333, + "grad_norm": 0.05532886570130611, + "learning_rate": 2e-05, + "loss": 0.1086, + "step": 112 + }, + { + "epoch": 0.9642666666666667, + "grad_norm": 0.05327811326654907, + "learning_rate": 2e-05, + "loss": 0.0989, + "step": 113 + }, + { + "epoch": 0.9728, + "grad_norm": 0.05663279364147864, + "learning_rate": 2e-05, + "loss": 0.0958, + "step": 114 + }, + { + "epoch": 0.9813333333333333, + "grad_norm": 0.04930904541225805, + "learning_rate": 2e-05, + "loss": 0.0887, + "step": 115 + }, + { + "epoch": 0.9898666666666667, + "grad_norm": 0.06096947951115022, + "learning_rate": 2e-05, + "loss": 0.106, + "step": 116 + }, + { + "epoch": 0.9984, + "grad_norm": 0.050092322361182495, + "learning_rate": 2e-05, + "loss": 0.0931, + "step": 117 + }, + { + "epoch": 1.0069333333333332, + "grad_norm": 0.04980408443758999, + "learning_rate": 2e-05, + "loss": 0.0955, + "step": 118 + }, + { + "epoch": 1.0154666666666667, + "grad_norm": 0.051183082721834305, + "learning_rate": 2e-05, + "loss": 0.1049, + "step": 119 + }, + { + "epoch": 1.024, + "grad_norm": 0.04332220265802814, + "learning_rate": 2e-05, + "loss": 0.0983, + "step": 120 + }, + { + "epoch": 1.0325333333333333, + "grad_norm": 0.07211731499677299, + "learning_rate": 2e-05, + "loss": 0.1386, + "step": 121 + }, + { + "epoch": 1.0410666666666666, + "grad_norm": 0.06550870223740553, + "learning_rate": 2e-05, + "loss": 0.1334, + "step": 122 + }, + { + "epoch": 1.0496, + "grad_norm": 0.05331839690767287, + "learning_rate": 2e-05, + "loss": 0.1014, + "step": 123 + }, + { + "epoch": 1.0581333333333334, + "grad_norm": 0.05227685628767905, + "learning_rate": 2e-05, + "loss": 0.1098, + "step": 124 + }, + { + "epoch": 1.0666666666666667, + "grad_norm": 0.07641693882491171, + "learning_rate": 2e-05, + "loss": 0.1127, + "step": 125 + }, + { + "epoch": 1.0752, + "grad_norm": 0.052835367770791786, + "learning_rate": 2e-05, + "loss": 0.1231, + "step": 126 + }, + { + "epoch": 1.0837333333333334, + "grad_norm": 0.07520329755025788, + "learning_rate": 2e-05, + "loss": 0.085, + "step": 127 + }, + { + "epoch": 1.0922666666666667, + "grad_norm": 0.07670066152157425, + "learning_rate": 2e-05, + "loss": 0.1071, + "step": 128 + }, + { + "epoch": 1.1008, + "grad_norm": 0.052832906560645154, + "learning_rate": 2e-05, + "loss": 0.1093, + "step": 129 + }, + { + "epoch": 1.1093333333333333, + "grad_norm": 0.06573889037311398, + "learning_rate": 2e-05, + "loss": 0.1193, + "step": 130 + }, + { + "epoch": 1.1178666666666666, + "grad_norm": 0.05175471296566334, + "learning_rate": 2e-05, + "loss": 0.1184, + "step": 131 + }, + { + "epoch": 1.1264, + "grad_norm": 0.05912231419793496, + "learning_rate": 2e-05, + "loss": 0.1154, + "step": 132 + }, + { + "epoch": 1.1349333333333333, + "grad_norm": 0.04899140475981105, + "learning_rate": 2e-05, + "loss": 0.0957, + "step": 133 + }, + { + "epoch": 1.1434666666666666, + "grad_norm": 0.05939916939142137, + "learning_rate": 2e-05, + "loss": 0.0979, + "step": 134 + }, + { + "epoch": 1.152, + "grad_norm": 0.0516819217599706, + "learning_rate": 2e-05, + "loss": 0.0834, + "step": 135 + }, + { + "epoch": 1.1605333333333334, + "grad_norm": 0.05456440346454737, + "learning_rate": 2e-05, + "loss": 0.1183, + "step": 136 + }, + { + "epoch": 1.1690666666666667, + "grad_norm": 0.059906464476343235, + "learning_rate": 2e-05, + "loss": 0.1048, + "step": 137 + }, + { + "epoch": 1.1776, + "grad_norm": 0.0720112680204319, + "learning_rate": 2e-05, + "loss": 0.1168, + "step": 138 + }, + { + "epoch": 1.1861333333333333, + "grad_norm": 0.04940202805828527, + "learning_rate": 2e-05, + "loss": 0.0948, + "step": 139 + }, + { + "epoch": 1.1946666666666665, + "grad_norm": 0.060088609545130046, + "learning_rate": 2e-05, + "loss": 0.0952, + "step": 140 + }, + { + "epoch": 1.2032, + "grad_norm": 0.04694761423612446, + "learning_rate": 2e-05, + "loss": 0.0717, + "step": 141 + }, + { + "epoch": 1.2117333333333333, + "grad_norm": 0.05628581562512457, + "learning_rate": 2e-05, + "loss": 0.1062, + "step": 142 + }, + { + "epoch": 1.2202666666666666, + "grad_norm": 0.06876420990437652, + "learning_rate": 2e-05, + "loss": 0.1218, + "step": 143 + }, + { + "epoch": 1.2288000000000001, + "grad_norm": 0.058774700501610655, + "learning_rate": 2e-05, + "loss": 0.1125, + "step": 144 + }, + { + "epoch": 1.2373333333333334, + "grad_norm": 0.061855922064341186, + "learning_rate": 2e-05, + "loss": 0.1295, + "step": 145 + }, + { + "epoch": 1.2458666666666667, + "grad_norm": 0.0813047704730138, + "learning_rate": 2e-05, + "loss": 0.1165, + "step": 146 + }, + { + "epoch": 1.2544, + "grad_norm": 0.061374000305305446, + "learning_rate": 2e-05, + "loss": 0.1094, + "step": 147 + }, + { + "epoch": 1.2629333333333332, + "grad_norm": 0.055537169110833, + "learning_rate": 2e-05, + "loss": 0.1054, + "step": 148 + }, + { + "epoch": 1.2714666666666667, + "grad_norm": 0.04423248714119304, + "learning_rate": 2e-05, + "loss": 0.0841, + "step": 149 + }, + { + "epoch": 1.28, + "grad_norm": 0.049931966607835034, + "learning_rate": 2e-05, + "loss": 0.0961, + "step": 150 + }, + { + "epoch": 1.2885333333333333, + "grad_norm": 0.06178656953298769, + "learning_rate": 2e-05, + "loss": 0.0854, + "step": 151 + }, + { + "epoch": 1.2970666666666666, + "grad_norm": 0.05783812343287897, + "learning_rate": 2e-05, + "loss": 0.1141, + "step": 152 + }, + { + "epoch": 1.3056, + "grad_norm": 0.048955120400167584, + "learning_rate": 2e-05, + "loss": 0.0947, + "step": 153 + }, + { + "epoch": 1.3141333333333334, + "grad_norm": 0.12270174746806978, + "learning_rate": 2e-05, + "loss": 0.1553, + "step": 154 + }, + { + "epoch": 1.3226666666666667, + "grad_norm": 0.06928026959973474, + "learning_rate": 2e-05, + "loss": 0.1274, + "step": 155 + }, + { + "epoch": 1.3312, + "grad_norm": 0.04756100666105405, + "learning_rate": 2e-05, + "loss": 0.0893, + "step": 156 + }, + { + "epoch": 1.3397333333333332, + "grad_norm": 0.056054951338196934, + "learning_rate": 2e-05, + "loss": 0.0831, + "step": 157 + }, + { + "epoch": 1.3482666666666667, + "grad_norm": 0.0516990471964239, + "learning_rate": 2e-05, + "loss": 0.0883, + "step": 158 + }, + { + "epoch": 1.3568, + "grad_norm": 0.06011650542069954, + "learning_rate": 2e-05, + "loss": 0.0938, + "step": 159 + }, + { + "epoch": 1.3653333333333333, + "grad_norm": 0.051831307951873976, + "learning_rate": 2e-05, + "loss": 0.1019, + "step": 160 + } + ], + "logging_steps": 1, + "max_steps": 351, + "num_input_tokens_seen": 0, + "num_train_epochs": 3, + "save_steps": 20, + "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.273910921652863e+18, + "train_batch_size": 16, + "trial_name": null, + "trial_params": null +} diff --git a/checkpoint-160/training_args.bin b/checkpoint-160/training_args.bin new file mode 100644 index 0000000000000000000000000000000000000000..8ac842d29fc6ad3e132cb7208dda5b61dd1079ee --- /dev/null +++ b/checkpoint-160/training_args.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:aa4edad1da5557fcd52a6da980443588016cead6f0444a3562cfa68029c66a04 +size 6840 diff --git a/checkpoint-160/zero_to_fp32.py b/checkpoint-160/zero_to_fp32.py new file mode 100644 index 0000000000000000000000000000000000000000..49b846633d6eb1e836e34681e44033581f4edb7b --- /dev/null +++ b/checkpoint-160/zero_to_fp32.py @@ -0,0 +1,592 @@ +#!/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 . pytorch_model.bin + +import argparse +import torch +import glob +import math +import os +import re +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) + + +@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 parse_model_states(files): + zero_model_states = [] + for file in files: + state_dict = torch.load(file, map_location=device) + + 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 files: + state_dict = torch.load(f, map_location=device) + # 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 not ZERO_STAGE 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}") + + if zero_stage <= 2: + fp32_flat_groups = [state_dicts[i][OPTIMIZER_STATE_DICT][fp32_groups_key] for i in range(len(state_dicts))] + elif zero_stage == 3: + # if there is more than one param group, there will be multiple flattened tensors - one + # flattened tensor per group - for simplicity merge them into a single tensor + # + # XXX: could make the script more memory efficient for when there are multiple groups - it + # will require matching the sub-lists of param_shapes for each param group flattened tensor + + fp32_flat_groups = [ + torch.cat(state_dicts[i][OPTIMIZER_STATE_DICT][fp32_groups_key], 0) 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): + """ + 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}'") + + 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}") + + 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}') + + if zero_stage <= 2: + return _get_fp32_state_dict_from_zero2_checkpoint(world_size, fp32_flat_groups, zero_model_states) + elif zero_stage == 3: + return _get_fp32_state_dict_from_zero3_checkpoint(world_size, fp32_flat_groups, zero_model_states) + + +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): + state_dict = OrderedDict() + + # buffers + buffers = zero_model_states[0].buffers + state_dict.update(buffers) + if debug: + print(f"added {len(buffers)} buffers") + + _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") + + +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 = fp32_flat_groups[0].numel() * 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 + for name, shape in param_shapes.items(): + + 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}" + ) + + # XXX: memory usage doubles here + state_dict[name] = torch.cat( + tuple(fp32_flat_groups[i].narrow(0, offset, partitioned_numel) for i in range(world_size)), + 0).narrow(0, 0, unpartitioned_numel).view(shape) + 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): + state_dict = OrderedDict() + + # buffers + buffers = zero_model_states[0].buffers + state_dict.update(buffers) + if debug: + print(f"added {len(buffers)} buffers") + + _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 get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir, tag=None): + """ + 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`` + + Returns: + - pytorch ``state_dict`` + + Note: this approach may not work if your application doesn't have sufficient free CPU memory and + you may need to use the offline approach using the ``zero_to_fp32.py`` script that is saved with + the checkpoint. + + 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. + + """ + 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") + + return _get_fp32_state_dict_from_zero_checkpoint(ds_checkpoint_dir) + + +def convert_zero_checkpoint_to_fp32_state_dict(checkpoint_dir, output_file, tag=None): + """ + 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_file``: path to the pytorch fp32 state_dict output file (e.g. path/pytorch_model.bin) + - ``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`` + """ + + state_dict = get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir, tag) + print(f"Saving fp32 state dict to {output_file}") + torch.save(state_dict, output_file) + + +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(f"Extracting fp32 weights") + state_dict = get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir, tag) + + logger.info(f"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_file", + type=str, + help="path to the pytorch fp32 state_dict output file (e.g. path/checkpoint-12/pytorch_model.bin)") + 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("-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_file, tag=args.tag) diff --git a/checkpoint-20/README.md b/checkpoint-20/README.md new file mode 100644 index 0000000000000000000000000000000000000000..e7d4f706aeefc6bb2aa84e963870f345a14c4af9 --- /dev/null +++ b/checkpoint-20/README.md @@ -0,0 +1,202 @@ +--- +library_name: peft +base_model: ../ckpts/Meta-Llama-3-8B-Instruct +--- + +# 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.11.1 \ No newline at end of file diff --git a/checkpoint-20/adapter_config.json b/checkpoint-20/adapter_config.json new file mode 100644 index 0000000000000000000000000000000000000000..ad16c073ed8946d227350e8fe4e99d689a8ede54 --- /dev/null +++ b/checkpoint-20/adapter_config.json @@ -0,0 +1,35 @@ +{ + "alpha_pattern": {}, + "auto_mapping": null, + "base_model_name_or_path": "../ckpts/Meta-Llama-3-8B-Instruct", + "bias": "none", + "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": 32, + "lora_dropout": 0.1, + "megatron_config": null, + "megatron_core": "megatron.core", + "modules_to_save": null, + "peft_type": "LORA", + "r": 16, + "rank_pattern": {}, + "revision": null, + "target_modules": [ + "down_proj", + "gate_proj", + "q_proj", + "lm_head", + "o_proj", + "v_proj", + "up_proj", + "k_proj" + ], + "task_type": "CAUSAL_LM", + "use_dora": false, + "use_rslora": false +} \ No newline at end of file diff --git a/checkpoint-20/adapter_model.safetensors b/checkpoint-20/adapter_model.safetensors new file mode 100644 index 0000000000000000000000000000000000000000..a5751695ace327ef7df9be2a6b3f20d53644e8d0 --- /dev/null +++ b/checkpoint-20/adapter_model.safetensors @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:181727761583eeba365bc29814e3196c50f90d02ae039c8a529d15c6b58813d4 +size 1138856856 diff --git a/checkpoint-20/global_step20/bf16_zero_pp_rank_0_mp_rank_00_optim_states.pt b/checkpoint-20/global_step20/bf16_zero_pp_rank_0_mp_rank_00_optim_states.pt new file mode 100644 index 0000000000000000000000000000000000000000..3b21aa8cad85e685e006ce3bc2075c0fe2ecff03 --- /dev/null +++ b/checkpoint-20/global_step20/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:fc02bac7488ab5bf8abdc7c2b5344d7b8dfb0afbb5b445938a1d48306aa2f091 +size 528781328 diff --git a/checkpoint-20/global_step20/mp_rank_00_model_states.pt b/checkpoint-20/global_step20/mp_rank_00_model_states.pt new file mode 100644 index 0000000000000000000000000000000000000000..d507f268adaf97bdeb412c5e835a44e56ae43a83 --- /dev/null +++ b/checkpoint-20/global_step20/mp_rank_00_model_states.pt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:92ae839a372c83084c52ed7acb3f7c30fafafaf5b2d3a11194adddf87b919f14 +size 199905337 diff --git a/checkpoint-20/latest b/checkpoint-20/latest new file mode 100644 index 0000000000000000000000000000000000000000..11e5c63223cdf01f44f9f3129915f9de3d647f31 --- /dev/null +++ b/checkpoint-20/latest @@ -0,0 +1 @@ +global_step20 \ No newline at end of file diff --git a/checkpoint-20/rng_state.pth b/checkpoint-20/rng_state.pth new file mode 100644 index 0000000000000000000000000000000000000000..e8254dbcbd4c6875b8d6617755cc9afd84a43b3c --- /dev/null +++ b/checkpoint-20/rng_state.pth @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:926d305e96380bc96ae95066ad252aa5ad89a958f613cc36a658033c5409657d +size 14244 diff --git a/checkpoint-20/trainer_state.json b/checkpoint-20/trainer_state.json new file mode 100644 index 0000000000000000000000000000000000000000..198f2a79d1ff6a247e3846966433fe7cb967dca2 --- /dev/null +++ b/checkpoint-20/trainer_state.json @@ -0,0 +1,173 @@ +{ + "best_metric": null, + "best_model_checkpoint": null, + "epoch": 0.17066666666666666, + "eval_steps": 500, + "global_step": 20, + "is_hyper_param_search": false, + "is_local_process_zero": true, + "is_world_process_zero": true, + "log_history": [ + { + "epoch": 0.008533333333333334, + "grad_norm": 100.21848203113535, + "learning_rate": 0.0, + "loss": 7.1962, + "step": 1 + }, + { + "epoch": 0.017066666666666667, + "grad_norm": 96.43006188910957, + "learning_rate": 3.0102999566398115e-06, + "loss": 6.9414, + "step": 2 + }, + { + "epoch": 0.0256, + "grad_norm": 97.35803466618715, + "learning_rate": 4.771212547196624e-06, + "loss": 7.0102, + "step": 3 + }, + { + "epoch": 0.034133333333333335, + "grad_norm": 95.14837816372646, + "learning_rate": 6.020599913279623e-06, + "loss": 6.5295, + "step": 4 + }, + { + "epoch": 0.042666666666666665, + "grad_norm": 91.76544275692784, + "learning_rate": 6.989700043360187e-06, + "loss": 6.4806, + "step": 5 + }, + { + "epoch": 0.0512, + "grad_norm": 84.4494318688335, + "learning_rate": 7.781512503836437e-06, + "loss": 6.4194, + "step": 6 + }, + { + "epoch": 0.05973333333333333, + "grad_norm": 71.37977490595638, + "learning_rate": 8.450980400142568e-06, + "loss": 5.4953, + "step": 7 + }, + { + "epoch": 0.06826666666666667, + "grad_norm": 49.31153456754566, + "learning_rate": 9.030899869919434e-06, + "loss": 5.4123, + "step": 8 + }, + { + "epoch": 0.0768, + "grad_norm": 20.37296364560341, + "learning_rate": 9.542425094393249e-06, + "loss": 5.2334, + "step": 9 + }, + { + "epoch": 0.08533333333333333, + "grad_norm": 7.968467079076881, + "learning_rate": 9.999999999999999e-06, + "loss": 5.0282, + "step": 10 + }, + { + "epoch": 0.09386666666666667, + "grad_norm": 3.559446532055649, + "learning_rate": 1.041392685158225e-05, + "loss": 4.612, + "step": 11 + }, + { + "epoch": 0.1024, + "grad_norm": 3.5528846947995674, + "learning_rate": 1.0791812460476248e-05, + "loss": 4.9475, + "step": 12 + }, + { + "epoch": 0.11093333333333333, + "grad_norm": 3.541968897471334, + "learning_rate": 1.1139433523068365e-05, + "loss": 4.2777, + "step": 13 + }, + { + "epoch": 0.11946666666666667, + "grad_norm": 3.54718070036198, + "learning_rate": 1.1461280356782378e-05, + "loss": 4.3507, + "step": 14 + }, + { + "epoch": 0.128, + "grad_norm": 3.8632334830606747, + "learning_rate": 1.1760912590556813e-05, + "loss": 4.5364, + "step": 15 + }, + { + "epoch": 0.13653333333333334, + "grad_norm": 3.6637424744054004, + "learning_rate": 1.2041199826559246e-05, + "loss": 3.9672, + "step": 16 + }, + { + "epoch": 0.14506666666666668, + "grad_norm": 3.919802904818311, + "learning_rate": 1.230448921378274e-05, + "loss": 4.0618, + "step": 17 + }, + { + "epoch": 0.1536, + "grad_norm": 4.71904950738746, + "learning_rate": 1.2552725051033058e-05, + "loss": 4.6656, + "step": 18 + }, + { + "epoch": 0.16213333333333332, + "grad_norm": 4.6656317698690835, + "learning_rate": 1.2787536009528288e-05, + "loss": 4.1131, + "step": 19 + }, + { + "epoch": 0.17066666666666666, + "grad_norm": 5.145138692367417, + "learning_rate": 1.301029995663981e-05, + "loss": 4.0989, + "step": 20 + } + ], + "logging_steps": 1, + "max_steps": 351, + "num_input_tokens_seen": 0, + "num_train_epochs": 3, + "save_steps": 20, + "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.924957640079442e+17, + "train_batch_size": 16, + "trial_name": null, + "trial_params": null +} diff --git a/checkpoint-20/training_args.bin b/checkpoint-20/training_args.bin new file mode 100644 index 0000000000000000000000000000000000000000..8ac842d29fc6ad3e132cb7208dda5b61dd1079ee --- /dev/null +++ b/checkpoint-20/training_args.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:aa4edad1da5557fcd52a6da980443588016cead6f0444a3562cfa68029c66a04 +size 6840 diff --git a/checkpoint-20/zero_to_fp32.py b/checkpoint-20/zero_to_fp32.py new file mode 100644 index 0000000000000000000000000000000000000000..49b846633d6eb1e836e34681e44033581f4edb7b --- /dev/null +++ b/checkpoint-20/zero_to_fp32.py @@ -0,0 +1,592 @@ +#!/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 . pytorch_model.bin + +import argparse +import torch +import glob +import math +import os +import re +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) + + +@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 parse_model_states(files): + zero_model_states = [] + for file in files: + state_dict = torch.load(file, map_location=device) + + 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 files: + state_dict = torch.load(f, map_location=device) + # 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 not ZERO_STAGE 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}") + + if zero_stage <= 2: + fp32_flat_groups = [state_dicts[i][OPTIMIZER_STATE_DICT][fp32_groups_key] for i in range(len(state_dicts))] + elif zero_stage == 3: + # if there is more than one param group, there will be multiple flattened tensors - one + # flattened tensor per group - for simplicity merge them into a single tensor + # + # XXX: could make the script more memory efficient for when there are multiple groups - it + # will require matching the sub-lists of param_shapes for each param group flattened tensor + + fp32_flat_groups = [ + torch.cat(state_dicts[i][OPTIMIZER_STATE_DICT][fp32_groups_key], 0) 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): + """ + 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}'") + + 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}") + + 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}') + + if zero_stage <= 2: + return _get_fp32_state_dict_from_zero2_checkpoint(world_size, fp32_flat_groups, zero_model_states) + elif zero_stage == 3: + return _get_fp32_state_dict_from_zero3_checkpoint(world_size, fp32_flat_groups, zero_model_states) + + +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): + state_dict = OrderedDict() + + # buffers + buffers = zero_model_states[0].buffers + state_dict.update(buffers) + if debug: + print(f"added {len(buffers)} buffers") + + _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") + + +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 = fp32_flat_groups[0].numel() * 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 + for name, shape in param_shapes.items(): + + 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}" + ) + + # XXX: memory usage doubles here + state_dict[name] = torch.cat( + tuple(fp32_flat_groups[i].narrow(0, offset, partitioned_numel) for i in range(world_size)), + 0).narrow(0, 0, unpartitioned_numel).view(shape) + 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): + state_dict = OrderedDict() + + # buffers + buffers = zero_model_states[0].buffers + state_dict.update(buffers) + if debug: + print(f"added {len(buffers)} buffers") + + _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 get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir, tag=None): + """ + 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`` + + Returns: + - pytorch ``state_dict`` + + Note: this approach may not work if your application doesn't have sufficient free CPU memory and + you may need to use the offline approach using the ``zero_to_fp32.py`` script that is saved with + the checkpoint. + + 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. + + """ + 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") + + return _get_fp32_state_dict_from_zero_checkpoint(ds_checkpoint_dir) + + +def convert_zero_checkpoint_to_fp32_state_dict(checkpoint_dir, output_file, tag=None): + """ + 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_file``: path to the pytorch fp32 state_dict output file (e.g. path/pytorch_model.bin) + - ``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`` + """ + + state_dict = get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir, tag) + print(f"Saving fp32 state dict to {output_file}") + torch.save(state_dict, output_file) + + +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(f"Extracting fp32 weights") + state_dict = get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir, tag) + + logger.info(f"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_file", + type=str, + help="path to the pytorch fp32 state_dict output file (e.g. path/checkpoint-12/pytorch_model.bin)") + 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("-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_file, tag=args.tag) diff --git a/checkpoint-40/README.md b/checkpoint-40/README.md new file mode 100644 index 0000000000000000000000000000000000000000..e7d4f706aeefc6bb2aa84e963870f345a14c4af9 --- /dev/null +++ b/checkpoint-40/README.md @@ -0,0 +1,202 @@ +--- +library_name: peft +base_model: ../ckpts/Meta-Llama-3-8B-Instruct +--- + +# 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.11.1 \ No newline at end of file diff --git a/checkpoint-40/adapter_config.json b/checkpoint-40/adapter_config.json new file mode 100644 index 0000000000000000000000000000000000000000..ad16c073ed8946d227350e8fe4e99d689a8ede54 --- /dev/null +++ b/checkpoint-40/adapter_config.json @@ -0,0 +1,35 @@ +{ + "alpha_pattern": {}, + "auto_mapping": null, + "base_model_name_or_path": "../ckpts/Meta-Llama-3-8B-Instruct", + "bias": "none", + "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": 32, + "lora_dropout": 0.1, + "megatron_config": null, + "megatron_core": "megatron.core", + "modules_to_save": null, + "peft_type": "LORA", + "r": 16, + "rank_pattern": {}, + "revision": null, + "target_modules": [ + "down_proj", + "gate_proj", + "q_proj", + "lm_head", + "o_proj", + "v_proj", + "up_proj", + "k_proj" + ], + "task_type": "CAUSAL_LM", + "use_dora": false, + "use_rslora": false +} \ No newline at end of file diff --git a/checkpoint-40/adapter_model.safetensors b/checkpoint-40/adapter_model.safetensors new file mode 100644 index 0000000000000000000000000000000000000000..3b5879d19cd4f8dde7e26054ed1062a9ea0c49ef --- /dev/null +++ b/checkpoint-40/adapter_model.safetensors @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:df22fc3523779ffcc3c8161bd924866943914d0fe3f077b47683ce0a44bbd378 +size 1138856856 diff --git a/checkpoint-40/global_step40/bf16_zero_pp_rank_0_mp_rank_00_optim_states.pt b/checkpoint-40/global_step40/bf16_zero_pp_rank_0_mp_rank_00_optim_states.pt new file mode 100644 index 0000000000000000000000000000000000000000..7c10a2861b3f1e14617b012a49b35ac6e2c73c36 --- /dev/null +++ b/checkpoint-40/global_step40/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:d1659655a3d80ff77b190ea02ca19985a67df95eb8d71a71bee18bc73f17802e +size 528781328 diff --git a/checkpoint-40/global_step40/mp_rank_00_model_states.pt b/checkpoint-40/global_step40/mp_rank_00_model_states.pt new file mode 100644 index 0000000000000000000000000000000000000000..49b525d1793eaa3d4e4a8bc0afe5613a0906676c --- /dev/null +++ b/checkpoint-40/global_step40/mp_rank_00_model_states.pt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:22800478617c1bd7dfacaacc129c28a57125fff961281628b3488d45734cfe67 +size 199905337 diff --git a/checkpoint-40/latest b/checkpoint-40/latest new file mode 100644 index 0000000000000000000000000000000000000000..8631ab8ddebf60eb3e7f5f2c2b1a2da8298a43c3 --- /dev/null +++ b/checkpoint-40/latest @@ -0,0 +1 @@ +global_step40 \ No newline at end of file diff --git a/checkpoint-40/rng_state.pth b/checkpoint-40/rng_state.pth new file mode 100644 index 0000000000000000000000000000000000000000..7b9e0578d84b49cb235d98e0d8879a37a434e8c5 --- /dev/null +++ b/checkpoint-40/rng_state.pth @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a49aafe79c0893003242520587ee35071de0249e66c0af69e715f46e1600841d +size 14244 diff --git a/checkpoint-40/trainer_state.json b/checkpoint-40/trainer_state.json new file mode 100644 index 0000000000000000000000000000000000000000..d7551f1e8a47468d64544f9bf3e05f95baea0ad6 --- /dev/null +++ b/checkpoint-40/trainer_state.json @@ -0,0 +1,313 @@ +{ + "best_metric": null, + "best_model_checkpoint": null, + "epoch": 0.3413333333333333, + "eval_steps": 500, + "global_step": 40, + "is_hyper_param_search": false, + "is_local_process_zero": true, + "is_world_process_zero": true, + "log_history": [ + { + "epoch": 0.008533333333333334, + "grad_norm": 100.21848203113535, + "learning_rate": 0.0, + "loss": 7.1962, + "step": 1 + }, + { + "epoch": 0.017066666666666667, + "grad_norm": 96.43006188910957, + "learning_rate": 3.0102999566398115e-06, + "loss": 6.9414, + "step": 2 + }, + { + "epoch": 0.0256, + "grad_norm": 97.35803466618715, + "learning_rate": 4.771212547196624e-06, + "loss": 7.0102, + "step": 3 + }, + { + "epoch": 0.034133333333333335, + "grad_norm": 95.14837816372646, + "learning_rate": 6.020599913279623e-06, + "loss": 6.5295, + "step": 4 + }, + { + "epoch": 0.042666666666666665, + "grad_norm": 91.76544275692784, + "learning_rate": 6.989700043360187e-06, + "loss": 6.4806, + "step": 5 + }, + { + "epoch": 0.0512, + "grad_norm": 84.4494318688335, + "learning_rate": 7.781512503836437e-06, + "loss": 6.4194, + "step": 6 + }, + { + "epoch": 0.05973333333333333, + "grad_norm": 71.37977490595638, + "learning_rate": 8.450980400142568e-06, + "loss": 5.4953, + "step": 7 + }, + { + "epoch": 0.06826666666666667, + "grad_norm": 49.31153456754566, + "learning_rate": 9.030899869919434e-06, + "loss": 5.4123, + "step": 8 + }, + { + "epoch": 0.0768, + "grad_norm": 20.37296364560341, + "learning_rate": 9.542425094393249e-06, + "loss": 5.2334, + "step": 9 + }, + { + "epoch": 0.08533333333333333, + "grad_norm": 7.968467079076881, + "learning_rate": 9.999999999999999e-06, + "loss": 5.0282, + "step": 10 + }, + { + "epoch": 0.09386666666666667, + "grad_norm": 3.559446532055649, + "learning_rate": 1.041392685158225e-05, + "loss": 4.612, + "step": 11 + }, + { + "epoch": 0.1024, + "grad_norm": 3.5528846947995674, + "learning_rate": 1.0791812460476248e-05, + "loss": 4.9475, + "step": 12 + }, + { + "epoch": 0.11093333333333333, + "grad_norm": 3.541968897471334, + "learning_rate": 1.1139433523068365e-05, + "loss": 4.2777, + "step": 13 + }, + { + "epoch": 0.11946666666666667, + "grad_norm": 3.54718070036198, + "learning_rate": 1.1461280356782378e-05, + "loss": 4.3507, + "step": 14 + }, + { + "epoch": 0.128, + "grad_norm": 3.8632334830606747, + "learning_rate": 1.1760912590556813e-05, + "loss": 4.5364, + "step": 15 + }, + { + "epoch": 0.13653333333333334, + "grad_norm": 3.6637424744054004, + "learning_rate": 1.2041199826559246e-05, + "loss": 3.9672, + "step": 16 + }, + { + "epoch": 0.14506666666666668, + "grad_norm": 3.919802904818311, + "learning_rate": 1.230448921378274e-05, + "loss": 4.0618, + "step": 17 + }, + { + "epoch": 0.1536, + "grad_norm": 4.71904950738746, + "learning_rate": 1.2552725051033058e-05, + "loss": 4.6656, + "step": 18 + }, + { + "epoch": 0.16213333333333332, + "grad_norm": 4.6656317698690835, + "learning_rate": 1.2787536009528288e-05, + "loss": 4.1131, + "step": 19 + }, + { + "epoch": 0.17066666666666666, + "grad_norm": 5.145138692367417, + "learning_rate": 1.301029995663981e-05, + "loss": 4.0989, + "step": 20 + }, + { + "epoch": 0.1792, + "grad_norm": 5.923538014759818, + "learning_rate": 1.3222192947339192e-05, + "loss": 4.4991, + "step": 21 + }, + { + "epoch": 0.18773333333333334, + "grad_norm": 5.941056962941364, + "learning_rate": 1.3424226808222062e-05, + "loss": 4.0836, + "step": 22 + }, + { + "epoch": 0.19626666666666667, + "grad_norm": 6.171026012117947, + "learning_rate": 1.3617278360175927e-05, + "loss": 3.6861, + "step": 23 + }, + { + "epoch": 0.2048, + "grad_norm": 7.130542138930838, + "learning_rate": 1.380211241711606e-05, + "loss": 4.0958, + "step": 24 + }, + { + "epoch": 0.21333333333333335, + "grad_norm": 7.328837606110418, + "learning_rate": 1.3979400086720374e-05, + "loss": 3.9524, + "step": 25 + }, + { + "epoch": 0.22186666666666666, + "grad_norm": 6.923489005711429, + "learning_rate": 1.4149733479708178e-05, + "loss": 3.6062, + "step": 26 + }, + { + "epoch": 0.2304, + "grad_norm": 6.409498926059221, + "learning_rate": 1.4313637641589872e-05, + "loss": 3.2034, + "step": 27 + }, + { + "epoch": 0.23893333333333333, + "grad_norm": 5.781628405584682, + "learning_rate": 1.4471580313422191e-05, + "loss": 2.8158, + "step": 28 + }, + { + "epoch": 0.24746666666666667, + "grad_norm": 6.2927590068243315, + "learning_rate": 1.4623979978989559e-05, + "loss": 2.9803, + "step": 29 + }, + { + "epoch": 0.256, + "grad_norm": 6.103844678630006, + "learning_rate": 1.4771212547196623e-05, + "loss": 2.847, + "step": 30 + }, + { + "epoch": 0.26453333333333334, + "grad_norm": 7.656341925867144, + "learning_rate": 1.4913616938342726e-05, + "loss": 3.0907, + "step": 31 + }, + { + "epoch": 0.2730666666666667, + "grad_norm": 6.324242877501844, + "learning_rate": 1.5051499783199059e-05, + "loss": 2.3467, + "step": 32 + }, + { + "epoch": 0.2816, + "grad_norm": 7.606313101162739, + "learning_rate": 1.5185139398778874e-05, + "loss": 2.5292, + "step": 33 + }, + { + "epoch": 0.29013333333333335, + "grad_norm": 8.553792493849265, + "learning_rate": 1.531478917042255e-05, + "loss": 2.4547, + "step": 34 + }, + { + "epoch": 0.2986666666666667, + "grad_norm": 8.483368703272543, + "learning_rate": 1.5440680443502753e-05, + "loss": 2.1956, + "step": 35 + }, + { + "epoch": 0.3072, + "grad_norm": 8.364739352838077, + "learning_rate": 1.5563025007672873e-05, + "loss": 1.8552, + "step": 36 + }, + { + "epoch": 0.3157333333333333, + "grad_norm": 9.37663682000104, + "learning_rate": 1.5682017240669948e-05, + "loss": 1.9228, + "step": 37 + }, + { + "epoch": 0.32426666666666665, + "grad_norm": 9.823047193440066, + "learning_rate": 1.57978359661681e-05, + "loss": 1.7033, + "step": 38 + }, + { + "epoch": 0.3328, + "grad_norm": 9.692618512955894, + "learning_rate": 1.591064607026499e-05, + "loss": 1.3768, + "step": 39 + }, + { + "epoch": 0.3413333333333333, + "grad_norm": 9.08889021911031, + "learning_rate": 1.6020599913279622e-05, + "loss": 1.3015, + "step": 40 + } + ], + "logging_steps": 1, + "max_steps": 351, + "num_input_tokens_seen": 0, + "num_train_epochs": 3, + "save_steps": 20, + "stateful_callbacks": { + "TrainerControl": { + "args": { + "should_epoch_stop": false, + "should_evaluate": false, + "should_log": false, + "should_save": true, + "should_training_stop": false + }, + "attributes": {} + } + }, + "total_flos": 5.708931636490404e+17, + "train_batch_size": 16, + "trial_name": null, + "trial_params": null +} diff --git a/checkpoint-40/training_args.bin b/checkpoint-40/training_args.bin new file mode 100644 index 0000000000000000000000000000000000000000..8ac842d29fc6ad3e132cb7208dda5b61dd1079ee --- /dev/null +++ b/checkpoint-40/training_args.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:aa4edad1da5557fcd52a6da980443588016cead6f0444a3562cfa68029c66a04 +size 6840 diff --git a/checkpoint-40/zero_to_fp32.py b/checkpoint-40/zero_to_fp32.py new file mode 100644 index 0000000000000000000000000000000000000000..49b846633d6eb1e836e34681e44033581f4edb7b --- /dev/null +++ b/checkpoint-40/zero_to_fp32.py @@ -0,0 +1,592 @@ +#!/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 . pytorch_model.bin + +import argparse +import torch +import glob +import math +import os +import re +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) + + +@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 parse_model_states(files): + zero_model_states = [] + for file in files: + state_dict = torch.load(file, map_location=device) + + 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 files: + state_dict = torch.load(f, map_location=device) + # 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 not ZERO_STAGE 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}") + + if zero_stage <= 2: + fp32_flat_groups = [state_dicts[i][OPTIMIZER_STATE_DICT][fp32_groups_key] for i in range(len(state_dicts))] + elif zero_stage == 3: + # if there is more than one param group, there will be multiple flattened tensors - one + # flattened tensor per group - for simplicity merge them into a single tensor + # + # XXX: could make the script more memory efficient for when there are multiple groups - it + # will require matching the sub-lists of param_shapes for each param group flattened tensor + + fp32_flat_groups = [ + torch.cat(state_dicts[i][OPTIMIZER_STATE_DICT][fp32_groups_key], 0) 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): + """ + 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}'") + + 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}") + + 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}') + + if zero_stage <= 2: + return _get_fp32_state_dict_from_zero2_checkpoint(world_size, fp32_flat_groups, zero_model_states) + elif zero_stage == 3: + return _get_fp32_state_dict_from_zero3_checkpoint(world_size, fp32_flat_groups, zero_model_states) + + +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): + state_dict = OrderedDict() + + # buffers + buffers = zero_model_states[0].buffers + state_dict.update(buffers) + if debug: + print(f"added {len(buffers)} buffers") + + _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") + + +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 = fp32_flat_groups[0].numel() * 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 + for name, shape in param_shapes.items(): + + 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}" + ) + + # XXX: memory usage doubles here + state_dict[name] = torch.cat( + tuple(fp32_flat_groups[i].narrow(0, offset, partitioned_numel) for i in range(world_size)), + 0).narrow(0, 0, unpartitioned_numel).view(shape) + 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): + state_dict = OrderedDict() + + # buffers + buffers = zero_model_states[0].buffers + state_dict.update(buffers) + if debug: + print(f"added {len(buffers)} buffers") + + _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 get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir, tag=None): + """ + 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`` + + Returns: + - pytorch ``state_dict`` + + Note: this approach may not work if your application doesn't have sufficient free CPU memory and + you may need to use the offline approach using the ``zero_to_fp32.py`` script that is saved with + the checkpoint. + + 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. + + """ + 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") + + return _get_fp32_state_dict_from_zero_checkpoint(ds_checkpoint_dir) + + +def convert_zero_checkpoint_to_fp32_state_dict(checkpoint_dir, output_file, tag=None): + """ + 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_file``: path to the pytorch fp32 state_dict output file (e.g. path/pytorch_model.bin) + - ``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`` + """ + + state_dict = get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir, tag) + print(f"Saving fp32 state dict to {output_file}") + torch.save(state_dict, output_file) + + +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(f"Extracting fp32 weights") + state_dict = get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir, tag) + + logger.info(f"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_file", + type=str, + help="path to the pytorch fp32 state_dict output file (e.g. path/checkpoint-12/pytorch_model.bin)") + 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("-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_file, tag=args.tag) diff --git a/checkpoint-60/README.md b/checkpoint-60/README.md new file mode 100644 index 0000000000000000000000000000000000000000..e7d4f706aeefc6bb2aa84e963870f345a14c4af9 --- /dev/null +++ b/checkpoint-60/README.md @@ -0,0 +1,202 @@ +--- +library_name: peft +base_model: ../ckpts/Meta-Llama-3-8B-Instruct +--- + +# 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.11.1 \ No newline at end of file diff --git a/checkpoint-60/adapter_config.json b/checkpoint-60/adapter_config.json new file mode 100644 index 0000000000000000000000000000000000000000..ad16c073ed8946d227350e8fe4e99d689a8ede54 --- /dev/null +++ b/checkpoint-60/adapter_config.json @@ -0,0 +1,35 @@ +{ + "alpha_pattern": {}, + "auto_mapping": null, + "base_model_name_or_path": "../ckpts/Meta-Llama-3-8B-Instruct", + "bias": "none", + "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": 32, + "lora_dropout": 0.1, + "megatron_config": null, + "megatron_core": "megatron.core", + "modules_to_save": null, + "peft_type": "LORA", + "r": 16, + "rank_pattern": {}, + "revision": null, + "target_modules": [ + "down_proj", + "gate_proj", + "q_proj", + "lm_head", + "o_proj", + "v_proj", + "up_proj", + "k_proj" + ], + "task_type": "CAUSAL_LM", + "use_dora": false, + "use_rslora": false +} \ No newline at end of file diff --git a/checkpoint-60/adapter_model.safetensors b/checkpoint-60/adapter_model.safetensors new file mode 100644 index 0000000000000000000000000000000000000000..1e35e584361c6261e9c4af6ea5e70c0462bb4cbe --- /dev/null +++ b/checkpoint-60/adapter_model.safetensors @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:77335a2ac39e530a5aa962884d40c39cb11419d44e8052c02325a25871cb3493 +size 1138856856 diff --git a/checkpoint-60/global_step60/bf16_zero_pp_rank_0_mp_rank_00_optim_states.pt b/checkpoint-60/global_step60/bf16_zero_pp_rank_0_mp_rank_00_optim_states.pt new file mode 100644 index 0000000000000000000000000000000000000000..d25b204332c531a51ec954290d139c575888edb6 --- /dev/null +++ b/checkpoint-60/global_step60/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:72fe210e9583468ebc447e663cdb5e604bb48429b5370b6ebe2ac0eef1c8b4be +size 528781328 diff --git a/checkpoint-60/global_step60/mp_rank_00_model_states.pt b/checkpoint-60/global_step60/mp_rank_00_model_states.pt new file mode 100644 index 0000000000000000000000000000000000000000..d44ca31b5158f431652974b2f8656cf3edf7da8f --- /dev/null +++ b/checkpoint-60/global_step60/mp_rank_00_model_states.pt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:96748f130193979fdb318f39bbcc7a68656cd18dae9c2703108db3b979b02fcc +size 199905337 diff --git a/checkpoint-60/latest b/checkpoint-60/latest new file mode 100644 index 0000000000000000000000000000000000000000..6dac34b840ecfb636ba8ab1e4da79fa1bdc8c3d4 --- /dev/null +++ b/checkpoint-60/latest @@ -0,0 +1 @@ +global_step60 \ No newline at end of file diff --git a/checkpoint-60/rng_state.pth b/checkpoint-60/rng_state.pth new file mode 100644 index 0000000000000000000000000000000000000000..dd3ffd279d461273ef27d2b6bf5825c51e430c25 --- /dev/null +++ b/checkpoint-60/rng_state.pth @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:59a5d7a69796d62bbddf60556572e2039646e271b96568851e851a9d2963d37e +size 14244 diff --git a/checkpoint-60/trainer_state.json b/checkpoint-60/trainer_state.json new file mode 100644 index 0000000000000000000000000000000000000000..90f15707e6ea9190026f4a15be797c7e71f842d4 --- /dev/null +++ b/checkpoint-60/trainer_state.json @@ -0,0 +1,453 @@ +{ + "best_metric": null, + "best_model_checkpoint": null, + "epoch": 0.512, + "eval_steps": 500, + "global_step": 60, + "is_hyper_param_search": false, + "is_local_process_zero": true, + "is_world_process_zero": true, + "log_history": [ + { + "epoch": 0.008533333333333334, + "grad_norm": 100.21848203113535, + "learning_rate": 0.0, + "loss": 7.1962, + "step": 1 + }, + { + "epoch": 0.017066666666666667, + "grad_norm": 96.43006188910957, + "learning_rate": 3.0102999566398115e-06, + "loss": 6.9414, + "step": 2 + }, + { + "epoch": 0.0256, + "grad_norm": 97.35803466618715, + "learning_rate": 4.771212547196624e-06, + "loss": 7.0102, + "step": 3 + }, + { + "epoch": 0.034133333333333335, + "grad_norm": 95.14837816372646, + "learning_rate": 6.020599913279623e-06, + "loss": 6.5295, + "step": 4 + }, + { + "epoch": 0.042666666666666665, + "grad_norm": 91.76544275692784, + "learning_rate": 6.989700043360187e-06, + "loss": 6.4806, + "step": 5 + }, + { + "epoch": 0.0512, + "grad_norm": 84.4494318688335, + "learning_rate": 7.781512503836437e-06, + "loss": 6.4194, + "step": 6 + }, + { + "epoch": 0.05973333333333333, + "grad_norm": 71.37977490595638, + "learning_rate": 8.450980400142568e-06, + "loss": 5.4953, + "step": 7 + }, + { + "epoch": 0.06826666666666667, + "grad_norm": 49.31153456754566, + "learning_rate": 9.030899869919434e-06, + "loss": 5.4123, + "step": 8 + }, + { + "epoch": 0.0768, + "grad_norm": 20.37296364560341, + "learning_rate": 9.542425094393249e-06, + "loss": 5.2334, + "step": 9 + }, + { + "epoch": 0.08533333333333333, + "grad_norm": 7.968467079076881, + "learning_rate": 9.999999999999999e-06, + "loss": 5.0282, + "step": 10 + }, + { + "epoch": 0.09386666666666667, + "grad_norm": 3.559446532055649, + "learning_rate": 1.041392685158225e-05, + "loss": 4.612, + "step": 11 + }, + { + "epoch": 0.1024, + "grad_norm": 3.5528846947995674, + "learning_rate": 1.0791812460476248e-05, + "loss": 4.9475, + "step": 12 + }, + { + "epoch": 0.11093333333333333, + "grad_norm": 3.541968897471334, + "learning_rate": 1.1139433523068365e-05, + "loss": 4.2777, + "step": 13 + }, + { + "epoch": 0.11946666666666667, + "grad_norm": 3.54718070036198, + "learning_rate": 1.1461280356782378e-05, + "loss": 4.3507, + "step": 14 + }, + { + "epoch": 0.128, + "grad_norm": 3.8632334830606747, + "learning_rate": 1.1760912590556813e-05, + "loss": 4.5364, + "step": 15 + }, + { + "epoch": 0.13653333333333334, + "grad_norm": 3.6637424744054004, + "learning_rate": 1.2041199826559246e-05, + "loss": 3.9672, + "step": 16 + }, + { + "epoch": 0.14506666666666668, + "grad_norm": 3.919802904818311, + "learning_rate": 1.230448921378274e-05, + "loss": 4.0618, + "step": 17 + }, + { + "epoch": 0.1536, + "grad_norm": 4.71904950738746, + "learning_rate": 1.2552725051033058e-05, + "loss": 4.6656, + "step": 18 + }, + { + "epoch": 0.16213333333333332, + "grad_norm": 4.6656317698690835, + "learning_rate": 1.2787536009528288e-05, + "loss": 4.1131, + "step": 19 + }, + { + "epoch": 0.17066666666666666, + "grad_norm": 5.145138692367417, + "learning_rate": 1.301029995663981e-05, + "loss": 4.0989, + "step": 20 + }, + { + "epoch": 0.1792, + "grad_norm": 5.923538014759818, + "learning_rate": 1.3222192947339192e-05, + "loss": 4.4991, + "step": 21 + }, + { + "epoch": 0.18773333333333334, + "grad_norm": 5.941056962941364, + "learning_rate": 1.3424226808222062e-05, + "loss": 4.0836, + "step": 22 + }, + { + "epoch": 0.19626666666666667, + "grad_norm": 6.171026012117947, + "learning_rate": 1.3617278360175927e-05, + "loss": 3.6861, + "step": 23 + }, + { + "epoch": 0.2048, + "grad_norm": 7.130542138930838, + "learning_rate": 1.380211241711606e-05, + "loss": 4.0958, + "step": 24 + }, + { + "epoch": 0.21333333333333335, + "grad_norm": 7.328837606110418, + "learning_rate": 1.3979400086720374e-05, + "loss": 3.9524, + "step": 25 + }, + { + "epoch": 0.22186666666666666, + "grad_norm": 6.923489005711429, + "learning_rate": 1.4149733479708178e-05, + "loss": 3.6062, + "step": 26 + }, + { + "epoch": 0.2304, + "grad_norm": 6.409498926059221, + "learning_rate": 1.4313637641589872e-05, + "loss": 3.2034, + "step": 27 + }, + { + "epoch": 0.23893333333333333, + "grad_norm": 5.781628405584682, + "learning_rate": 1.4471580313422191e-05, + "loss": 2.8158, + "step": 28 + }, + { + "epoch": 0.24746666666666667, + "grad_norm": 6.2927590068243315, + "learning_rate": 1.4623979978989559e-05, + "loss": 2.9803, + "step": 29 + }, + { + "epoch": 0.256, + "grad_norm": 6.103844678630006, + "learning_rate": 1.4771212547196623e-05, + "loss": 2.847, + "step": 30 + }, + { + "epoch": 0.26453333333333334, + "grad_norm": 7.656341925867144, + "learning_rate": 1.4913616938342726e-05, + "loss": 3.0907, + "step": 31 + }, + { + "epoch": 0.2730666666666667, + "grad_norm": 6.324242877501844, + "learning_rate": 1.5051499783199059e-05, + "loss": 2.3467, + "step": 32 + }, + { + "epoch": 0.2816, + "grad_norm": 7.606313101162739, + "learning_rate": 1.5185139398778874e-05, + "loss": 2.5292, + "step": 33 + }, + { + "epoch": 0.29013333333333335, + "grad_norm": 8.553792493849265, + "learning_rate": 1.531478917042255e-05, + "loss": 2.4547, + "step": 34 + }, + { + "epoch": 0.2986666666666667, + "grad_norm": 8.483368703272543, + "learning_rate": 1.5440680443502753e-05, + "loss": 2.1956, + "step": 35 + }, + { + "epoch": 0.3072, + "grad_norm": 8.364739352838077, + "learning_rate": 1.5563025007672873e-05, + "loss": 1.8552, + "step": 36 + }, + { + "epoch": 0.3157333333333333, + "grad_norm": 9.37663682000104, + "learning_rate": 1.5682017240669948e-05, + "loss": 1.9228, + "step": 37 + }, + { + "epoch": 0.32426666666666665, + "grad_norm": 9.823047193440066, + "learning_rate": 1.57978359661681e-05, + "loss": 1.7033, + "step": 38 + }, + { + "epoch": 0.3328, + "grad_norm": 9.692618512955894, + "learning_rate": 1.591064607026499e-05, + "loss": 1.3768, + "step": 39 + }, + { + "epoch": 0.3413333333333333, + "grad_norm": 9.08889021911031, + "learning_rate": 1.6020599913279622e-05, + "loss": 1.3015, + "step": 40 + }, + { + "epoch": 0.34986666666666666, + "grad_norm": 8.081534221516058, + "learning_rate": 1.6127838567197353e-05, + "loss": 0.9228, + "step": 41 + }, + { + "epoch": 0.3584, + "grad_norm": 6.238638048950311, + "learning_rate": 1.6232492903979005e-05, + "loss": 0.7267, + "step": 42 + }, + { + "epoch": 0.36693333333333333, + "grad_norm": 3.4058036861773604, + "learning_rate": 1.6334684555795865e-05, + "loss": 0.5875, + "step": 43 + }, + { + "epoch": 0.37546666666666667, + "grad_norm": 2.079163829467713, + "learning_rate": 1.6434526764861872e-05, + "loss": 0.6355, + "step": 44 + }, + { + "epoch": 0.384, + "grad_norm": 1.5597487833024746, + "learning_rate": 1.6532125137753435e-05, + "loss": 0.5106, + "step": 45 + }, + { + "epoch": 0.39253333333333335, + "grad_norm": 2.491689602375256, + "learning_rate": 1.662757831681574e-05, + "loss": 0.6454, + "step": 46 + }, + { + "epoch": 0.4010666666666667, + "grad_norm": 2.010880438195854, + "learning_rate": 1.672097857935717e-05, + "loss": 0.4757, + "step": 47 + }, + { + "epoch": 0.4096, + "grad_norm": 1.9452805114322096, + "learning_rate": 1.681241237375587e-05, + "loss": 0.4133, + "step": 48 + }, + { + "epoch": 0.41813333333333336, + "grad_norm": 1.7620848552306103, + "learning_rate": 1.6901960800285137e-05, + "loss": 0.4004, + "step": 49 + }, + { + "epoch": 0.4266666666666667, + "grad_norm": 1.278224489774809, + "learning_rate": 1.6989700043360187e-05, + "loss": 0.3523, + "step": 50 + }, + { + "epoch": 0.4352, + "grad_norm": 1.6151354758303231, + "learning_rate": 1.7075701760979363e-05, + "loss": 0.4317, + "step": 51 + }, + { + "epoch": 0.4437333333333333, + "grad_norm": 1.3451396055695035, + "learning_rate": 1.716003343634799e-05, + "loss": 0.3474, + "step": 52 + }, + { + "epoch": 0.45226666666666665, + "grad_norm": 1.6814977782362666, + "learning_rate": 1.724275869600789e-05, + "loss": 0.3706, + "step": 53 + }, + { + "epoch": 0.4608, + "grad_norm": 1.1682442432688667, + "learning_rate": 1.7323937598229687e-05, + "loss": 0.3488, + "step": 54 + }, + { + "epoch": 0.4693333333333333, + "grad_norm": 0.8839814540462471, + "learning_rate": 1.7403626894942437e-05, + "loss": 0.293, + "step": 55 + }, + { + "epoch": 0.47786666666666666, + "grad_norm": 0.7974304806295485, + "learning_rate": 1.7481880270062003e-05, + "loss": 0.2717, + "step": 56 + }, + { + "epoch": 0.4864, + "grad_norm": 0.6232203657585239, + "learning_rate": 1.7558748556724913e-05, + "loss": 0.1741, + "step": 57 + }, + { + "epoch": 0.49493333333333334, + "grad_norm": 0.6850688604563008, + "learning_rate": 1.763427993562937e-05, + "loss": 0.228, + "step": 58 + }, + { + "epoch": 0.5034666666666666, + "grad_norm": 0.5923826384300431, + "learning_rate": 1.7708520116421443e-05, + "loss": 0.2131, + "step": 59 + }, + { + "epoch": 0.512, + "grad_norm": 0.489754430485032, + "learning_rate": 1.7781512503836432e-05, + "loss": 0.165, + "step": 60 + } + ], + "logging_steps": 1, + "max_steps": 351, + "num_input_tokens_seen": 0, + "num_train_epochs": 3, + "save_steps": 20, + "stateful_callbacks": { + "TrainerControl": { + "args": { + "should_epoch_stop": false, + "should_evaluate": false, + "should_log": false, + "should_save": true, + "should_training_stop": false + }, + "attributes": {} + } + }, + "total_flos": 8.473824188421898e+17, + "train_batch_size": 16, + "trial_name": null, + "trial_params": null +} diff --git a/checkpoint-60/training_args.bin b/checkpoint-60/training_args.bin new file mode 100644 index 0000000000000000000000000000000000000000..8ac842d29fc6ad3e132cb7208dda5b61dd1079ee --- /dev/null +++ b/checkpoint-60/training_args.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:aa4edad1da5557fcd52a6da980443588016cead6f0444a3562cfa68029c66a04 +size 6840 diff --git a/checkpoint-60/zero_to_fp32.py b/checkpoint-60/zero_to_fp32.py new file mode 100644 index 0000000000000000000000000000000000000000..49b846633d6eb1e836e34681e44033581f4edb7b --- /dev/null +++ b/checkpoint-60/zero_to_fp32.py @@ -0,0 +1,592 @@ +#!/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 . pytorch_model.bin + +import argparse +import torch +import glob +import math +import os +import re +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) + + +@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 parse_model_states(files): + zero_model_states = [] + for file in files: + state_dict = torch.load(file, map_location=device) + + 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 files: + state_dict = torch.load(f, map_location=device) + # 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 not ZERO_STAGE 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}") + + if zero_stage <= 2: + fp32_flat_groups = [state_dicts[i][OPTIMIZER_STATE_DICT][fp32_groups_key] for i in range(len(state_dicts))] + elif zero_stage == 3: + # if there is more than one param group, there will be multiple flattened tensors - one + # flattened tensor per group - for simplicity merge them into a single tensor + # + # XXX: could make the script more memory efficient for when there are multiple groups - it + # will require matching the sub-lists of param_shapes for each param group flattened tensor + + fp32_flat_groups = [ + torch.cat(state_dicts[i][OPTIMIZER_STATE_DICT][fp32_groups_key], 0) 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): + """ + 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}'") + + 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}") + + 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}') + + if zero_stage <= 2: + return _get_fp32_state_dict_from_zero2_checkpoint(world_size, fp32_flat_groups, zero_model_states) + elif zero_stage == 3: + return _get_fp32_state_dict_from_zero3_checkpoint(world_size, fp32_flat_groups, zero_model_states) + + +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): + state_dict = OrderedDict() + + # buffers + buffers = zero_model_states[0].buffers + state_dict.update(buffers) + if debug: + print(f"added {len(buffers)} buffers") + + _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") + + +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 = fp32_flat_groups[0].numel() * 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 + for name, shape in param_shapes.items(): + + 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}" + ) + + # XXX: memory usage doubles here + state_dict[name] = torch.cat( + tuple(fp32_flat_groups[i].narrow(0, offset, partitioned_numel) for i in range(world_size)), + 0).narrow(0, 0, unpartitioned_numel).view(shape) + 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): + state_dict = OrderedDict() + + # buffers + buffers = zero_model_states[0].buffers + state_dict.update(buffers) + if debug: + print(f"added {len(buffers)} buffers") + + _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 get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir, tag=None): + """ + 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`` + + Returns: + - pytorch ``state_dict`` + + Note: this approach may not work if your application doesn't have sufficient free CPU memory and + you may need to use the offline approach using the ``zero_to_fp32.py`` script that is saved with + the checkpoint. + + 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. + + """ + 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") + + return _get_fp32_state_dict_from_zero_checkpoint(ds_checkpoint_dir) + + +def convert_zero_checkpoint_to_fp32_state_dict(checkpoint_dir, output_file, tag=None): + """ + 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_file``: path to the pytorch fp32 state_dict output file (e.g. path/pytorch_model.bin) + - ``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`` + """ + + state_dict = get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir, tag) + print(f"Saving fp32 state dict to {output_file}") + torch.save(state_dict, output_file) + + +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(f"Extracting fp32 weights") + state_dict = get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir, tag) + + logger.info(f"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_file", + type=str, + help="path to the pytorch fp32 state_dict output file (e.g. path/checkpoint-12/pytorch_model.bin)") + 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("-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_file, tag=args.tag) diff --git a/checkpoint-80/README.md b/checkpoint-80/README.md new file mode 100644 index 0000000000000000000000000000000000000000..e7d4f706aeefc6bb2aa84e963870f345a14c4af9 --- /dev/null +++ b/checkpoint-80/README.md @@ -0,0 +1,202 @@ +--- +library_name: peft +base_model: ../ckpts/Meta-Llama-3-8B-Instruct +--- + +# 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.11.1 \ No newline at end of file diff --git a/checkpoint-80/adapter_config.json b/checkpoint-80/adapter_config.json new file mode 100644 index 0000000000000000000000000000000000000000..ad16c073ed8946d227350e8fe4e99d689a8ede54 --- /dev/null +++ b/checkpoint-80/adapter_config.json @@ -0,0 +1,35 @@ +{ + "alpha_pattern": {}, + "auto_mapping": null, + "base_model_name_or_path": "../ckpts/Meta-Llama-3-8B-Instruct", + "bias": "none", + "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": 32, + "lora_dropout": 0.1, + "megatron_config": null, + "megatron_core": "megatron.core", + "modules_to_save": null, + "peft_type": "LORA", + "r": 16, + "rank_pattern": {}, + "revision": null, + "target_modules": [ + "down_proj", + "gate_proj", + "q_proj", + "lm_head", + "o_proj", + "v_proj", + "up_proj", + "k_proj" + ], + "task_type": "CAUSAL_LM", + "use_dora": false, + "use_rslora": false +} \ No newline at end of file diff --git a/checkpoint-80/adapter_model.safetensors b/checkpoint-80/adapter_model.safetensors new file mode 100644 index 0000000000000000000000000000000000000000..e5b220be87d770efa22c9a3bd0b89f8013ff3677 --- /dev/null +++ b/checkpoint-80/adapter_model.safetensors @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:10625511bb4a701e8f8e64bc3f7db95052839ef791bc49bc5a2d6b06919ef7b5 +size 1138856856 diff --git a/checkpoint-80/global_step80/bf16_zero_pp_rank_0_mp_rank_00_optim_states.pt b/checkpoint-80/global_step80/bf16_zero_pp_rank_0_mp_rank_00_optim_states.pt new file mode 100644 index 0000000000000000000000000000000000000000..f20ca11895ff276ee101dec8924bb8886fb5c438 --- /dev/null +++ b/checkpoint-80/global_step80/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:3295f7e9af2a8907fb77c532e880faab2d3a9dcd2339152e00274dc3270d6d6e +size 528781328 diff --git a/checkpoint-80/global_step80/mp_rank_00_model_states.pt b/checkpoint-80/global_step80/mp_rank_00_model_states.pt new file mode 100644 index 0000000000000000000000000000000000000000..4597b6784e892de36b1d03a24211e18025f489da --- /dev/null +++ b/checkpoint-80/global_step80/mp_rank_00_model_states.pt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:40a127a519a4ea92e0fdc77e5cb7af8a1ba57fc56493947402fdaf9ea88074e0 +size 199905337 diff --git a/checkpoint-80/latest b/checkpoint-80/latest new file mode 100644 index 0000000000000000000000000000000000000000..75eab498d0366633484ab40334e4b8fb92b16dad --- /dev/null +++ b/checkpoint-80/latest @@ -0,0 +1 @@ +global_step80 \ No newline at end of file diff --git a/checkpoint-80/rng_state.pth b/checkpoint-80/rng_state.pth new file mode 100644 index 0000000000000000000000000000000000000000..8e517b54bddc9a584fd365a8263b41bc4db34a77 --- /dev/null +++ b/checkpoint-80/rng_state.pth @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3cc159e4a5aac19e6e964e22a137b013ca1c8ce5f2b961284169db4c58ac7f68 +size 14244 diff --git a/checkpoint-80/trainer_state.json b/checkpoint-80/trainer_state.json new file mode 100644 index 0000000000000000000000000000000000000000..15e164c1bb266a4e40a02fdf6b068c5df922b0b9 --- /dev/null +++ b/checkpoint-80/trainer_state.json @@ -0,0 +1,593 @@ +{ + "best_metric": null, + "best_model_checkpoint": null, + "epoch": 0.6826666666666666, + "eval_steps": 500, + "global_step": 80, + "is_hyper_param_search": false, + "is_local_process_zero": true, + "is_world_process_zero": true, + "log_history": [ + { + "epoch": 0.008533333333333334, + "grad_norm": 100.21848203113535, + "learning_rate": 0.0, + "loss": 7.1962, + "step": 1 + }, + { + "epoch": 0.017066666666666667, + "grad_norm": 96.43006188910957, + "learning_rate": 3.0102999566398115e-06, + "loss": 6.9414, + "step": 2 + }, + { + "epoch": 0.0256, + "grad_norm": 97.35803466618715, + "learning_rate": 4.771212547196624e-06, + "loss": 7.0102, + "step": 3 + }, + { + "epoch": 0.034133333333333335, + "grad_norm": 95.14837816372646, + "learning_rate": 6.020599913279623e-06, + "loss": 6.5295, + "step": 4 + }, + { + "epoch": 0.042666666666666665, + "grad_norm": 91.76544275692784, + "learning_rate": 6.989700043360187e-06, + "loss": 6.4806, + "step": 5 + }, + { + "epoch": 0.0512, + "grad_norm": 84.4494318688335, + "learning_rate": 7.781512503836437e-06, + "loss": 6.4194, + "step": 6 + }, + { + "epoch": 0.05973333333333333, + "grad_norm": 71.37977490595638, + "learning_rate": 8.450980400142568e-06, + "loss": 5.4953, + "step": 7 + }, + { + "epoch": 0.06826666666666667, + "grad_norm": 49.31153456754566, + "learning_rate": 9.030899869919434e-06, + "loss": 5.4123, + "step": 8 + }, + { + "epoch": 0.0768, + "grad_norm": 20.37296364560341, + "learning_rate": 9.542425094393249e-06, + "loss": 5.2334, + "step": 9 + }, + { + "epoch": 0.08533333333333333, + "grad_norm": 7.968467079076881, + "learning_rate": 9.999999999999999e-06, + "loss": 5.0282, + "step": 10 + }, + { + "epoch": 0.09386666666666667, + "grad_norm": 3.559446532055649, + "learning_rate": 1.041392685158225e-05, + "loss": 4.612, + "step": 11 + }, + { + "epoch": 0.1024, + "grad_norm": 3.5528846947995674, + "learning_rate": 1.0791812460476248e-05, + "loss": 4.9475, + "step": 12 + }, + { + "epoch": 0.11093333333333333, + "grad_norm": 3.541968897471334, + "learning_rate": 1.1139433523068365e-05, + "loss": 4.2777, + "step": 13 + }, + { + "epoch": 0.11946666666666667, + "grad_norm": 3.54718070036198, + "learning_rate": 1.1461280356782378e-05, + "loss": 4.3507, + "step": 14 + }, + { + "epoch": 0.128, + "grad_norm": 3.8632334830606747, + "learning_rate": 1.1760912590556813e-05, + "loss": 4.5364, + "step": 15 + }, + { + "epoch": 0.13653333333333334, + "grad_norm": 3.6637424744054004, + "learning_rate": 1.2041199826559246e-05, + "loss": 3.9672, + "step": 16 + }, + { + "epoch": 0.14506666666666668, + "grad_norm": 3.919802904818311, + "learning_rate": 1.230448921378274e-05, + "loss": 4.0618, + "step": 17 + }, + { + "epoch": 0.1536, + "grad_norm": 4.71904950738746, + "learning_rate": 1.2552725051033058e-05, + "loss": 4.6656, + "step": 18 + }, + { + "epoch": 0.16213333333333332, + "grad_norm": 4.6656317698690835, + "learning_rate": 1.2787536009528288e-05, + "loss": 4.1131, + "step": 19 + }, + { + "epoch": 0.17066666666666666, + "grad_norm": 5.145138692367417, + "learning_rate": 1.301029995663981e-05, + "loss": 4.0989, + "step": 20 + }, + { + "epoch": 0.1792, + "grad_norm": 5.923538014759818, + "learning_rate": 1.3222192947339192e-05, + "loss": 4.4991, + "step": 21 + }, + { + "epoch": 0.18773333333333334, + "grad_norm": 5.941056962941364, + "learning_rate": 1.3424226808222062e-05, + "loss": 4.0836, + "step": 22 + }, + { + "epoch": 0.19626666666666667, + "grad_norm": 6.171026012117947, + "learning_rate": 1.3617278360175927e-05, + "loss": 3.6861, + "step": 23 + }, + { + "epoch": 0.2048, + "grad_norm": 7.130542138930838, + "learning_rate": 1.380211241711606e-05, + "loss": 4.0958, + "step": 24 + }, + { + "epoch": 0.21333333333333335, + "grad_norm": 7.328837606110418, + "learning_rate": 1.3979400086720374e-05, + "loss": 3.9524, + "step": 25 + }, + { + "epoch": 0.22186666666666666, + "grad_norm": 6.923489005711429, + "learning_rate": 1.4149733479708178e-05, + "loss": 3.6062, + "step": 26 + }, + { + "epoch": 0.2304, + "grad_norm": 6.409498926059221, + "learning_rate": 1.4313637641589872e-05, + "loss": 3.2034, + "step": 27 + }, + { + "epoch": 0.23893333333333333, + "grad_norm": 5.781628405584682, + "learning_rate": 1.4471580313422191e-05, + "loss": 2.8158, + "step": 28 + }, + { + "epoch": 0.24746666666666667, + "grad_norm": 6.2927590068243315, + "learning_rate": 1.4623979978989559e-05, + "loss": 2.9803, + "step": 29 + }, + { + "epoch": 0.256, + "grad_norm": 6.103844678630006, + "learning_rate": 1.4771212547196623e-05, + "loss": 2.847, + "step": 30 + }, + { + "epoch": 0.26453333333333334, + "grad_norm": 7.656341925867144, + "learning_rate": 1.4913616938342726e-05, + "loss": 3.0907, + "step": 31 + }, + { + "epoch": 0.2730666666666667, + "grad_norm": 6.324242877501844, + "learning_rate": 1.5051499783199059e-05, + "loss": 2.3467, + "step": 32 + }, + { + "epoch": 0.2816, + "grad_norm": 7.606313101162739, + "learning_rate": 1.5185139398778874e-05, + "loss": 2.5292, + "step": 33 + }, + { + "epoch": 0.29013333333333335, + "grad_norm": 8.553792493849265, + "learning_rate": 1.531478917042255e-05, + "loss": 2.4547, + "step": 34 + }, + { + "epoch": 0.2986666666666667, + "grad_norm": 8.483368703272543, + "learning_rate": 1.5440680443502753e-05, + "loss": 2.1956, + "step": 35 + }, + { + "epoch": 0.3072, + "grad_norm": 8.364739352838077, + "learning_rate": 1.5563025007672873e-05, + "loss": 1.8552, + "step": 36 + }, + { + "epoch": 0.3157333333333333, + "grad_norm": 9.37663682000104, + "learning_rate": 1.5682017240669948e-05, + "loss": 1.9228, + "step": 37 + }, + { + "epoch": 0.32426666666666665, + "grad_norm": 9.823047193440066, + "learning_rate": 1.57978359661681e-05, + "loss": 1.7033, + "step": 38 + }, + { + "epoch": 0.3328, + "grad_norm": 9.692618512955894, + "learning_rate": 1.591064607026499e-05, + "loss": 1.3768, + "step": 39 + }, + { + "epoch": 0.3413333333333333, + "grad_norm": 9.08889021911031, + "learning_rate": 1.6020599913279622e-05, + "loss": 1.3015, + "step": 40 + }, + { + "epoch": 0.34986666666666666, + "grad_norm": 8.081534221516058, + "learning_rate": 1.6127838567197353e-05, + "loss": 0.9228, + "step": 41 + }, + { + "epoch": 0.3584, + "grad_norm": 6.238638048950311, + "learning_rate": 1.6232492903979005e-05, + "loss": 0.7267, + "step": 42 + }, + { + "epoch": 0.36693333333333333, + "grad_norm": 3.4058036861773604, + "learning_rate": 1.6334684555795865e-05, + "loss": 0.5875, + "step": 43 + }, + { + "epoch": 0.37546666666666667, + "grad_norm": 2.079163829467713, + "learning_rate": 1.6434526764861872e-05, + "loss": 0.6355, + "step": 44 + }, + { + "epoch": 0.384, + "grad_norm": 1.5597487833024746, + "learning_rate": 1.6532125137753435e-05, + "loss": 0.5106, + "step": 45 + }, + { + "epoch": 0.39253333333333335, + "grad_norm": 2.491689602375256, + "learning_rate": 1.662757831681574e-05, + "loss": 0.6454, + "step": 46 + }, + { + "epoch": 0.4010666666666667, + "grad_norm": 2.010880438195854, + "learning_rate": 1.672097857935717e-05, + "loss": 0.4757, + "step": 47 + }, + { + "epoch": 0.4096, + "grad_norm": 1.9452805114322096, + "learning_rate": 1.681241237375587e-05, + "loss": 0.4133, + "step": 48 + }, + { + "epoch": 0.41813333333333336, + "grad_norm": 1.7620848552306103, + "learning_rate": 1.6901960800285137e-05, + "loss": 0.4004, + "step": 49 + }, + { + "epoch": 0.4266666666666667, + "grad_norm": 1.278224489774809, + "learning_rate": 1.6989700043360187e-05, + "loss": 0.3523, + "step": 50 + }, + { + "epoch": 0.4352, + "grad_norm": 1.6151354758303231, + "learning_rate": 1.7075701760979363e-05, + "loss": 0.4317, + "step": 51 + }, + { + "epoch": 0.4437333333333333, + "grad_norm": 1.3451396055695035, + "learning_rate": 1.716003343634799e-05, + "loss": 0.3474, + "step": 52 + }, + { + "epoch": 0.45226666666666665, + "grad_norm": 1.6814977782362666, + "learning_rate": 1.724275869600789e-05, + "loss": 0.3706, + "step": 53 + }, + { + "epoch": 0.4608, + "grad_norm": 1.1682442432688667, + "learning_rate": 1.7323937598229687e-05, + "loss": 0.3488, + "step": 54 + }, + { + "epoch": 0.4693333333333333, + "grad_norm": 0.8839814540462471, + "learning_rate": 1.7403626894942437e-05, + "loss": 0.293, + "step": 55 + }, + { + "epoch": 0.47786666666666666, + "grad_norm": 0.7974304806295485, + "learning_rate": 1.7481880270062003e-05, + "loss": 0.2717, + "step": 56 + }, + { + "epoch": 0.4864, + "grad_norm": 0.6232203657585239, + "learning_rate": 1.7558748556724913e-05, + "loss": 0.1741, + "step": 57 + }, + { + "epoch": 0.49493333333333334, + "grad_norm": 0.6850688604563008, + "learning_rate": 1.763427993562937e-05, + "loss": 0.228, + "step": 58 + }, + { + "epoch": 0.5034666666666666, + "grad_norm": 0.5923826384300431, + "learning_rate": 1.7708520116421443e-05, + "loss": 0.2131, + "step": 59 + }, + { + "epoch": 0.512, + "grad_norm": 0.489754430485032, + "learning_rate": 1.7781512503836432e-05, + "loss": 0.165, + "step": 60 + }, + { + "epoch": 0.5205333333333333, + "grad_norm": 0.5280940052395061, + "learning_rate": 1.7853298350107667e-05, + "loss": 0.1658, + "step": 61 + }, + { + "epoch": 0.5290666666666667, + "grad_norm": 0.4750905992036739, + "learning_rate": 1.7923916894982537e-05, + "loss": 0.1438, + "step": 62 + }, + { + "epoch": 0.5376, + "grad_norm": 0.4162998392722401, + "learning_rate": 1.7993405494535815e-05, + "loss": 0.1555, + "step": 63 + }, + { + "epoch": 0.5461333333333334, + "grad_norm": 0.26863266246370443, + "learning_rate": 1.806179973983887e-05, + "loss": 0.1323, + "step": 64 + }, + { + "epoch": 0.5546666666666666, + "grad_norm": 0.26534221125601215, + "learning_rate": 1.8129133566428553e-05, + "loss": 0.1671, + "step": 65 + }, + { + "epoch": 0.5632, + "grad_norm": 0.2548662962257576, + "learning_rate": 1.8195439355418686e-05, + "loss": 0.1308, + "step": 66 + }, + { + "epoch": 0.5717333333333333, + "grad_norm": 0.18045394638578796, + "learning_rate": 1.8260748027008263e-05, + "loss": 0.1262, + "step": 67 + }, + { + "epoch": 0.5802666666666667, + "grad_norm": 0.17070388073612064, + "learning_rate": 1.8325089127062364e-05, + "loss": 0.1192, + "step": 68 + }, + { + "epoch": 0.5888, + "grad_norm": 0.1531381679244776, + "learning_rate": 1.8388490907372553e-05, + "loss": 0.1274, + "step": 69 + }, + { + "epoch": 0.5973333333333334, + "grad_norm": 0.18196434993687946, + "learning_rate": 1.8450980400142568e-05, + "loss": 0.1375, + "step": 70 + }, + { + "epoch": 0.6058666666666667, + "grad_norm": 0.15324416972951205, + "learning_rate": 1.8512583487190752e-05, + "loss": 0.1599, + "step": 71 + }, + { + "epoch": 0.6144, + "grad_norm": 0.10884462064503801, + "learning_rate": 1.857332496431268e-05, + "loss": 0.1041, + "step": 72 + }, + { + "epoch": 0.6229333333333333, + "grad_norm": 0.12915133528192668, + "learning_rate": 1.8633228601204555e-05, + "loss": 0.1406, + "step": 73 + }, + { + "epoch": 0.6314666666666666, + "grad_norm": 0.12553425699952878, + "learning_rate": 1.8692317197309763e-05, + "loss": 0.1256, + "step": 74 + }, + { + "epoch": 0.64, + "grad_norm": 0.11976960918968543, + "learning_rate": 1.8750612633916997e-05, + "loss": 0.1144, + "step": 75 + }, + { + "epoch": 0.6485333333333333, + "grad_norm": 0.115805998298789, + "learning_rate": 1.8808135922807914e-05, + "loss": 0.1528, + "step": 76 + }, + { + "epoch": 0.6570666666666667, + "grad_norm": 0.10325948496697443, + "learning_rate": 1.8864907251724818e-05, + "loss": 0.1044, + "step": 77 + }, + { + "epoch": 0.6656, + "grad_norm": 0.09595064346541006, + "learning_rate": 1.8920946026904802e-05, + "loss": 0.1534, + "step": 78 + }, + { + "epoch": 0.6741333333333334, + "grad_norm": 0.08796742845240496, + "learning_rate": 1.8976270912904414e-05, + "loss": 0.1155, + "step": 79 + }, + { + "epoch": 0.6826666666666666, + "grad_norm": 0.08218991738379527, + "learning_rate": 1.9030899869919434e-05, + "loss": 0.1311, + "step": 80 + } + ], + "logging_steps": 1, + "max_steps": 351, + "num_input_tokens_seen": 0, + "num_train_epochs": 3, + "save_steps": 20, + "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.1373018660449812e+18, + "train_batch_size": 16, + "trial_name": null, + "trial_params": null +} diff --git a/checkpoint-80/training_args.bin b/checkpoint-80/training_args.bin new file mode 100644 index 0000000000000000000000000000000000000000..8ac842d29fc6ad3e132cb7208dda5b61dd1079ee --- /dev/null +++ b/checkpoint-80/training_args.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:aa4edad1da5557fcd52a6da980443588016cead6f0444a3562cfa68029c66a04 +size 6840 diff --git a/checkpoint-80/zero_to_fp32.py b/checkpoint-80/zero_to_fp32.py new file mode 100644 index 0000000000000000000000000000000000000000..49b846633d6eb1e836e34681e44033581f4edb7b --- /dev/null +++ b/checkpoint-80/zero_to_fp32.py @@ -0,0 +1,592 @@ +#!/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 . pytorch_model.bin + +import argparse +import torch +import glob +import math +import os +import re +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) + + +@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 parse_model_states(files): + zero_model_states = [] + for file in files: + state_dict = torch.load(file, map_location=device) + + 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 files: + state_dict = torch.load(f, map_location=device) + # 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 not ZERO_STAGE 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}") + + if zero_stage <= 2: + fp32_flat_groups = [state_dicts[i][OPTIMIZER_STATE_DICT][fp32_groups_key] for i in range(len(state_dicts))] + elif zero_stage == 3: + # if there is more than one param group, there will be multiple flattened tensors - one + # flattened tensor per group - for simplicity merge them into a single tensor + # + # XXX: could make the script more memory efficient for when there are multiple groups - it + # will require matching the sub-lists of param_shapes for each param group flattened tensor + + fp32_flat_groups = [ + torch.cat(state_dicts[i][OPTIMIZER_STATE_DICT][fp32_groups_key], 0) 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): + """ + 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}'") + + 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}") + + 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}') + + if zero_stage <= 2: + return _get_fp32_state_dict_from_zero2_checkpoint(world_size, fp32_flat_groups, zero_model_states) + elif zero_stage == 3: + return _get_fp32_state_dict_from_zero3_checkpoint(world_size, fp32_flat_groups, zero_model_states) + + +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): + state_dict = OrderedDict() + + # buffers + buffers = zero_model_states[0].buffers + state_dict.update(buffers) + if debug: + print(f"added {len(buffers)} buffers") + + _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") + + +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 = fp32_flat_groups[0].numel() * 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 + for name, shape in param_shapes.items(): + + 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}" + ) + + # XXX: memory usage doubles here + state_dict[name] = torch.cat( + tuple(fp32_flat_groups[i].narrow(0, offset, partitioned_numel) for i in range(world_size)), + 0).narrow(0, 0, unpartitioned_numel).view(shape) + 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): + state_dict = OrderedDict() + + # buffers + buffers = zero_model_states[0].buffers + state_dict.update(buffers) + if debug: + print(f"added {len(buffers)} buffers") + + _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 get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir, tag=None): + """ + 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`` + + Returns: + - pytorch ``state_dict`` + + Note: this approach may not work if your application doesn't have sufficient free CPU memory and + you may need to use the offline approach using the ``zero_to_fp32.py`` script that is saved with + the checkpoint. + + 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. + + """ + 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") + + return _get_fp32_state_dict_from_zero_checkpoint(ds_checkpoint_dir) + + +def convert_zero_checkpoint_to_fp32_state_dict(checkpoint_dir, output_file, tag=None): + """ + 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_file``: path to the pytorch fp32 state_dict output file (e.g. path/pytorch_model.bin) + - ``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`` + """ + + state_dict = get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir, tag) + print(f"Saving fp32 state dict to {output_file}") + torch.save(state_dict, output_file) + + +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(f"Extracting fp32 weights") + state_dict = get_fp32_state_dict_from_zero_checkpoint(checkpoint_dir, tag) + + logger.info(f"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_file", + type=str, + help="path to the pytorch fp32 state_dict output file (e.g. path/checkpoint-12/pytorch_model.bin)") + 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("-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_file, tag=args.tag) diff --git a/config.yaml b/config.yaml new file mode 100644 index 0000000000000000000000000000000000000000..e10622613c4b9b525db646e9c45db6eda2d898bf --- /dev/null +++ b/config.yaml @@ -0,0 +1,74 @@ +data: + prompt: llama3_formal + train: ../data/susgen/FINAL/PER_3500/FINAL_PER3500_30k.json + val: null + val_split_ratio: 0.005 +device: cuda +instruct_mask: true +local_rank: 0 +model: + acceleration: null + int4_config: + bnb_4bit_compute_dtype: bfloat16 + bnb_4bit_quant_type: nf4 + bnb_4bit_use_double_quant: true + load_in_4bit: true + load_in_8bit: false + int8_config: + load_in_4bit: false + load_in_8bit: true + lora: + bias: none + inference_mode: false + lora_alpha: 32 + lora_dropout: 0.1 + r: 16 + target_modules: + - q_proj + - k_proj + - v_proj + - o_proj + - gate_proj + - up_proj + - down_proj + - lm_head + task_type: CAUSAL_LM + lora_path: false + model_path: ../ckpts/Meta-Llama-3-8B-Instruct + quantization: int4 + seed: 2024 + show_config: false + use_lora: true +name: 30k-Llama3-8B-Instruct +output_dir: ../results/ +tokenizer: + add_bos_token: true + add_eos_token: false + add_prefix_space: false + encode: + max_length: 2048 + return_tensors: pt + truncation: true + model_max_length: 2048 + padding_side: left + pretrained_model_name_or_path: ../ckpts/Meta-Llama-3-8B-Instruct + truncation_side: right + use_fast: true +trainer: NewTrainer +training: + bf16: true + deepspeed: ./configs/ds_configs/ds_config_stage_2.json + gradient_accumulation_steps: 16 + learning_rate: 2.0e-05 + logging_steps: 1 + lr_scheduler_type: cosine + num_train_epochs: 3 + optim: paged_adamw_32bit + per_device_train_batch_size: 16 + remove_unused_columns: false + report_to: wandb + resume_from_checkpoint: null + save_steps: 20 + save_strategy: steps + warmup_steps: 100 + weight_decay: 0.01