From 93ec62b9d3fdcb9c9eafc08e1bd0530cb53aa929 Mon Sep 17 00:00:00 2001 From: diaoshizhe <654745845@qq.com> Date: Mon, 27 Mar 2023 23:28:32 +0800 Subject: [PATCH] initial release --- .github/workflows/documentation.yaml | 35 ++ .gitignore | 180 +++++++ LICENSE | 201 ++++++++ README.md | 266 +++++++++++ assets/features.png | Bin 0 -> 397394 bytes assets/logo.png | Bin 0 -> 139180 bytes configs/ds_config_zero2.json | 45 ++ configs/ds_config_zero3.json | 52 ++ docs/requirements.txt | 5 + docs/source/_static/IT_sample1.png | Bin 0 -> 523440 bytes docs/source/_static/IT_sample2.png | Bin 0 -> 282807 bytes docs/source/_static/IT_sample3.png | Bin 0 -> 400679 bytes docs/source/_static/IT_sample4.png | Bin 0 -> 334618 bytes docs/source/_static/IT_sample5.png | Bin 0 -> 632293 bytes docs/source/_static/IT_sample6.png | Bin 0 -> 365253 bytes docs/source/_static/IT_sample7.png | Bin 0 -> 578291 bytes .../check_before_after_lora_tuning.jsonl | 252 ++++++++++ docs/source/_static/logo.png | Bin 0 -> 139180 bytes docs/source/_static/logo.svg | 1 + docs/source/_static/logo2.svg | 1 + docs/source/_static/logo3.svg | 1 + docs/source/_static/logo4.svg | 1 + docs/source/_static/logo5.svg | 1 + docs/source/_static/logo6.svg | 1 + docs/source/about/authors.md | 4 + docs/source/about/changelog.md | 15 + docs/source/about/index.md | 15 + docs/source/api/_autosummary/lmflow.args.rst | 32 ++ docs/source/conf.py | 74 +++ docs/source/documentation/data.md | 1 + docs/source/documentation/index.md | 37 ++ docs/source/documentation/infer.md | 1 + docs/source/documentation/model.md | 1 + docs/source/documentation/tuning.md | 1 + docs/source/examples/DATASETS.md | 111 +++++ docs/source/examples/index.md | 23 + docs/source/examples/medical_finetune.md | 55 +++ docs/source/index.md | 185 +++++++ examples/ds_config.json | 12 + examples/finetune.py | 70 +++ examples/inference.py | 42 ++ .../download_finetune_regression_test.sh | 8 + .../commit.txt | 1 + .../compare.sh | 1 + .../cuda_version.txt | 1 + .../ds_config_zero2.json | 54 +++ .../gpu_type.txt | 1 + .../new_test-finetune-00001_gpt2-example.sh | 43 ++ .../nvcc_version.txt | 5 + .../pip_list.txt | 98 ++++ .../server.txt | 1 + .../test-finetune-00001_gpt2-example.sh | 50 ++ .../uname_-a.txt | 1 + .../ds_config_zero2.json | 54 +++ ...new_test-finetune-00002-from-00001_fp16.sh | 43 ++ .../ds_config_zero2.json | 54 +++ ...inetune-00003-from-00001_full-precision.sh | 42 ++ ...inetune-00003-from-00001_full-precision.sh | 49 ++ .../ds_config_zero2.json | 54 +++ ...est-finetune-00004-from-00001_larger-lr.sh | 43 ++ ...est-finetune-00004-from-00001_larger-lr.sh | 50 ++ .../ds_config_zero2.json | 54 +++ ...st-finetune-00005-from-00001_default-lr.sh | 42 ++ ...st-finetune-00005-from-00001_default-lr.sh | 49 ++ .../ds_config_zero2.json | 54 +++ ...test-finetune-00006-from-00001_multigpu.sh | 43 ++ ...test-finetune-00006-from-00001_multigpu.sh | 50 ++ .../ds_config_zero2.json | 54 +++ ...netune-00007-from-00001_longer-training.sh | 43 ++ ...netune-00007-from-00001_longer-training.sh | 50 ++ .../ds_config_zero2.json | 54 +++ ...st-finetune-00008-from-00001_gpt2-large.sh | 43 ++ ...st-finetune-00008-from-00001_gpt2-large.sh | 50 ++ .../comparison.sh | 2 + .../input_new.json | 0 .../input_old.json | 10 + ...ew_test_galactica1.3b_gsm8k_4gpu_max100.sh | 1 + .../old_comparison.sh | 10 + .../output_old.json | 12 + .../sys_info/commit.txt | 1 + .../sys_info/cuda_version.txt | 1 + .../sys_info/gpu_type.txt | 1 + .../sys_info/nvcc_version.txt | 5 + .../sys_info/pip_list.txt | 419 ++++++++++++++++ .../sys_info/server.txt | 1 + .../sys_info/uname_-a.txt | 1 + .../comparison.sh | 2 + .../input_new.json | 45 ++ .../input_old.json | 92 ++++ ..._test_galactica1.3b_medmcqa_4gpu_max100.sh | 1 + .../old_comparison.sh | 10 + .../output_old.json | 12 + .../comparison.sh | 2 + .../input_new.json | 45 ++ .../input_old.json | 72 +++ ...test_galactica1.3b_pubmedqa_4gpu_max100.sh | 1 + .../old_comparison.sh | 10 + .../output_old.json | 12 + .../comparison.sh | 2 + .../input_new.json | 45 ++ .../input_old.json | 82 ++++ ...ew_test_galactica1.3b_usmle_4gpu_max100.sh | 1 + .../old_comparison.sh | 10 + .../output_old.json | 12 + .../test_gpt2_gsm8k_4gpu_max100/comparison.sh | 2 + .../input_new.json | 0 .../input_old.json | 10 + .../new_test_gpt2_gsm8k_4gpu_max100.sh | 1 + .../old_comparison.sh | 10 + .../output_old.json | 12 + .../comparison.sh | 2 + .../input_new.json | 45 ++ .../input_old.json | 92 ++++ .../new_test_gpt2_medmcqa_1gpu_max100.sh | 1 + .../old_comparison.sh | 10 + .../output_old.json | 10 + .../comparison.sh | 2 + .../input_new.json | 45 ++ .../input_old.json | 92 ++++ .../new_test_gpt2_medmcqa_1gpu_max25.sh | 1 + .../old_comparison.sh | 10 + .../output_old.json | 10 + .../comparison.sh | 2 + .../input_new.json | 45 ++ .../input_old.json | 92 ++++ .../new_test_gpt2_medmcqa_2gpu_max100.sh | 1 + .../old_comparison.sh | 10 + .../output_old.json | 10 + .../comparison.sh | 2 + .../input_new.json | 45 ++ .../input_old.json | 92 ++++ .../new_test_gpt2_medmcqa_2gpu_max25.sh | 1 + .../old_comparison.sh | 10 + .../output_old.json | 10 + .../comparison.sh | 2 + .../input_new.json | 45 ++ .../input_old.json | 92 ++++ .../new_test_gpt2_medmcqa_2gpu_max50.sh | 1 + .../old_comparison.sh | 10 + .../output_old.json | 10 + .../comparison.sh | 2 + .../input_new.json | 45 ++ .../input_old.json | 92 ++++ .../new_test_gpt2_medmcqa_4gpu_max100.sh | 1 + .../old_comparison.sh | 10 + .../output_old.json | 12 + .../comparison.sh | 2 + .../input_new.json | 45 ++ .../input_old.json | 72 +++ .../new_test_gpt2_pubmedqa_4gpu_max100.sh | 1 + .../old_comparison.sh | 10 + .../output_old.json | 12 + .../test_gpt2_usmle_4gpu_max100/comparison.sh | 2 + .../input_new.json | 45 ++ .../input_old.json | 82 ++++ .../new_test_gpt2_usmle_4gpu_max100.sh | 1 + .../old_comparison.sh | 10 + .../output_old.json | 12 + .../comparison.sh | 2 + .../input_new.json | 0 .../input_old.json | 10 + .../new_test_gpt2l_gsm8k_4gpu_max100.sh | 1 + .../old_comparison.sh | 10 + .../output_old.json | 12 + .../comparison.sh | 2 + .../input_new.json | 45 ++ .../input_old.json | 92 ++++ .../new_test_gpt2l_medmcqa_4gpu_max100.sh | 1 + .../old_comparison.sh | 10 + .../output_old.json | 12 + .../comparison.sh | 2 + .../input_new.json | 45 ++ .../input_old.json | 72 +++ .../new_test_gpt2l_pubmedqa_4gpu_max100.sh | 1 + .../old_comparison.sh | 10 + .../output_old.json | 12 + .../comparison.sh | 2 + .../input_new.json | 45 ++ .../input_old.json | 82 ++++ .../new_test_gpt2l_usmle_4gpu_max100.sh | 1 + .../old_comparison.sh | 10 + .../output_old.json | 12 + .../comparison.sh | 2 + .../input_new.json | 0 .../input_old.json | 10 + .../new_test_gpt2m_gsm8k_4gpu_max100.sh | 1 + .../old_comparison.sh | 10 + .../output_old.json | 12 + .../comparison.sh | 2 + .../input_new.json | 45 ++ .../input_old.json | 92 ++++ .../new_test_gpt2m_medmcqa_4gpu_max100.sh | 1 + .../old_comparison.sh | 10 + .../output_old.json | 12 + .../comparison.sh | 2 + .../input_new.json | 45 ++ .../input_old.json | 72 +++ .../new_test_gpt2m_pubmedqa_4gpu_max100.sh | 1 + .../old_comparison.sh | 10 + .../output_old.json | 12 + .../comparison.sh | 2 + .../input_new.json | 45 ++ .../input_old.json | 82 ++++ .../new_test_gpt2m_usmle_4gpu_max100.sh | 1 + .../old_comparison.sh | 10 + .../output_old.json | 12 + requirements.txt | 22 + scripts/bash.sh | 3 + scripts/convert_llama_weights_to_hf.py | 279 +++++++++++ scripts/run_finetune.sh | 39 ++ scripts/run_finetune_with_lora.sh | 41 ++ scripts/run_inference.sh | 9 + scripts/run_inference_with_lora.sh | 13 + scripts/run_regression_test.sh | 43 ++ scripts/run_unittest.sh | 3 + setup.py | 44 ++ src/lmflow/__init__.py | 13 + src/lmflow/args.py | 451 ++++++++++++++++++ src/lmflow/datasets/__init__.py | 6 + src/lmflow/datasets/dataset.py | 205 ++++++++ src/lmflow/models/__init__.py | 0 src/lmflow/models/auto_model.py | 14 + src/lmflow/models/base_model.py | 12 + src/lmflow/models/decoder_model.py | 22 + src/lmflow/models/hf_decoder_model.py | 371 ++++++++++++++ src/lmflow/models/interfaces/__init__.py | 0 src/lmflow/models/interfaces/tunable.py | 10 + src/lmflow/pipeline/__init__.py | 0 src/lmflow/pipeline/auto_pipeline.py | 41 ++ src/lmflow/pipeline/base_pipeline.py | 9 + src/lmflow/pipeline/base_tuner.py | 20 + src/lmflow/pipeline/finetuner.py | 264 ++++++++++ src/lmflow/pipeline/inferencer.py | 185 +++++++ src/lmflow/utils/__init__.py | 0 src/lmflow/utils/data_utils.py | 212 ++++++++ src/lmflow/version.py | 1 + tests/__init__.py | 0 tests/datasets/__init__.py | 0 tests/datasets/test_dataset.py | 39 ++ tests/models/__init__.py | 0 tests/models/test_hf_decoder_model.py | 108 +++++ tests/utils/__init__.py | 1 + tests/utils/test_data_utils.py | 87 ++++ 243 files changed, 8720 insertions(+) create mode 100644 .github/workflows/documentation.yaml create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 README.md create mode 100644 assets/features.png create mode 100644 assets/logo.png create mode 100644 configs/ds_config_zero2.json create mode 100644 configs/ds_config_zero3.json create mode 100644 docs/requirements.txt create mode 100644 docs/source/_static/IT_sample1.png create mode 100644 docs/source/_static/IT_sample2.png create mode 100644 docs/source/_static/IT_sample3.png create mode 100644 docs/source/_static/IT_sample4.png create mode 100644 docs/source/_static/IT_sample5.png create mode 100644 docs/source/_static/IT_sample6.png create mode 100644 docs/source/_static/IT_sample7.png create mode 100644 docs/source/_static/check_before_after_lora_tuning.jsonl create mode 100644 docs/source/_static/logo.png create mode 100644 docs/source/_static/logo.svg create mode 100644 docs/source/_static/logo2.svg create mode 100644 docs/source/_static/logo3.svg create mode 100644 docs/source/_static/logo4.svg create mode 100644 docs/source/_static/logo5.svg create mode 100644 docs/source/_static/logo6.svg create mode 100644 docs/source/about/authors.md create mode 100644 docs/source/about/changelog.md create mode 100644 docs/source/about/index.md create mode 100644 docs/source/api/_autosummary/lmflow.args.rst create mode 100644 docs/source/conf.py create mode 100644 docs/source/documentation/data.md create mode 100644 docs/source/documentation/index.md create mode 100644 docs/source/documentation/infer.md create mode 100644 docs/source/documentation/model.md create mode 100644 docs/source/documentation/tuning.md create mode 100644 docs/source/examples/DATASETS.md create mode 100644 docs/source/examples/index.md create mode 100644 docs/source/examples/medical_finetune.md create mode 100644 docs/source/index.md create mode 100644 examples/ds_config.json create mode 100644 examples/finetune.py create mode 100644 examples/inference.py create mode 100644 regression_test/download_finetune_regression_test.sh create mode 100644 regression_test/test-finetune-00001_gpt2-example/commit.txt create mode 100644 regression_test/test-finetune-00001_gpt2-example/compare.sh create mode 100644 regression_test/test-finetune-00001_gpt2-example/cuda_version.txt create mode 100644 regression_test/test-finetune-00001_gpt2-example/ds_config_zero2.json create mode 100644 regression_test/test-finetune-00001_gpt2-example/gpu_type.txt create mode 100755 regression_test/test-finetune-00001_gpt2-example/new_test-finetune-00001_gpt2-example.sh create mode 100644 regression_test/test-finetune-00001_gpt2-example/nvcc_version.txt create mode 100644 regression_test/test-finetune-00001_gpt2-example/pip_list.txt create mode 100644 regression_test/test-finetune-00001_gpt2-example/server.txt create mode 100755 regression_test/test-finetune-00001_gpt2-example/test-finetune-00001_gpt2-example.sh create mode 100644 regression_test/test-finetune-00001_gpt2-example/uname_-a.txt create mode 100644 regression_test/test-finetune-00002-from-00001_fp16/ds_config_zero2.json create mode 100755 regression_test/test-finetune-00002-from-00001_fp16/new_test-finetune-00002-from-00001_fp16.sh create mode 100644 regression_test/test-finetune-00003-from-00001_full-precision/ds_config_zero2.json create mode 100755 regression_test/test-finetune-00003-from-00001_full-precision/new_test-finetune-00003-from-00001_full-precision.sh create mode 100755 regression_test/test-finetune-00003-from-00001_full-precision/test-finetune-00003-from-00001_full-precision.sh create mode 100644 regression_test/test-finetune-00004-from-00001_larger-lr/ds_config_zero2.json create mode 100755 regression_test/test-finetune-00004-from-00001_larger-lr/new_test-finetune-00004-from-00001_larger-lr.sh create mode 100755 regression_test/test-finetune-00004-from-00001_larger-lr/test-finetune-00004-from-00001_larger-lr.sh create mode 100644 regression_test/test-finetune-00005-from-00001_default-lr/ds_config_zero2.json create mode 100755 regression_test/test-finetune-00005-from-00001_default-lr/new_test-finetune-00005-from-00001_default-lr.sh create mode 100755 regression_test/test-finetune-00005-from-00001_default-lr/test-finetune-00005-from-00001_default-lr.sh create mode 100644 regression_test/test-finetune-00006-from-00001_multigpu/ds_config_zero2.json create mode 100755 regression_test/test-finetune-00006-from-00001_multigpu/new_test-finetune-00006-from-00001_multigpu.sh create mode 100755 regression_test/test-finetune-00006-from-00001_multigpu/test-finetune-00006-from-00001_multigpu.sh create mode 100644 regression_test/test-finetune-00007-from-00001_longer-training/ds_config_zero2.json create mode 100755 regression_test/test-finetune-00007-from-00001_longer-training/new_test-finetune-00007-from-00001_longer-training.sh create mode 100755 regression_test/test-finetune-00007-from-00001_longer-training/test-finetune-00007-from-00001_longer-training.sh create mode 100644 regression_test/test-finetune-00008-from-00001_gpt2-large/ds_config_zero2.json create mode 100755 regression_test/test-finetune-00008-from-00001_gpt2-large/new_test-finetune-00008-from-00001_gpt2-large.sh create mode 100755 regression_test/test-finetune-00008-from-00001_gpt2-large/test-finetune-00008-from-00001_gpt2-large.sh create mode 100644 regression_test/test_galactica1.3b_gsm8k_4gpu_max100/comparison.sh create mode 100644 regression_test/test_galactica1.3b_gsm8k_4gpu_max100/input_new.json create mode 100644 regression_test/test_galactica1.3b_gsm8k_4gpu_max100/input_old.json create mode 120000 regression_test/test_galactica1.3b_gsm8k_4gpu_max100/new_test_galactica1.3b_gsm8k_4gpu_max100.sh create mode 100755 regression_test/test_galactica1.3b_gsm8k_4gpu_max100/old_comparison.sh create mode 100644 regression_test/test_galactica1.3b_gsm8k_4gpu_max100/output_old.json create mode 100644 regression_test/test_galactica1.3b_gsm8k_4gpu_max100/sys_info/commit.txt create mode 100644 regression_test/test_galactica1.3b_gsm8k_4gpu_max100/sys_info/cuda_version.txt create mode 100644 regression_test/test_galactica1.3b_gsm8k_4gpu_max100/sys_info/gpu_type.txt create mode 100644 regression_test/test_galactica1.3b_gsm8k_4gpu_max100/sys_info/nvcc_version.txt create mode 100644 regression_test/test_galactica1.3b_gsm8k_4gpu_max100/sys_info/pip_list.txt create mode 100644 regression_test/test_galactica1.3b_gsm8k_4gpu_max100/sys_info/server.txt create mode 100644 regression_test/test_galactica1.3b_gsm8k_4gpu_max100/sys_info/uname_-a.txt create mode 100644 regression_test/test_galactica1.3b_medmcqa_4gpu_max100/comparison.sh create mode 100644 regression_test/test_galactica1.3b_medmcqa_4gpu_max100/input_new.json create mode 100644 regression_test/test_galactica1.3b_medmcqa_4gpu_max100/input_old.json create mode 120000 regression_test/test_galactica1.3b_medmcqa_4gpu_max100/new_test_galactica1.3b_medmcqa_4gpu_max100.sh create mode 100755 regression_test/test_galactica1.3b_medmcqa_4gpu_max100/old_comparison.sh create mode 100644 regression_test/test_galactica1.3b_medmcqa_4gpu_max100/output_old.json create mode 100644 regression_test/test_galactica1.3b_pubmedqa_4gpu_max100/comparison.sh create mode 100644 regression_test/test_galactica1.3b_pubmedqa_4gpu_max100/input_new.json create mode 100644 regression_test/test_galactica1.3b_pubmedqa_4gpu_max100/input_old.json create mode 120000 regression_test/test_galactica1.3b_pubmedqa_4gpu_max100/new_test_galactica1.3b_pubmedqa_4gpu_max100.sh create mode 100755 regression_test/test_galactica1.3b_pubmedqa_4gpu_max100/old_comparison.sh create mode 100644 regression_test/test_galactica1.3b_pubmedqa_4gpu_max100/output_old.json create mode 100644 regression_test/test_galactica1.3b_usmle_4gpu_max100/comparison.sh create mode 100644 regression_test/test_galactica1.3b_usmle_4gpu_max100/input_new.json create mode 100644 regression_test/test_galactica1.3b_usmle_4gpu_max100/input_old.json create mode 120000 regression_test/test_galactica1.3b_usmle_4gpu_max100/new_test_galactica1.3b_usmle_4gpu_max100.sh create mode 100755 regression_test/test_galactica1.3b_usmle_4gpu_max100/old_comparison.sh create mode 100644 regression_test/test_galactica1.3b_usmle_4gpu_max100/output_old.json create mode 100644 regression_test/test_gpt2_gsm8k_4gpu_max100/comparison.sh create mode 100644 regression_test/test_gpt2_gsm8k_4gpu_max100/input_new.json create mode 100644 regression_test/test_gpt2_gsm8k_4gpu_max100/input_old.json create mode 120000 regression_test/test_gpt2_gsm8k_4gpu_max100/new_test_gpt2_gsm8k_4gpu_max100.sh create mode 100755 regression_test/test_gpt2_gsm8k_4gpu_max100/old_comparison.sh create mode 100644 regression_test/test_gpt2_gsm8k_4gpu_max100/output_old.json create mode 100644 regression_test/test_gpt2_medmcqa_1gpu_max100/comparison.sh create mode 100644 regression_test/test_gpt2_medmcqa_1gpu_max100/input_new.json create mode 100644 regression_test/test_gpt2_medmcqa_1gpu_max100/input_old.json create mode 120000 regression_test/test_gpt2_medmcqa_1gpu_max100/new_test_gpt2_medmcqa_1gpu_max100.sh create mode 100755 regression_test/test_gpt2_medmcqa_1gpu_max100/old_comparison.sh create mode 100644 regression_test/test_gpt2_medmcqa_1gpu_max100/output_old.json create mode 100644 regression_test/test_gpt2_medmcqa_1gpu_max25/comparison.sh create mode 100644 regression_test/test_gpt2_medmcqa_1gpu_max25/input_new.json create mode 100644 regression_test/test_gpt2_medmcqa_1gpu_max25/input_old.json create mode 120000 regression_test/test_gpt2_medmcqa_1gpu_max25/new_test_gpt2_medmcqa_1gpu_max25.sh create mode 100755 regression_test/test_gpt2_medmcqa_1gpu_max25/old_comparison.sh create mode 100644 regression_test/test_gpt2_medmcqa_1gpu_max25/output_old.json create mode 100644 regression_test/test_gpt2_medmcqa_2gpu_max100/comparison.sh create mode 100644 regression_test/test_gpt2_medmcqa_2gpu_max100/input_new.json create mode 100644 regression_test/test_gpt2_medmcqa_2gpu_max100/input_old.json create mode 120000 regression_test/test_gpt2_medmcqa_2gpu_max100/new_test_gpt2_medmcqa_2gpu_max100.sh create mode 100755 regression_test/test_gpt2_medmcqa_2gpu_max100/old_comparison.sh create mode 100644 regression_test/test_gpt2_medmcqa_2gpu_max100/output_old.json create mode 100644 regression_test/test_gpt2_medmcqa_2gpu_max25/comparison.sh create mode 100644 regression_test/test_gpt2_medmcqa_2gpu_max25/input_new.json create mode 100644 regression_test/test_gpt2_medmcqa_2gpu_max25/input_old.json create mode 120000 regression_test/test_gpt2_medmcqa_2gpu_max25/new_test_gpt2_medmcqa_2gpu_max25.sh create mode 100755 regression_test/test_gpt2_medmcqa_2gpu_max25/old_comparison.sh create mode 100644 regression_test/test_gpt2_medmcqa_2gpu_max25/output_old.json create mode 100644 regression_test/test_gpt2_medmcqa_2gpu_max50/comparison.sh create mode 100644 regression_test/test_gpt2_medmcqa_2gpu_max50/input_new.json create mode 100644 regression_test/test_gpt2_medmcqa_2gpu_max50/input_old.json create mode 120000 regression_test/test_gpt2_medmcqa_2gpu_max50/new_test_gpt2_medmcqa_2gpu_max50.sh create mode 100755 regression_test/test_gpt2_medmcqa_2gpu_max50/old_comparison.sh create mode 100644 regression_test/test_gpt2_medmcqa_2gpu_max50/output_old.json create mode 100644 regression_test/test_gpt2_medmcqa_4gpu_max100/comparison.sh create mode 100644 regression_test/test_gpt2_medmcqa_4gpu_max100/input_new.json create mode 100644 regression_test/test_gpt2_medmcqa_4gpu_max100/input_old.json create mode 120000 regression_test/test_gpt2_medmcqa_4gpu_max100/new_test_gpt2_medmcqa_4gpu_max100.sh create mode 100755 regression_test/test_gpt2_medmcqa_4gpu_max100/old_comparison.sh create mode 100644 regression_test/test_gpt2_medmcqa_4gpu_max100/output_old.json create mode 100644 regression_test/test_gpt2_pubmedqa_4gpu_max100/comparison.sh create mode 100644 regression_test/test_gpt2_pubmedqa_4gpu_max100/input_new.json create mode 100644 regression_test/test_gpt2_pubmedqa_4gpu_max100/input_old.json create mode 120000 regression_test/test_gpt2_pubmedqa_4gpu_max100/new_test_gpt2_pubmedqa_4gpu_max100.sh create mode 100755 regression_test/test_gpt2_pubmedqa_4gpu_max100/old_comparison.sh create mode 100644 regression_test/test_gpt2_pubmedqa_4gpu_max100/output_old.json create mode 100644 regression_test/test_gpt2_usmle_4gpu_max100/comparison.sh create mode 100644 regression_test/test_gpt2_usmle_4gpu_max100/input_new.json create mode 100644 regression_test/test_gpt2_usmle_4gpu_max100/input_old.json create mode 120000 regression_test/test_gpt2_usmle_4gpu_max100/new_test_gpt2_usmle_4gpu_max100.sh create mode 100755 regression_test/test_gpt2_usmle_4gpu_max100/old_comparison.sh create mode 100644 regression_test/test_gpt2_usmle_4gpu_max100/output_old.json create mode 100644 regression_test/test_gpt2l_gsm8k_4gpu_max100/comparison.sh create mode 100644 regression_test/test_gpt2l_gsm8k_4gpu_max100/input_new.json create mode 100644 regression_test/test_gpt2l_gsm8k_4gpu_max100/input_old.json create mode 120000 regression_test/test_gpt2l_gsm8k_4gpu_max100/new_test_gpt2l_gsm8k_4gpu_max100.sh create mode 100755 regression_test/test_gpt2l_gsm8k_4gpu_max100/old_comparison.sh create mode 100644 regression_test/test_gpt2l_gsm8k_4gpu_max100/output_old.json create mode 100644 regression_test/test_gpt2l_medmcqa_4gpu_max100/comparison.sh create mode 100644 regression_test/test_gpt2l_medmcqa_4gpu_max100/input_new.json create mode 100644 regression_test/test_gpt2l_medmcqa_4gpu_max100/input_old.json create mode 120000 regression_test/test_gpt2l_medmcqa_4gpu_max100/new_test_gpt2l_medmcqa_4gpu_max100.sh create mode 100755 regression_test/test_gpt2l_medmcqa_4gpu_max100/old_comparison.sh create mode 100644 regression_test/test_gpt2l_medmcqa_4gpu_max100/output_old.json create mode 100644 regression_test/test_gpt2l_pubmedqa_4gpu_max100/comparison.sh create mode 100644 regression_test/test_gpt2l_pubmedqa_4gpu_max100/input_new.json create mode 100644 regression_test/test_gpt2l_pubmedqa_4gpu_max100/input_old.json create mode 120000 regression_test/test_gpt2l_pubmedqa_4gpu_max100/new_test_gpt2l_pubmedqa_4gpu_max100.sh create mode 100755 regression_test/test_gpt2l_pubmedqa_4gpu_max100/old_comparison.sh create mode 100644 regression_test/test_gpt2l_pubmedqa_4gpu_max100/output_old.json create mode 100644 regression_test/test_gpt2l_usmle_4gpu_max100/comparison.sh create mode 100644 regression_test/test_gpt2l_usmle_4gpu_max100/input_new.json create mode 100644 regression_test/test_gpt2l_usmle_4gpu_max100/input_old.json create mode 120000 regression_test/test_gpt2l_usmle_4gpu_max100/new_test_gpt2l_usmle_4gpu_max100.sh create mode 100755 regression_test/test_gpt2l_usmle_4gpu_max100/old_comparison.sh create mode 100644 regression_test/test_gpt2l_usmle_4gpu_max100/output_old.json create mode 100644 regression_test/test_gpt2m_gsm8k_4gpu_max100/comparison.sh create mode 100644 regression_test/test_gpt2m_gsm8k_4gpu_max100/input_new.json create mode 100644 regression_test/test_gpt2m_gsm8k_4gpu_max100/input_old.json create mode 120000 regression_test/test_gpt2m_gsm8k_4gpu_max100/new_test_gpt2m_gsm8k_4gpu_max100.sh create mode 100755 regression_test/test_gpt2m_gsm8k_4gpu_max100/old_comparison.sh create mode 100644 regression_test/test_gpt2m_gsm8k_4gpu_max100/output_old.json create mode 100644 regression_test/test_gpt2m_medmcqa_4gpu_max100/comparison.sh create mode 100644 regression_test/test_gpt2m_medmcqa_4gpu_max100/input_new.json create mode 100644 regression_test/test_gpt2m_medmcqa_4gpu_max100/input_old.json create mode 120000 regression_test/test_gpt2m_medmcqa_4gpu_max100/new_test_gpt2m_medmcqa_4gpu_max100.sh create mode 100755 regression_test/test_gpt2m_medmcqa_4gpu_max100/old_comparison.sh create mode 100644 regression_test/test_gpt2m_medmcqa_4gpu_max100/output_old.json create mode 100644 regression_test/test_gpt2m_pubmedqa_4gpu_max100/comparison.sh create mode 100644 regression_test/test_gpt2m_pubmedqa_4gpu_max100/input_new.json create mode 100644 regression_test/test_gpt2m_pubmedqa_4gpu_max100/input_old.json create mode 120000 regression_test/test_gpt2m_pubmedqa_4gpu_max100/new_test_gpt2m_pubmedqa_4gpu_max100.sh create mode 100755 regression_test/test_gpt2m_pubmedqa_4gpu_max100/old_comparison.sh create mode 100644 regression_test/test_gpt2m_pubmedqa_4gpu_max100/output_old.json create mode 100644 regression_test/test_gpt2m_usmle_4gpu_max100/comparison.sh create mode 100644 regression_test/test_gpt2m_usmle_4gpu_max100/input_new.json create mode 100644 regression_test/test_gpt2m_usmle_4gpu_max100/input_old.json create mode 120000 regression_test/test_gpt2m_usmle_4gpu_max100/new_test_gpt2m_usmle_4gpu_max100.sh create mode 100755 regression_test/test_gpt2m_usmle_4gpu_max100/old_comparison.sh create mode 100644 regression_test/test_gpt2m_usmle_4gpu_max100/output_old.json create mode 100644 requirements.txt create mode 100644 scripts/bash.sh create mode 100644 scripts/convert_llama_weights_to_hf.py create mode 100755 scripts/run_finetune.sh create mode 100755 scripts/run_finetune_with_lora.sh create mode 100755 scripts/run_inference.sh create mode 100755 scripts/run_inference_with_lora.sh create mode 100755 scripts/run_regression_test.sh create mode 100755 scripts/run_unittest.sh create mode 100644 setup.py create mode 100644 src/lmflow/__init__.py create mode 100644 src/lmflow/args.py create mode 100644 src/lmflow/datasets/__init__.py create mode 100644 src/lmflow/datasets/dataset.py create mode 100644 src/lmflow/models/__init__.py create mode 100644 src/lmflow/models/auto_model.py create mode 100644 src/lmflow/models/base_model.py create mode 100644 src/lmflow/models/decoder_model.py create mode 100644 src/lmflow/models/hf_decoder_model.py create mode 100644 src/lmflow/models/interfaces/__init__.py create mode 100644 src/lmflow/models/interfaces/tunable.py create mode 100644 src/lmflow/pipeline/__init__.py create mode 100644 src/lmflow/pipeline/auto_pipeline.py create mode 100644 src/lmflow/pipeline/base_pipeline.py create mode 100644 src/lmflow/pipeline/base_tuner.py create mode 100644 src/lmflow/pipeline/finetuner.py create mode 100644 src/lmflow/pipeline/inferencer.py create mode 100644 src/lmflow/utils/__init__.py create mode 100644 src/lmflow/utils/data_utils.py create mode 100644 src/lmflow/version.py create mode 100644 tests/__init__.py create mode 100644 tests/datasets/__init__.py create mode 100644 tests/datasets/test_dataset.py create mode 100644 tests/models/__init__.py create mode 100644 tests/models/test_hf_decoder_model.py create mode 100644 tests/utils/__init__.py create mode 100644 tests/utils/test_data_utils.py diff --git a/.github/workflows/documentation.yaml b/.github/workflows/documentation.yaml new file mode 100644 index 000000000..0f2e57b40 --- /dev/null +++ b/.github/workflows/documentation.yaml @@ -0,0 +1,35 @@ +name: Docs +on: [push, pull_request, workflow_dispatch] +jobs: + docs: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-python@v3 + - name: Install dependencies + run: | + pip install sphinx + pip install matplotlib + pip install numpydoc + - name: Install torch + run: | + pip install torch + - name: Install numpy + run: | + pip install numpy + - name: Install dependencies + run: | + pip install -r ./docs/requirements.txt + - name: Install current pkg + run: | + pip install -e . + - name: Sphinx build + run: | + sphinx-build docs/source _build + - name: Deploy + uses: peaceiris/actions-gh-pages@v3 + with: + publish_branch: gh-pages + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: _build/ + force_orphan: true diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..b7a594dbd --- /dev/null +++ b/.gitignore @@ -0,0 +1,180 @@ +# Initially taken from Github's Python gitignore file + +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class +_build + +# C extensions +*.so + +# tests and logs +tests/fixtures/cached_*_text.txt +logs/ +lightning_logs/ +lang_code_data/ +log/ +regression_test/*/new_output_models +regression_test/*/new_log +output_dir/ + +# data files +data/ + +# output models +output_models/ + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +.hypothesis/ +.pytest_cache/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +.python-version + +# celery beat schedule file +celerybeat-schedule + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# vscode +.vs +.vscode + +# Pycharm +.idea + +# TF code +tensorflow_code + +# Models +proc_data + +# examples +runs +/runs_old +/wandb +/examples/runs +/examples/**/*.args +/examples/rag/sweep + +# data +# /data +serialization_dir + +# emacs +*.*~ +debug.env + +# vim +.*.swp + +#ctags +tags + +# pre-commit +.pre-commit* + +# .lock +*.lock + +# DS_Store (MacOS) +.DS_Store + +# ruff +.ruff_cache diff --git a/LICENSE b/LICENSE new file mode 100644 index 000000000..f49a4e16e --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 000000000..903863e7b --- /dev/null +++ b/README.md @@ -0,0 +1,266 @@ +

+LMFlow +

+ + +# LMFlow + + + +[![Code License](https://img.shields.io/badge/Code%20License-Apache_2.0-green.svg)](https://github.com/shizhediao/LMFlow/blob/main/LICENSE) +[![Python 3.9+](https://img.shields.io/badge/python-3.9+-blue.svg)](https://www.python.org/downloads/release/python-390/) +[![Doc](https://img.shields.io/badge/Website-Doc-orange.svg)](https://shizhediao.github.io/LMFlow/) +[![Embark](https://img.shields.io/badge/discord-LMFlow-%237289da.svg?logo=discord)](https://discord.gg/NcMPyDVP) + + +An extensible, convenient, and efficient toolbox for finetuning large machine learning models, designed to be user-friendly, speedy and reliable, and accessible to the entire community. + +

+LMFlow-features +

+ +## Model Performance + +| | PubMedQA | MedQA-USMLE | MedMCQA | Average | +|:---------:|:--------:|:-----------:|:-------:|:----:| +| Human (pass) | 60.0 | 50.0 | | | +| Human (expert) | 78.0 | 87.0 | 90.0 | 85.0 | +| | | | | | +| InstructGPT 175B | 73.2 | 46.0 | 44.0 | 54.4 | +| ChatGPT | 63.9 | **57.0** | 44.7 | 55.2 | +| LLaMA 7B | 5.2 | 27.1 | 24.3 | 18.9 | +| LLaMA 30B | 1.8 | 43.4 | 30.3 | 25.2 | +| | | | | | | +| Task-tuned LLaMA 7B (Full) | **75.1** | 44.5 | 49.9 | 56.5 | +| Task-tuned LLaMA 30B (LoRA) | 74 | 51.3 | **50.2**|**58.5**| + +The LLaMA 30B (LoRA) performance is achieved with only **~16h** finetuning in a +single 8 \* A100 server. For more performance, including instruction tuning +results, please refer to our +[Documentation](https://shizhediao.github.io/LMFlow/). + +## Supported Pipelines + +| Pipelines | Status | +|----------|:-------------:| +| Task Tuning | :white_check_mark: Supported | +| Instruction Tuning | :white_check_mark: Supported | +| Parameter-Efficient Tuning | :white_check_mark: Supported | +| Large Model Inference | :white_check_mark: Supported | +| Reinforced Tuning | :construction: Developing | + + +## Supported Models +Seamlessly supported the models in 🤗 huggingface. + +| Models | Status | | Models | Status | +|----------|:-------------:|----------|----------|:-------------:| +| GPT2-large | :white_check_mark: Tested | | Galactica-6.7B | :construction: Untested | +| GPT2-xl | :white_check_mark: Tested | | Galactica-30B | :construction: Untested | +| GPT-Neo-1.3B | :construction: Untested | | LLaMA-7B | :white_check_mark: Tested :star: | +| GPT-Neo-2.7B | :construction: Untested | | LLaMA-13B | :white_check_mark: Tested :star: | +| GPT-Neox-20B | :construction: Untested | | LLaMA-33B | :white_check_mark: Tested :star: | +| Galactica-1.3B | :white_check_mark: Tested | |LLaMA-65B | :construction: Untested | + +## 1.Setup +``` +conda create -n lmflow python=3.9 -y +conda activate lmflow +conda install mpi4py +pip install -e . +``` + +## 2.Prepare Dataset +You can easily download the example training dataset and test dataset by running +```bash +cd data +bash download.sh --all +cd - +``` +If you cannot access Google Drive, you can download the data by [BaiduNetDisk](https://pan.baidu.com/s/1L7AC5Oy-3YhbCp2aNX4tnQ?pwd=dm2s). + +You can also use your own dataset by simply convert to the following format: +```json +{ + "type": "text2text", + "instances": [ + { + "input": "Question: The Transformer architecture [START_REF]", + "output": "N/A" + }, + ... + ] +} +``` +```json +{ + "type": "text_only", + "instances": [ + { + "text": "Defintion: In this task, we ask you to write an answer to a question that involves events that may be stationary (not changing over time) or transient (changing over time). For example, the sentence \"he was born in the U.S.\" contains a stationary event since it will last forever; however, \"he is hungry\" contains a transient event since it will remain true for a short period of time. Note that a lot of the questions could have more than one correct answer. We only need a single most-likely answer. Please try to keep your \"answer\" as simple as possible. Concise and simple \"answer\" is preferred over those complex and verbose ones. \n Input: Question: Sentence: It's hail crackled across the comm, and Tara spun to retake her seat at the helm. \nQuestion: Will the hail storm ever end? \n Output: NA \n\n" + }, + ... + ] +} +``` +## 3. Run Scripts +### 3.1 Run Finetuning + +You can run `scripts/run_finetune.sh` to finetune a GPT-2 base model +```sh +./scripts/run_finetune.sh +``` + +If you would like to provide arguments for deepspeed to reflect your machine +settings, you may pass the corresponding deepspeed arguments to the script. For +example, +```sh +./scripts/run_finetune.sh "--num_gpus=8 --master_port 10001" +``` + +To enable LoRA finetuning, you may refer to +```sh +./scripts/run_finetune_with_lora.sh +``` +which can be run in similar manner. + +For detailed configurations, one may modify these scripts directly. These +scripts actually just call python script `examples/finetune.py`, which can +be run in following manner, + +```sh +deepspeed ${deepspeed_args} \ + examples/finetune.py \ + --deepspeed configs/ds_config_zero3.json \ + --bf16 \ + --run_name finetune_with_lora \ + --model_name_or_path facebook/galactica-1.3b \ + --num_train_epochs 0.01 \ + --learning_rate 2e-5 \ + --dataset_path ${dataset_path} \ + --per_device_train_batch_size 1 \ + --per_device_eval_batch_size 1 \ + --validation_split_percentage 0 \ + --logging_steps 20 \ + --block_size 512 \ + --do_train \ + --output_dir output_models/finetune \ + --overwrite_output_dir \ + --ddp_timeout 72000 \ + --save_steps 5000 \ + --dataloader_num_workers 1 +``` +Here we set number of epochs `--num_train_epochs` to `0.01` so that the +finetuning process can be finished quickly. If you wish to obtain a model with +better performance, feel free to adjust those hyperparameters. You may run +```python +python examples/finetune.py -h +``` +to view all possible finetuning arguments. The finetuned model checkpoint will +be saved in the argument specified by `--output_dir`, which is +`output_models/finetune` in the above example. +### 3.2 Run Inference + +One can directly run inference with an existing huggingface model, e.g. to run +GPT2 large, one may execute +```sh +./scripts/run_inference.sh +``` +or run the corresponding python script +```python +CUDA_VISIBLE_DEVICES=0 \ + deepspeed examples/inference.py \ + --answer_type medmcqa \ + --model_name_or_path gpt2-large \ + --test_file data/MedQA-USMLE/validation/valid_1273.json \ + --deepspeed examples/ds_config.json \ +``` +To load the finetuned model, specify `--model_name_or_path` with the saved +model checkpoint directory path. + +For LoRA finetuned models, one may refer to +```sh +./scripts/run_inference_with_lora.sh +``` + +Those scripts invoke the examples `examples/*.py` built based on our APIs. For +more API-related examples, one may refer to the methods in the unittest +`tests`. + +## 4. Additional Notes +### 4.1 LLaMA Checkpoint + +1. First, you need to get the access of LLaMA model from [facebookresearch/llama](https://github.com/facebookresearch/llama). Download the official checkpoints and save them into `${llama-path}`. + +2. Second, convert the official checkpoints `${llama-path}` to HuggingFace supported checkpoints `${llama-hf-path}` by running + + `python ./scripts/convert_llama_weights_to_hf.py --input_dir ${llama-path} --model_size 7B --output_dir ${llama-hf-path}/llama-7b-hf` + +3. Then you are good to go by setting the checkpoint path to `${llama-hf-path}/llama-7b-hf`. Enjoy it! + +4. (optional) Now you have the original llama-7b-hf pretrained model. With +```sh +cd output_models && ./download.sh && cd - +``` +You can obtain the model difference finetuned by ours. By a way similar to `./scripts/run_inference_with_lora.sh`, +```sh +CUDA_VISIBLE_DEVICES=0 \ + deepspeed examples/inference.py \ + --answer_type text \ + --model_name_or_path ${llama-hf-path}/llama-7b-hf \ + --lora_model_path output_models/${llama-model-diff-path} \ + --test_file data/alpaca/test/test_252.json \ + --deepspeed examples/ds_config.json +``` +You can now inference with the finetuned llama model. + +### 4.2 DeepSpeed Config +You can config the deepspeed under configs. Details can be referred at [DeepSpeed Configuration](https://www.deepspeed.ai/docs/config-json/) + +## 5. Model Release + +### 5.1 Medical Model Checkpoints +You can run following script to download our medical model checkpoints : + +```bash +cd output_models +bash download.sh medical_ckpt +cd - +``` +You can also directly download our model via google drive link : [medical_ckpt.tar.gz](https://drive.google.com/file/d/1bnsQGNGNYchsOfiNyRAmL2fNiowbmFNw/view?usp=share_link) + +### 5.2 Instruction Model Checkpoints +Similarly, you can run following script to download our instruction model checkpoints : +```bash +cd output_models +bash download.sh instruction_ckpt +cd - +``` + +You can also directly download our model via google drive link : [instruction_ckpt.tar.gz](https://drive.google.com/file/d/1d_ioQ-ViVweeifbsFSO4pczc3UORFHZO/view?usp=share_link) + +### 5.3 Begin Reproduce + +After downloading the model checkpoints. You can replace the `--lora_model_path` with `output_models/instruction_ckpt/llama7b-lora` (example for llama-7b for instruction) and replace `--model_name_or_path` with your converted llama model inside `LMFlow/scripts/run_inference_with_lora.sh` and run this shell script to reproduce the result. + +Then you can check the model performance at our [Doc](https://shizhediao.github.io/LMFlow/). + +## Documentation +Please refer to our [Documentation](https://shizhediao.github.io/LMFlow/) for more API reference and experimental results. + +## Citation + +TBD + +## Disclaimer + +This package aims to provide a streamlined and user-friendly pipeline for large model tuning. Its functionalities serve as a reference and are intended for use by the user. However, it is important to note that the responsibility for the preparation of the data and pretrained models lies solely with the user. This package does not guarantee the accuracy, completeness, applicability, or legality of the components from the user's preparation. Users must be aware of and assume all risks and liabilities associated with the preparation of the models and data, and obtain legal, commercial, and technical advice before utilizing this package. The pipeline shall not be held responsible for any direct, indirect, special, incidental, or consequential damages resulting from the user's improper preparation of the data and pretrained models. + +It is also crucial to highlight that the results generated by the model are based on probabilistic models and not directly related to this pipeline. The accuracy, reliability, applicability, and legality of the results are not guaranteed by this pipeline. Therefore, users must also be aware of the risks and liabilities associated with the results and seek legal, commercial, and technical advice before relying on the model-generated outcomes. This pipeline shall not be accountable for any direct, indirect, special, incidental, or consequential damages resulting from the user's reliance on the model-generated results. + +## Support + +If you need any help, please submit a [Github](https://github.com/OptimalScale/LMFlow) issue. + + + diff --git a/assets/features.png b/assets/features.png new file mode 100644 index 0000000000000000000000000000000000000000..b5b00d2c358155796e2ff48c224e4d342539acb8 GIT binary patch literal 397394 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

n?C|IoW_(oY&RYoTJdefg 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 z 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