Add files using upload-large-folder tool
Browse filesThis view is limited to 50 files because it contains too many changes.
See raw diff
- .gitattributes +3 -0
- docs/resources/grpo_countdown.png +3 -0
- docs/resources/grpo_countdown_1.png +3 -0
- docs/resources/grpo_geoqa.png +3 -0
- examples/infer/demo_agent.py +118 -0
- examples/infer/demo_bert.py +53 -0
- examples/infer/demo_grounding.py +43 -0
- examples/infer/demo_hf.py +61 -0
- examples/infer/demo_lora.py +68 -0
- examples/infer/demo_mllm.py +145 -0
- examples/infer/demo_reward_model.py +31 -0
- examples/infer/lmdeploy/ddp.sh +7 -0
- examples/infer/lmdeploy/mllm_tp.sh +8 -0
- examples/infer/pt/batch_ddp.sh +9 -0
- examples/infer/pt/bert.sh +8 -0
- examples/infer/pt/lora.sh +10 -0
- examples/infer/pt/mllm_device_map.sh +9 -0
- examples/infer/pt/prm.sh +4 -0
- examples/infer/pt/reward_model.sh +5 -0
- examples/infer/vllm/ddp.sh +9 -0
- examples/infer/vllm/mllm_ddp.sh +11 -0
- examples/infer/vllm/mllm_tp.sh +11 -0
- examples/notebook/qwen2_5-self-cognition/infer.ipynb +148 -0
- examples/notebook/qwen2_5-self-cognition/infer.sh +7 -0
- examples/notebook/qwen2_5-self-cognition/self-cognition-sft.ipynb +219 -0
- examples/notebook/qwen2_5-self-cognition/sft.sh +30 -0
- examples/notebook/qwen2_5-vl-grounding/zh.ipynb +261 -0
- examples/notebook/qwen2vl-ocr/infer.ipynb +136 -0
- examples/notebook/qwen2vl-ocr/ocr-sft.ipynb +226 -0
- examples/sampler/distill/distill.sh +11 -0
- examples/sampler/mcts/mcts.py +116 -0
- examples/sampler/mcts/mcts.sh +35 -0
- examples/sampler/mcts/system_prompt.txt +7 -0
- examples/train/agent/deepseek_r1.sh +27 -0
- examples/train/agent/glm4.sh +28 -0
- examples/train/agent/loss_scale/infer_lora.py +90 -0
- examples/train/agent/loss_scale/train.sh +28 -0
- examples/train/agent/qwen2_5.sh +26 -0
- examples/train/all_to_all/infer.sh +9 -0
- examples/train/all_to_all/train.sh +23 -0
- examples/train/base_to_chat/full.sh +28 -0
- examples/train/base_to_chat/lora.sh +34 -0
- examples/train/base_to_chat/lora2.sh +33 -0
- examples/train/embedding/train_gme.sh +29 -0
- examples/train/embedding/train_gte.sh +31 -0
- examples/train/full/infer.sh +7 -0
- examples/train/full/qwen2_5_32b.sh +28 -0
- examples/train/full/train.sh +25 -0
- examples/train/grpo/external/README.md +46 -0
- examples/train/grpo/external/grpo.sh +33 -0
.gitattributes
CHANGED
|
@@ -38,3 +38,6 @@ asset/banner.png filter=lfs diff=lfs merge=lfs -text
|
|
| 38 |
docs/resources/grpo_clevr_count.png filter=lfs diff=lfs merge=lfs -text
|
| 39 |
docs/resources/grpo_code.png filter=lfs diff=lfs merge=lfs -text
|
| 40 |
docs/resources/dpo_data.png filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
|
|
|
|
|
|
| 38 |
docs/resources/grpo_clevr_count.png filter=lfs diff=lfs merge=lfs -text
|
| 39 |
docs/resources/grpo_code.png filter=lfs diff=lfs merge=lfs -text
|
| 40 |
docs/resources/dpo_data.png filter=lfs diff=lfs merge=lfs -text
|
| 41 |
+
docs/resources/grpo_countdown_1.png filter=lfs diff=lfs merge=lfs -text
|
| 42 |
+
docs/resources/grpo_countdown.png filter=lfs diff=lfs merge=lfs -text
|
| 43 |
+
docs/resources/grpo_geoqa.png filter=lfs diff=lfs merge=lfs -text
|
docs/resources/grpo_countdown.png
ADDED
|
Git LFS Details
|
docs/resources/grpo_countdown_1.png
ADDED
|
Git LFS Details
|
docs/resources/grpo_geoqa.png
ADDED
|
Git LFS Details
|
examples/infer/demo_agent.py
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright (c) Alibaba, Inc. and its affiliates.
|
| 2 |
+
import os
|
| 3 |
+
|
| 4 |
+
os.environ['CUDA_VISIBLE_DEVICES'] = '0'
|
| 5 |
+
# os.environ['SWIFT_DEBUG'] = '1'
|
| 6 |
+
|
| 7 |
+
|
| 8 |
+
def infer(engine: 'InferEngine', infer_request: 'InferRequest'):
|
| 9 |
+
stop = [engine.default_template.agent_template.keyword.observation] # compat react_en
|
| 10 |
+
request_config = RequestConfig(max_tokens=512, temperature=0, stop=stop)
|
| 11 |
+
resp_list = engine.infer([infer_request], request_config)
|
| 12 |
+
query = infer_request.messages[0]['content']
|
| 13 |
+
response = resp_list[0].choices[0].message.content
|
| 14 |
+
print(f'query: {query}')
|
| 15 |
+
print(f'response: {response}')
|
| 16 |
+
print(f'tool_calls: {resp_list[0].choices[0].message.tool_calls}')
|
| 17 |
+
|
| 18 |
+
tool = '{"temperature": 32, "condition": "Sunny", "humidity": 50}'
|
| 19 |
+
print(f'tool_response: {tool}')
|
| 20 |
+
infer_request.messages += [{'role': 'assistant', 'content': response}, {'role': 'tool', 'content': tool}]
|
| 21 |
+
resp_list = engine.infer([infer_request], request_config)
|
| 22 |
+
response2 = resp_list[0].choices[0].message.content
|
| 23 |
+
print(f'response2: {response2}')
|
| 24 |
+
|
| 25 |
+
|
| 26 |
+
def infer_stream(engine: 'InferEngine', infer_request: 'InferRequest'):
|
| 27 |
+
stop = [engine.default_template.agent_template.keyword.observation]
|
| 28 |
+
request_config = RequestConfig(max_tokens=512, temperature=0, stream=True, stop=stop)
|
| 29 |
+
gen_list = engine.infer([infer_request], request_config)
|
| 30 |
+
query = infer_request.messages[0]['content']
|
| 31 |
+
response = ''
|
| 32 |
+
print(f'query: {query}\nresponse: ', end='')
|
| 33 |
+
for resp in gen_list[0]:
|
| 34 |
+
if resp is None:
|
| 35 |
+
continue
|
| 36 |
+
delta = resp.choices[0].delta.content
|
| 37 |
+
response += delta
|
| 38 |
+
print(delta, end='', flush=True)
|
| 39 |
+
print()
|
| 40 |
+
print(f'tool_calls: {resp.choices[0].delta.tool_calls}')
|
| 41 |
+
|
| 42 |
+
tool = '{"temperature": 32, "condition": "Sunny", "humidity": 50}'
|
| 43 |
+
print(f'tool_response: {tool}\nresponse2: ', end='')
|
| 44 |
+
infer_request.messages += [{'role': 'assistant', 'content': response}, {'role': 'tool', 'content': tool}]
|
| 45 |
+
gen_list = engine.infer([infer_request], request_config)
|
| 46 |
+
for resp in gen_list[0]:
|
| 47 |
+
if resp is None:
|
| 48 |
+
continue
|
| 49 |
+
print(resp.choices[0].delta.content, end='', flush=True)
|
| 50 |
+
print()
|
| 51 |
+
|
| 52 |
+
|
| 53 |
+
def get_infer_request():
|
| 54 |
+
return InferRequest(
|
| 55 |
+
messages=[{
|
| 56 |
+
'role': 'user',
|
| 57 |
+
'content': "How's the weather in Beijing today?"
|
| 58 |
+
}],
|
| 59 |
+
tools=[{
|
| 60 |
+
'name': 'get_current_weather',
|
| 61 |
+
'description': 'Get the current weather in a given location',
|
| 62 |
+
'parameters': {
|
| 63 |
+
'type': 'object',
|
| 64 |
+
'properties': {
|
| 65 |
+
'location': {
|
| 66 |
+
'type': 'string',
|
| 67 |
+
'description': 'The city and state, e.g. San Francisco, CA'
|
| 68 |
+
},
|
| 69 |
+
'unit': {
|
| 70 |
+
'type': 'string',
|
| 71 |
+
'enum': ['celsius', 'fahrenheit']
|
| 72 |
+
}
|
| 73 |
+
},
|
| 74 |
+
'required': ['location']
|
| 75 |
+
}
|
| 76 |
+
}])
|
| 77 |
+
|
| 78 |
+
|
| 79 |
+
def infer_continue_generate(engine):
|
| 80 |
+
# Continue generating after the assistant message.
|
| 81 |
+
infer_request = InferRequest(messages=[{
|
| 82 |
+
'role': 'user',
|
| 83 |
+
'content': 'How is the weather today?'
|
| 84 |
+
}, {
|
| 85 |
+
'role': 'assistant',
|
| 86 |
+
'content': 'It is sunny today, '
|
| 87 |
+
}, {
|
| 88 |
+
'role': 'assistant',
|
| 89 |
+
'content': None
|
| 90 |
+
}])
|
| 91 |
+
request_config = RequestConfig(max_tokens=512, temperature=0)
|
| 92 |
+
resp_list = engine.infer([infer_request], request_config)
|
| 93 |
+
response = resp_list[0].choices[0].message.content
|
| 94 |
+
print(f'response: {response}')
|
| 95 |
+
|
| 96 |
+
|
| 97 |
+
if __name__ == '__main__':
|
| 98 |
+
from swift.llm import InferEngine, InferRequest, PtEngine, RequestConfig
|
| 99 |
+
from swift.plugin import agent_templates
|
| 100 |
+
model = 'Qwen/Qwen2.5-1.5B-Instruct'
|
| 101 |
+
infer_backend = 'pt'
|
| 102 |
+
|
| 103 |
+
if infer_backend == 'pt':
|
| 104 |
+
engine = PtEngine(model, max_batch_size=64)
|
| 105 |
+
elif infer_backend == 'vllm':
|
| 106 |
+
from swift.llm import VllmEngine
|
| 107 |
+
engine = VllmEngine(model, max_model_len=8192)
|
| 108 |
+
elif infer_backend == 'lmdeploy':
|
| 109 |
+
from swift.llm import LmdeployEngine
|
| 110 |
+
engine = LmdeployEngine(model)
|
| 111 |
+
|
| 112 |
+
# agent_template = agent_templates['hermes']() # react_en/qwen_en/qwen_en_parallel
|
| 113 |
+
# engine.default_template.agent_template = agent_template
|
| 114 |
+
|
| 115 |
+
infer(engine, get_infer_request())
|
| 116 |
+
infer_stream(engine, get_infer_request())
|
| 117 |
+
|
| 118 |
+
# infer_continue_generate(engine)
|
examples/infer/demo_bert.py
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright (c) Alibaba, Inc. and its affiliates.
|
| 2 |
+
import os
|
| 3 |
+
from typing import List
|
| 4 |
+
|
| 5 |
+
os.environ['CUDA_VISIBLE_DEVICES'] = '0'
|
| 6 |
+
|
| 7 |
+
|
| 8 |
+
def infer_batch(engine: 'InferEngine', infer_requests: List['InferRequest']):
|
| 9 |
+
resp_list = engine.infer(infer_requests)
|
| 10 |
+
query0 = infer_requests[0].messages[0]['content']
|
| 11 |
+
query1 = infer_requests[1].messages[0]['content']
|
| 12 |
+
print(f'query0: {query0}')
|
| 13 |
+
print(f'response0: {resp_list[0].choices[0].message.content}')
|
| 14 |
+
print(f'query1: {query1}')
|
| 15 |
+
print(f'response1: {resp_list[1].choices[0].message.content}')
|
| 16 |
+
|
| 17 |
+
|
| 18 |
+
if __name__ == '__main__':
|
| 19 |
+
# This is an example of BERT with LoRA.
|
| 20 |
+
from swift.llm import InferEngine, InferRequest, PtEngine, load_dataset, safe_snapshot_download, BaseArguments
|
| 21 |
+
from swift.tuners import Swift
|
| 22 |
+
adapter_path = safe_snapshot_download('swift/test_bert')
|
| 23 |
+
args = BaseArguments.from_pretrained(adapter_path)
|
| 24 |
+
args.max_length = 512
|
| 25 |
+
args.truncation_strategy = 'right'
|
| 26 |
+
# method1
|
| 27 |
+
model, processor = args.get_model_processor()
|
| 28 |
+
model = Swift.from_pretrained(model, adapter_path)
|
| 29 |
+
template = args.get_template(processor)
|
| 30 |
+
engine = PtEngine.from_model_template(model, template, max_batch_size=64)
|
| 31 |
+
|
| 32 |
+
# method2
|
| 33 |
+
# engine = PtEngine(args.model, adapters=[adapter_path], max_batch_size=64,
|
| 34 |
+
# task_type=args.task_type, num_labels=args.num_labels)
|
| 35 |
+
# template = args.get_template(engine.processor)
|
| 36 |
+
# engine.default_template = template
|
| 37 |
+
|
| 38 |
+
# Here, `load_dataset` is used for convenience; `infer_batch` does not require creating a dataset.
|
| 39 |
+
dataset = load_dataset(['DAMO_NLP/jd:cls#1000'], seed=42)[0]
|
| 40 |
+
print(f'dataset: {dataset}')
|
| 41 |
+
infer_requests = [InferRequest(messages=data['messages']) for data in dataset]
|
| 42 |
+
infer_batch(engine, infer_requests)
|
| 43 |
+
|
| 44 |
+
infer_batch(engine, [
|
| 45 |
+
InferRequest(messages=[{
|
| 46 |
+
'role': 'user',
|
| 47 |
+
'content': '今天天气真好呀'
|
| 48 |
+
}]),
|
| 49 |
+
InferRequest(messages=[{
|
| 50 |
+
'role': 'user',
|
| 51 |
+
'content': '真倒霉'
|
| 52 |
+
}])
|
| 53 |
+
])
|
examples/infer/demo_grounding.py
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# pip install git+https://github.com/huggingface/transformers.git # transformers>=4.49
|
| 2 |
+
import os
|
| 3 |
+
import re
|
| 4 |
+
from typing import Literal
|
| 5 |
+
|
| 6 |
+
os.environ['CUDA_VISIBLE_DEVICES'] = '0'
|
| 7 |
+
|
| 8 |
+
|
| 9 |
+
def draw_bbox_qwen2_vl(image, response, norm_bbox: Literal['norm1000', 'none']):
|
| 10 |
+
matches = re.findall(
|
| 11 |
+
r'<\|object_ref_start\|>(.*?)<\|object_ref_end\|><\|box_start\|>\((\d+),(\d+)\),\((\d+),(\d+)\)<\|box_end\|>',
|
| 12 |
+
response)
|
| 13 |
+
ref = []
|
| 14 |
+
bbox = []
|
| 15 |
+
for match_ in matches:
|
| 16 |
+
ref.append(match_[0])
|
| 17 |
+
bbox.append(list(match_[1:]))
|
| 18 |
+
draw_bbox(image, ref, bbox, norm_bbox=norm_bbox)
|
| 19 |
+
|
| 20 |
+
|
| 21 |
+
def infer_grounding():
|
| 22 |
+
from swift.llm import PtEngine, RequestConfig, BaseArguments, InferRequest, safe_snapshot_download
|
| 23 |
+
output_path = 'bbox.png'
|
| 24 |
+
image = load_image('http://modelscope-open.oss-cn-hangzhou.aliyuncs.com/images/animal.png')
|
| 25 |
+
infer_request = InferRequest(messages=[{'role': 'user', 'content': 'Task: Object Detection'}], images=[image])
|
| 26 |
+
|
| 27 |
+
request_config = RequestConfig(max_tokens=512, temperature=0)
|
| 28 |
+
adapter_path = safe_snapshot_download('swift/test_grounding')
|
| 29 |
+
args = BaseArguments.from_pretrained(adapter_path)
|
| 30 |
+
|
| 31 |
+
engine = PtEngine(args.model, adapters=[adapter_path])
|
| 32 |
+
resp_list = engine.infer([infer_request], request_config)
|
| 33 |
+
response = resp_list[0].choices[0].message.content
|
| 34 |
+
print(f'lora-response: {response}')
|
| 35 |
+
|
| 36 |
+
draw_bbox_qwen2_vl(image, response, norm_bbox=args.norm_bbox)
|
| 37 |
+
print(f'output_path: {output_path}')
|
| 38 |
+
image.save(output_path)
|
| 39 |
+
|
| 40 |
+
|
| 41 |
+
if __name__ == '__main__':
|
| 42 |
+
from swift.llm import draw_bbox, load_image
|
| 43 |
+
infer_grounding()
|
examples/infer/demo_hf.py
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
def infer_hf():
|
| 2 |
+
from transformers import AutoModelForCausalLM, AutoTokenizer
|
| 3 |
+
from peft import PeftModel
|
| 4 |
+
from modelscope import snapshot_download
|
| 5 |
+
model_dir = snapshot_download('Qwen/Qwen2.5-7B-Instruct')
|
| 6 |
+
adapter_dir = snapshot_download('swift/test_lora')
|
| 7 |
+
model = AutoModelForCausalLM.from_pretrained(
|
| 8 |
+
model_dir, torch_dtype='auto', device_map='auto', trust_remote_code=True)
|
| 9 |
+
model = PeftModel.from_pretrained(model, adapter_dir)
|
| 10 |
+
|
| 11 |
+
tokenizer = AutoTokenizer.from_pretrained(model_dir, trust_remote_code=True)
|
| 12 |
+
|
| 13 |
+
messages = [{
|
| 14 |
+
'role': 'system',
|
| 15 |
+
'content': 'You are a helpful assistant.'
|
| 16 |
+
}, {
|
| 17 |
+
'role': 'user',
|
| 18 |
+
'content': 'who are you?'
|
| 19 |
+
}]
|
| 20 |
+
text = tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
|
| 21 |
+
model_inputs = tokenizer([text], return_tensors='pt', add_special_tokens=False).to(model.device)
|
| 22 |
+
|
| 23 |
+
generated_ids = model.generate(**model_inputs, max_new_tokens=512, do_sample=False)
|
| 24 |
+
generated_ids = [
|
| 25 |
+
output_ids[len(input_ids):] for input_ids, output_ids in zip(model_inputs.input_ids, generated_ids)
|
| 26 |
+
]
|
| 27 |
+
|
| 28 |
+
response = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]
|
| 29 |
+
print(f'response: {response}')
|
| 30 |
+
return response
|
| 31 |
+
|
| 32 |
+
|
| 33 |
+
def infer_swift():
|
| 34 |
+
from swift.llm import get_model_tokenizer, get_template, InferRequest, RequestConfig, PtEngine
|
| 35 |
+
from modelscope import snapshot_download
|
| 36 |
+
from swift.tuners import Swift
|
| 37 |
+
model_dir = snapshot_download('Qwen/Qwen2.5-7B-Instruct')
|
| 38 |
+
adapter_dir = snapshot_download('swift/test_lora')
|
| 39 |
+
model, tokenizer = get_model_tokenizer(model_dir, device_map='auto')
|
| 40 |
+
model = Swift.from_pretrained(model, adapter_dir)
|
| 41 |
+
template = get_template(model.model_meta.template, tokenizer)
|
| 42 |
+
engine = PtEngine.from_model_template(model, template)
|
| 43 |
+
|
| 44 |
+
messages = [{
|
| 45 |
+
'role': 'system',
|
| 46 |
+
'content': 'You are a helpful assistant.'
|
| 47 |
+
}, {
|
| 48 |
+
'role': 'user',
|
| 49 |
+
'content': 'who are you?'
|
| 50 |
+
}]
|
| 51 |
+
request_config = RequestConfig(max_tokens=512, temperature=0)
|
| 52 |
+
resp_list = engine.infer([InferRequest(messages=messages)], request_config=request_config)
|
| 53 |
+
response = resp_list[0].choices[0].message.content
|
| 54 |
+
print(f'response: {response}')
|
| 55 |
+
return response
|
| 56 |
+
|
| 57 |
+
|
| 58 |
+
if __name__ == '__main__':
|
| 59 |
+
response = infer_hf()
|
| 60 |
+
response2 = infer_swift()
|
| 61 |
+
assert response == response2
|
examples/infer/demo_lora.py
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
from typing import Literal
|
| 3 |
+
|
| 4 |
+
os.environ['CUDA_VISIBLE_DEVICES'] = '0'
|
| 5 |
+
|
| 6 |
+
|
| 7 |
+
def infer_multilora(infer_request: 'InferRequest', infer_backend: Literal['vllm', 'pt']):
|
| 8 |
+
# Dynamic LoRA
|
| 9 |
+
adapter_path = safe_snapshot_download('swift/test_lora')
|
| 10 |
+
adapter_path2 = safe_snapshot_download('swift/test_lora2')
|
| 11 |
+
args = BaseArguments.from_pretrained(adapter_path)
|
| 12 |
+
if infer_backend == 'pt':
|
| 13 |
+
engine = PtEngine(args.model)
|
| 14 |
+
elif infer_backend == 'vllm':
|
| 15 |
+
from swift.llm import VllmEngine
|
| 16 |
+
engine = VllmEngine(args.model, enable_lora=True, max_loras=1, max_lora_rank=16)
|
| 17 |
+
template = get_template(args.template, engine.processor, args.system)
|
| 18 |
+
request_config = RequestConfig(max_tokens=512, temperature=0)
|
| 19 |
+
adapter_request = AdapterRequest('lora1', adapter_path)
|
| 20 |
+
adapter_request2 = AdapterRequest('lora2', adapter_path2)
|
| 21 |
+
|
| 22 |
+
# use lora
|
| 23 |
+
resp_list = engine.infer([infer_request], request_config, template=template, adapter_request=adapter_request)
|
| 24 |
+
response = resp_list[0].choices[0].message.content
|
| 25 |
+
print(f'lora1-response: {response}')
|
| 26 |
+
# origin model
|
| 27 |
+
resp_list = engine.infer([infer_request], request_config)
|
| 28 |
+
response = resp_list[0].choices[0].message.content
|
| 29 |
+
print(f'response: {response}')
|
| 30 |
+
# use lora
|
| 31 |
+
resp_list = engine.infer([infer_request], request_config, template=template, adapter_request=adapter_request2)
|
| 32 |
+
response = resp_list[0].choices[0].message.content
|
| 33 |
+
print(f'lora2-response: {response}')
|
| 34 |
+
|
| 35 |
+
|
| 36 |
+
def infer_lora(infer_request: 'InferRequest'):
|
| 37 |
+
request_config = RequestConfig(max_tokens=512, temperature=0)
|
| 38 |
+
adapter_path = safe_snapshot_download('swift/test_lora')
|
| 39 |
+
args = BaseArguments.from_pretrained(adapter_path)
|
| 40 |
+
# method1
|
| 41 |
+
# engine = PtEngine(args.model, adapters=[adapter_path])
|
| 42 |
+
# template = get_template(args.template, engine.tokenizer, args.system)
|
| 43 |
+
# engine.default_template = template
|
| 44 |
+
|
| 45 |
+
# method2
|
| 46 |
+
# model, processor = args.get_model_processor()
|
| 47 |
+
# model = Swift.from_pretrained(model, adapter_path)
|
| 48 |
+
# template = args.get_template(processor)
|
| 49 |
+
# engine = PtEngine.from_model_template(model, template)
|
| 50 |
+
|
| 51 |
+
# method3
|
| 52 |
+
model, tokenizer = get_model_tokenizer(args.model)
|
| 53 |
+
model = Swift.from_pretrained(model, adapter_path)
|
| 54 |
+
template = get_template(args.template, tokenizer, args.system)
|
| 55 |
+
engine = PtEngine.from_model_template(model, template)
|
| 56 |
+
|
| 57 |
+
resp_list = engine.infer([infer_request], request_config)
|
| 58 |
+
response = resp_list[0].choices[0].message.content
|
| 59 |
+
print(f'lora-response: {response}')
|
| 60 |
+
|
| 61 |
+
|
| 62 |
+
if __name__ == '__main__':
|
| 63 |
+
from swift.llm import (PtEngine, RequestConfig, AdapterRequest, get_template, BaseArguments, InferRequest,
|
| 64 |
+
safe_snapshot_download, get_model_tokenizer)
|
| 65 |
+
from swift.tuners import Swift
|
| 66 |
+
infer_request = InferRequest(messages=[{'role': 'user', 'content': 'who are you?'}])
|
| 67 |
+
# infer_lora(infer_request)
|
| 68 |
+
infer_multilora(infer_request, 'pt')
|
examples/infer/demo_mllm.py
ADDED
|
@@ -0,0 +1,145 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright (c) Alibaba, Inc. and its affiliates.
|
| 2 |
+
import os
|
| 3 |
+
from typing import List, Literal
|
| 4 |
+
|
| 5 |
+
os.environ['CUDA_VISIBLE_DEVICES'] = '0'
|
| 6 |
+
|
| 7 |
+
|
| 8 |
+
def infer_batch(engine: 'InferEngine', infer_requests: List['InferRequest']):
|
| 9 |
+
request_config = RequestConfig(max_tokens=512, temperature=0)
|
| 10 |
+
metric = InferStats()
|
| 11 |
+
resp_list = engine.infer(infer_requests, request_config, metrics=[metric])
|
| 12 |
+
query0 = infer_requests[0].messages[0]['content']
|
| 13 |
+
print(f'query0: {query0}')
|
| 14 |
+
print(f'response0: {resp_list[0].choices[0].message.content}')
|
| 15 |
+
print(f'metric: {metric.compute()}')
|
| 16 |
+
# metric.reset() # reuse
|
| 17 |
+
|
| 18 |
+
|
| 19 |
+
def infer_stream(engine: 'InferEngine', infer_request: 'InferRequest'):
|
| 20 |
+
request_config = RequestConfig(max_tokens=512, temperature=0, stream=True)
|
| 21 |
+
metric = InferStats()
|
| 22 |
+
gen_list = engine.infer([infer_request], request_config, metrics=[metric])
|
| 23 |
+
query = infer_request.messages[0]['content']
|
| 24 |
+
print(f'query: {query}\nresponse: ', end='')
|
| 25 |
+
for resp in gen_list[0]:
|
| 26 |
+
if resp is None:
|
| 27 |
+
continue
|
| 28 |
+
print(resp.choices[0].delta.content, end='', flush=True)
|
| 29 |
+
print()
|
| 30 |
+
print(f'metric: {metric.compute()}')
|
| 31 |
+
|
| 32 |
+
|
| 33 |
+
def get_message(mm_type: Literal['text', 'image', 'video', 'audio']):
|
| 34 |
+
if mm_type == 'text':
|
| 35 |
+
message = {'role': 'user', 'content': 'who are you?'}
|
| 36 |
+
elif mm_type == 'image':
|
| 37 |
+
message = {
|
| 38 |
+
'role':
|
| 39 |
+
'user',
|
| 40 |
+
'content': [
|
| 41 |
+
{
|
| 42 |
+
'type': 'image',
|
| 43 |
+
# url or local_path or PIL.Image or base64
|
| 44 |
+
'image': 'http://modelscope-open.oss-cn-hangzhou.aliyuncs.com/images/animal.png'
|
| 45 |
+
},
|
| 46 |
+
{
|
| 47 |
+
'type': 'text',
|
| 48 |
+
'text': 'How many sheep are there in the picture?'
|
| 49 |
+
}
|
| 50 |
+
]
|
| 51 |
+
}
|
| 52 |
+
|
| 53 |
+
elif mm_type == 'video':
|
| 54 |
+
message = {
|
| 55 |
+
'role':
|
| 56 |
+
'user',
|
| 57 |
+
'content': [{
|
| 58 |
+
'type': 'video',
|
| 59 |
+
'video': 'https://modelscope-open.oss-cn-hangzhou.aliyuncs.com/images/baby.mp4'
|
| 60 |
+
}, {
|
| 61 |
+
'type': 'text',
|
| 62 |
+
'text': 'Describe this video.'
|
| 63 |
+
}]
|
| 64 |
+
}
|
| 65 |
+
elif mm_type == 'audio':
|
| 66 |
+
message = {
|
| 67 |
+
'role':
|
| 68 |
+
'user',
|
| 69 |
+
'content': [{
|
| 70 |
+
'type': 'audio',
|
| 71 |
+
'audio': 'http://modelscope-open.oss-cn-hangzhou.aliyuncs.com/images/weather.wav'
|
| 72 |
+
}, {
|
| 73 |
+
'type': 'text',
|
| 74 |
+
'text': 'What does this audio say?'
|
| 75 |
+
}]
|
| 76 |
+
}
|
| 77 |
+
return message
|
| 78 |
+
|
| 79 |
+
|
| 80 |
+
def get_data(mm_type: Literal['text', 'image', 'video', 'audio']):
|
| 81 |
+
data = {}
|
| 82 |
+
if mm_type == 'text':
|
| 83 |
+
messages = [{'role': 'user', 'content': 'who are you?'}]
|
| 84 |
+
elif mm_type == 'image':
|
| 85 |
+
# The number of <image> tags must be the same as len(images).
|
| 86 |
+
messages = [{'role': 'user', 'content': '<image>How many sheep are there in the picture?'}]
|
| 87 |
+
# Support URL/Path/base64/PIL.Image
|
| 88 |
+
data['images'] = ['http://modelscope-open.oss-cn-hangzhou.aliyuncs.com/images/animal.png']
|
| 89 |
+
elif mm_type == 'video':
|
| 90 |
+
messages = [{'role': 'user', 'content': '<video>Describe this video.'}]
|
| 91 |
+
data['videos'] = ['https://modelscope-open.oss-cn-hangzhou.aliyuncs.com/images/baby.mp4']
|
| 92 |
+
elif mm_type == 'audio':
|
| 93 |
+
messages = [{'role': 'user', 'content': '<audio>What does this audio say?'}]
|
| 94 |
+
data['audios'] = ['http://modelscope-open.oss-cn-hangzhou.aliyuncs.com/images/weather.wav']
|
| 95 |
+
data['messages'] = messages
|
| 96 |
+
return data
|
| 97 |
+
|
| 98 |
+
|
| 99 |
+
if __name__ == '__main__':
|
| 100 |
+
# The inference of the trained model can be referred to as:
|
| 101 |
+
# https://github.com/modelscope/ms-swift/tree/main/examples/notebook
|
| 102 |
+
from swift.llm import InferEngine, InferRequest, PtEngine, RequestConfig, load_dataset
|
| 103 |
+
from swift.plugin import InferStats
|
| 104 |
+
infer_backend = 'pt'
|
| 105 |
+
|
| 106 |
+
if infer_backend == 'pt':
|
| 107 |
+
model = 'Qwen/Qwen2-Audio-7B-Instruct'
|
| 108 |
+
mm_type = 'audio'
|
| 109 |
+
engine = PtEngine(model, max_batch_size=64)
|
| 110 |
+
elif infer_backend == 'vllm':
|
| 111 |
+
# test env: vllm==0.7.3, transformers==4.49.*
|
| 112 |
+
# The meaning of environment variables can be found at:
|
| 113 |
+
# https://swift.readthedocs.io/zh-cn/latest/Instruction/%E5%91%BD%E4%BB%A4%E8%A1%8C%E5%8F%82%E6%95%B0.html#id17
|
| 114 |
+
from swift.llm import VllmEngine
|
| 115 |
+
os.environ['MAX_PIXELS'] = '1003520'
|
| 116 |
+
os.environ['VIDEO_MAX_PIXELS'] = '50176'
|
| 117 |
+
os.environ['FPS_MAX_FRAMES'] = '12'
|
| 118 |
+
model = 'Qwen/Qwen2.5-VL-3B-Instruct'
|
| 119 |
+
# If you encounter insufficient GPU memory, please reduce `max_model_len` and set `max_num_seqs=5`.
|
| 120 |
+
engine = VllmEngine(model, max_model_len=8192, limit_mm_per_prompt={'image': 5, 'video': 2})
|
| 121 |
+
mm_type = 'image' # or 'video'
|
| 122 |
+
elif infer_backend == 'lmdeploy':
|
| 123 |
+
# test env: lmdeploy==0.7.1
|
| 124 |
+
from swift.llm import LmdeployEngine
|
| 125 |
+
model = 'OpenGVLab/InternVL2_5-1B'
|
| 126 |
+
engine = LmdeployEngine(model, vision_batch_size=8)
|
| 127 |
+
mm_type = 'image' # or 'video'
|
| 128 |
+
|
| 129 |
+
# infer dataset
|
| 130 |
+
if mm_type == 'audio':
|
| 131 |
+
dataset = 'speech_asr/speech_asr_aishell1_trainsets:validation#1000'
|
| 132 |
+
elif mm_type == 'image':
|
| 133 |
+
dataset = 'AI-ModelScope/LaTeX_OCR:small#1000'
|
| 134 |
+
elif mm_type == 'video':
|
| 135 |
+
dataset = 'swift/VideoChatGPT:Generic#100'
|
| 136 |
+
|
| 137 |
+
# Here, `load_dataset` is used for convenience; `infer_batch` does not require creating a dataset.
|
| 138 |
+
dataset = load_dataset([dataset], seed=42)[0]
|
| 139 |
+
print(f'dataset: {dataset}')
|
| 140 |
+
infer_requests = [InferRequest(**data) for data in dataset]
|
| 141 |
+
infer_batch(engine, infer_requests)
|
| 142 |
+
|
| 143 |
+
infer_stream(engine, InferRequest(messages=[get_message(mm_type)]))
|
| 144 |
+
# This writing is equivalent to the above writing.
|
| 145 |
+
infer_stream(engine, InferRequest(**get_data(mm_type)))
|
examples/infer/demo_reward_model.py
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright (c) Alibaba, Inc. and its affiliates.
|
| 2 |
+
import os
|
| 3 |
+
from typing import List
|
| 4 |
+
|
| 5 |
+
os.environ['CUDA_VISIBLE_DEVICES'] = '0'
|
| 6 |
+
|
| 7 |
+
|
| 8 |
+
def infer_batch(engine: 'InferEngine', infer_requests: List['InferRequest']):
|
| 9 |
+
resp_list = engine.infer(infer_requests)
|
| 10 |
+
print(f'messages0: {infer_requests[0].messages}')
|
| 11 |
+
print(f'response0: {resp_list[0].choices[0].message.content}')
|
| 12 |
+
|
| 13 |
+
|
| 14 |
+
if __name__ == '__main__':
|
| 15 |
+
from swift.llm import InferEngine, InferRequest, PtEngine, load_dataset
|
| 16 |
+
model = 'Shanghai_AI_Laboratory/internlm2-1_8b-reward'
|
| 17 |
+
engine = PtEngine(model, max_batch_size=64)
|
| 18 |
+
# Here, `load_dataset` is used for convenience; `infer_batch` does not require creating a dataset.
|
| 19 |
+
dataset = load_dataset(['AI-ModelScope/alpaca-gpt4-data-zh#1000'], seed=42)[0]
|
| 20 |
+
print(f'dataset: {dataset}')
|
| 21 |
+
infer_requests = [InferRequest(**data) for data in dataset]
|
| 22 |
+
infer_batch(engine, infer_requests)
|
| 23 |
+
|
| 24 |
+
messages = [{
|
| 25 |
+
'role': 'user',
|
| 26 |
+
'content': "Hello! What's your name?"
|
| 27 |
+
}, {
|
| 28 |
+
'role': 'assistant',
|
| 29 |
+
'content': 'My name is InternLM2! A helpful AI assistant. What can I do for you?'
|
| 30 |
+
}]
|
| 31 |
+
infer_batch(engine, [InferRequest(messages=messages)])
|
examples/infer/lmdeploy/ddp.sh
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
NPROC_PER_NODE=2 \
|
| 2 |
+
CUDA_VISIBLE_DEVICES=0,1 \
|
| 3 |
+
swift infer \
|
| 4 |
+
--model Qwen/Qwen2.5-7B-Instruct \
|
| 5 |
+
--infer_backend lmdeploy \
|
| 6 |
+
--val_dataset AI-ModelScope/alpaca-gpt4-data-zh#1000 \
|
| 7 |
+
--max_new_tokens 2048
|
examples/infer/lmdeploy/mllm_tp.sh
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
CUDA_VISIBLE_DEVICES=0,1 \
|
| 2 |
+
swift infer \
|
| 3 |
+
--model OpenGVLab/InternVL2_5-1B \
|
| 4 |
+
--infer_backend lmdeploy \
|
| 5 |
+
--val_dataset AI-ModelScope/captcha-images#1000 \
|
| 6 |
+
--tp 2 \
|
| 7 |
+
--vision_batch_size 8 \
|
| 8 |
+
--max_new_tokens 2048
|
examples/infer/pt/batch_ddp.sh
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# 18GB
|
| 2 |
+
NPROC_PER_NODE=4 \
|
| 3 |
+
CUDA_VISIBLE_DEVICES=0,1,2,3 \
|
| 4 |
+
swift infer \
|
| 5 |
+
--model Qwen/Qwen2.5-1.5B-Instruct \
|
| 6 |
+
--infer_backend pt \
|
| 7 |
+
--val_dataset AI-ModelScope/alpaca-gpt4-data-zh#1000 \
|
| 8 |
+
--max_batch_size 16 \
|
| 9 |
+
--max_new_tokens 512
|
examples/infer/pt/bert.sh
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Since `swift/test_lora` is trained by swift and contains an `args.json` file,
|
| 2 |
+
# there is no need to explicitly set `--model`, `--system`, etc., as they will be automatically read.
|
| 3 |
+
# To disable this behavior, please set `--load_args false`.
|
| 4 |
+
CUDA_VISIBLE_DEVICES=0 \
|
| 5 |
+
swift infer \
|
| 6 |
+
--adapters swift/test_bert \
|
| 7 |
+
--truncation_strategy right \
|
| 8 |
+
--max_length 512
|
examples/infer/pt/lora.sh
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Since `swift/test_lora` is trained by swift and contains an `args.json` file,
|
| 2 |
+
# there is no need to explicitly set `--model`, `--system`, etc., as they will be automatically read.
|
| 3 |
+
# To disable this behavior, please set `--load_args false`.
|
| 4 |
+
CUDA_VISIBLE_DEVICES=0 \
|
| 5 |
+
swift infer \
|
| 6 |
+
--adapters swift/test_lora \
|
| 7 |
+
--infer_backend pt \
|
| 8 |
+
--stream true \
|
| 9 |
+
--temperature 0 \
|
| 10 |
+
--max_new_tokens 2048
|
examples/infer/pt/mllm_device_map.sh
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
NPROC_PER_NODE=2 \
|
| 2 |
+
CUDA_VISIBLE_DEVICES=0,1,2,3 \
|
| 3 |
+
MAX_PIXELS=1003520 \
|
| 4 |
+
swift infer \
|
| 5 |
+
--model Qwen/Qwen2.5-VL-3B-Instruct \
|
| 6 |
+
--infer_backend pt \
|
| 7 |
+
--val_dataset AI-ModelScope/LaTeX_OCR#1000 \
|
| 8 |
+
--max_batch_size 16 \
|
| 9 |
+
--max_new_tokens 512
|
examples/infer/pt/prm.sh
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
CUDA_VISIBLE_DEVICES=0 \
|
| 2 |
+
swift infer \
|
| 3 |
+
--model Qwen/Qwen2.5-Math-PRM-7B \
|
| 4 |
+
--infer_backend pt
|
examples/infer/pt/reward_model.sh
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
CUDA_VISIBLE_DEVICES=0 \
|
| 2 |
+
swift infer \
|
| 3 |
+
--model Shanghai_AI_Laboratory/internlm2-1_8b-reward \
|
| 4 |
+
--val_dataset AI-ModelScope/alpaca-gpt4-data-zh#1000 \
|
| 5 |
+
--max_batch_size 64
|
examples/infer/vllm/ddp.sh
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
NPROC_PER_NODE=2 \
|
| 2 |
+
CUDA_VISIBLE_DEVICES=0,1 \
|
| 3 |
+
swift infer \
|
| 4 |
+
--model Qwen/Qwen2.5-7B-Instruct \
|
| 5 |
+
--infer_backend vllm \
|
| 6 |
+
--val_dataset AI-ModelScope/alpaca-gpt4-data-zh#1000 \
|
| 7 |
+
--gpu_memory_utilization 0.9 \
|
| 8 |
+
--max_model_len 8192 \
|
| 9 |
+
--max_new_tokens 2048
|
examples/infer/vllm/mllm_ddp.sh
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# You need to use flash-attn (manual installation) instead of xformers.
|
| 2 |
+
NPROC_PER_NODE=2 \
|
| 3 |
+
CUDA_VISIBLE_DEVICES=0,1 \
|
| 4 |
+
swift infer \
|
| 5 |
+
--model Qwen/Qwen2-Audio-7B-Instruct \
|
| 6 |
+
--infer_backend vllm \
|
| 7 |
+
--val_dataset speech_asr/speech_asr_aishell1_trainsets:validation#1000 \
|
| 8 |
+
--gpu_memory_utilization 0.9 \
|
| 9 |
+
--max_model_len 8192 \
|
| 10 |
+
--max_new_tokens 2048 \
|
| 11 |
+
--limit_mm_per_prompt '{"audio": 5}'
|
examples/infer/vllm/mllm_tp.sh
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
CUDA_VISIBLE_DEVICES=0,1 \
|
| 2 |
+
MAX_PIXELS=1003520 \
|
| 3 |
+
swift infer \
|
| 4 |
+
--model Qwen/Qwen2.5-VL-3B-Instruct \
|
| 5 |
+
--infer_backend vllm \
|
| 6 |
+
--val_dataset AI-ModelScope/LaTeX_OCR#1000 \
|
| 7 |
+
--gpu_memory_utilization 0.9 \
|
| 8 |
+
--tensor_parallel_size 2 \
|
| 9 |
+
--max_model_len 32768 \
|
| 10 |
+
--max_new_tokens 2048 \
|
| 11 |
+
--limit_mm_per_prompt '{"image": 5, "video": 2}'
|
examples/notebook/qwen2_5-self-cognition/infer.ipynb
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"cells": [
|
| 3 |
+
{
|
| 4 |
+
"cell_type": "markdown",
|
| 5 |
+
"metadata": {},
|
| 6 |
+
"source": [
|
| 7 |
+
"## Inference\n",
|
| 8 |
+
"We have trained a well-trained checkpoint through the `self-cognition-sft.ipynb` tutorial, and here we use `PtEngine` to do the inference on it."
|
| 9 |
+
]
|
| 10 |
+
},
|
| 11 |
+
{
|
| 12 |
+
"cell_type": "code",
|
| 13 |
+
"execution_count": 6,
|
| 14 |
+
"metadata": {},
|
| 15 |
+
"outputs": [],
|
| 16 |
+
"source": [
|
| 17 |
+
"# import some libraries\n",
|
| 18 |
+
"import os\n",
|
| 19 |
+
"os.environ['CUDA_VISIBLE_DEVICES'] = '0'\n",
|
| 20 |
+
"\n",
|
| 21 |
+
"from swift.llm import InferEngine, InferRequest, PtEngine, RequestConfig, get_template"
|
| 22 |
+
]
|
| 23 |
+
},
|
| 24 |
+
{
|
| 25 |
+
"cell_type": "code",
|
| 26 |
+
"execution_count": 7,
|
| 27 |
+
"metadata": {},
|
| 28 |
+
"outputs": [],
|
| 29 |
+
"source": [
|
| 30 |
+
"# Hyperparameters for inference\n",
|
| 31 |
+
"last_model_checkpoint = 'output/checkpoint-xxx'\n",
|
| 32 |
+
"\n",
|
| 33 |
+
"# model\n",
|
| 34 |
+
"model_id_or_path = 'Qwen/Qwen2.5-3B-Instruct' # model_id or model_path\n",
|
| 35 |
+
"system = 'You are a helpful assistant.'\n",
|
| 36 |
+
"infer_backend = 'pt'\n",
|
| 37 |
+
"\n",
|
| 38 |
+
"# generation_config\n",
|
| 39 |
+
"max_new_tokens = 512\n",
|
| 40 |
+
"temperature = 0\n",
|
| 41 |
+
"stream = True"
|
| 42 |
+
]
|
| 43 |
+
},
|
| 44 |
+
{
|
| 45 |
+
"cell_type": "code",
|
| 46 |
+
"execution_count": null,
|
| 47 |
+
"metadata": {},
|
| 48 |
+
"outputs": [],
|
| 49 |
+
"source": [
|
| 50 |
+
"# Get model and template, and load LoRA weights.\n",
|
| 51 |
+
"engine = PtEngine(model_id_or_path, adapters=[last_model_checkpoint])\n",
|
| 52 |
+
"template = get_template(engine.model_meta.template, engine.tokenizer, default_system=system)\n",
|
| 53 |
+
"# You can modify the `default_template` directly here, or pass it in during `engine.infer`.\n",
|
| 54 |
+
"engine.default_template = template"
|
| 55 |
+
]
|
| 56 |
+
},
|
| 57 |
+
{
|
| 58 |
+
"cell_type": "code",
|
| 59 |
+
"execution_count": 11,
|
| 60 |
+
"metadata": {},
|
| 61 |
+
"outputs": [
|
| 62 |
+
{
|
| 63 |
+
"name": "stdout",
|
| 64 |
+
"output_type": "stream",
|
| 65 |
+
"text": [
|
| 66 |
+
"query: who are you?\n",
|
| 67 |
+
"response: I am an artificial intelligence language model named Xiao Huang, developed by ModelScope. I can answer various questions and engage in conversation with humans. If you have any questions or need help, feel free to ask me at any time.\n",
|
| 68 |
+
"--------------------------------------------------\n",
|
| 69 |
+
"query: What should I do if I can't sleep at night?\n",
|
| 70 |
+
"response: If you're having trouble sleeping, there are several things you can try:\n",
|
| 71 |
+
"\n",
|
| 72 |
+
"1. Establish a regular sleep schedule: Try to go to bed and wake up at the same time every day, even on weekends.\n",
|
| 73 |
+
"\n",
|
| 74 |
+
"2. Create a relaxing bedtime routine: Engage in calming activities before bed, such as reading a book or taking a warm bath.\n",
|
| 75 |
+
"\n",
|
| 76 |
+
"3. Make your bedroom conducive to sleep: Keep your bedroom cool, dark, and quiet. Invest in comfortable bedding and pillows.\n",
|
| 77 |
+
"\n",
|
| 78 |
+
"4. Avoid stimulating activities before bed: Avoid using electronic devices, watching TV, or engaging in mentally stimulating activities before bed.\n",
|
| 79 |
+
"\n",
|
| 80 |
+
"5. Exercise regularly: Regular physical activity can help improve your sleep quality, but avoid exercising too close to bedtime.\n",
|
| 81 |
+
"\n",
|
| 82 |
+
"6. Manage stress: Practice relaxation techniques, such as deep breathing, meditation, or yoga, to help manage stress and promote better sleep.\n",
|
| 83 |
+
"\n",
|
| 84 |
+
"7. Limit caffeine and alcohol intake: Both caffeine and alcohol can disrupt sleep patterns, so it's best to limit their consumption, especially in the evening.\n",
|
| 85 |
+
"\n",
|
| 86 |
+
"8. Seek professional help: If you continue to have difficulty sleeping despite trying these strategies, consider seeking help from a healthcare provider or a sleep specialist.\n",
|
| 87 |
+
"--------------------------------------------------\n",
|
| 88 |
+
"query: 你是谁训练的?\n",
|
| 89 |
+
"response: 我是由魔搭团队训练和开发的。\n",
|
| 90 |
+
"--------------------------------------------------\n"
|
| 91 |
+
]
|
| 92 |
+
}
|
| 93 |
+
],
|
| 94 |
+
"source": [
|
| 95 |
+
"query_list = [\n",
|
| 96 |
+
" 'who are you?',\n",
|
| 97 |
+
" \"What should I do if I can't sleep at night?\",\n",
|
| 98 |
+
" '你是谁训练的?',\n",
|
| 99 |
+
"]\n",
|
| 100 |
+
"\n",
|
| 101 |
+
"def infer_stream(engine: InferEngine, infer_request: InferRequest):\n",
|
| 102 |
+
" request_config = RequestConfig(max_tokens=max_new_tokens, temperature=temperature, stream=True)\n",
|
| 103 |
+
" gen_list = engine.infer([infer_request], request_config)\n",
|
| 104 |
+
" query = infer_request.messages[0]['content']\n",
|
| 105 |
+
" print(f'query: {query}\\nresponse: ', end='')\n",
|
| 106 |
+
" for resp in gen_list[0]:\n",
|
| 107 |
+
" if resp is None:\n",
|
| 108 |
+
" continue\n",
|
| 109 |
+
" print(resp.choices[0].delta.content, end='', flush=True)\n",
|
| 110 |
+
" print()\n",
|
| 111 |
+
"\n",
|
| 112 |
+
"def infer(engine: InferEngine, infer_request: InferRequest):\n",
|
| 113 |
+
" request_config = RequestConfig(max_tokens=max_new_tokens, temperature=temperature)\n",
|
| 114 |
+
" resp_list = engine.infer([infer_request], request_config)\n",
|
| 115 |
+
" query = infer_request.messages[0]['content']\n",
|
| 116 |
+
" response = resp_list[0].choices[0].message.content\n",
|
| 117 |
+
" print(f'query: {query}')\n",
|
| 118 |
+
" print(f'response: {response}')\n",
|
| 119 |
+
"\n",
|
| 120 |
+
"infer_func = infer_stream if stream else infer\n",
|
| 121 |
+
"for query in query_list:\n",
|
| 122 |
+
" infer_func(engine, InferRequest(messages=[{'role': 'user', 'content': query}]))\n",
|
| 123 |
+
" print('-' * 50)"
|
| 124 |
+
]
|
| 125 |
+
}
|
| 126 |
+
],
|
| 127 |
+
"metadata": {
|
| 128 |
+
"kernelspec": {
|
| 129 |
+
"display_name": "test_py310",
|
| 130 |
+
"language": "python",
|
| 131 |
+
"name": "python3"
|
| 132 |
+
},
|
| 133 |
+
"language_info": {
|
| 134 |
+
"codemirror_mode": {
|
| 135 |
+
"name": "ipython",
|
| 136 |
+
"version": 3
|
| 137 |
+
},
|
| 138 |
+
"file_extension": ".py",
|
| 139 |
+
"mimetype": "text/x-python",
|
| 140 |
+
"name": "python",
|
| 141 |
+
"nbconvert_exporter": "python",
|
| 142 |
+
"pygments_lexer": "ipython3",
|
| 143 |
+
"version": "3.10.15"
|
| 144 |
+
}
|
| 145 |
+
},
|
| 146 |
+
"nbformat": 4,
|
| 147 |
+
"nbformat_minor": 2
|
| 148 |
+
}
|
examples/notebook/qwen2_5-self-cognition/infer.sh
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Here is the command-line style inference code.
|
| 2 |
+
CUDA_VISIBLE_DEVICES=0 \
|
| 3 |
+
swift infer \
|
| 4 |
+
--adapters output/vx-xxx/checkpoint-xxx \
|
| 5 |
+
--stream true \
|
| 6 |
+
--temperature 0 \
|
| 7 |
+
--max_new_tokens 2048
|
examples/notebook/qwen2_5-self-cognition/self-cognition-sft.ipynb
ADDED
|
@@ -0,0 +1,219 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"cells": [
|
| 3 |
+
{
|
| 4 |
+
"cell_type": "markdown",
|
| 5 |
+
"metadata": {},
|
| 6 |
+
"source": [
|
| 7 |
+
"## 10-minute self-cognition SFT\n",
|
| 8 |
+
"\n",
|
| 9 |
+
"Here is a demonstration of using python to perform self-cognition SFT of Qwen2.5-3B-Instruct. Through this tutorial, you can quickly understand some details of swift sft, which will be of great help in customizing ms-swift for you~\n",
|
| 10 |
+
"\n",
|
| 11 |
+
"Are you ready? Let's begin the journey...\n",
|
| 12 |
+
"\n",
|
| 13 |
+
"中文版:[魔搭教程](https://github.com/modelscope/modelscope-classroom/blob/main/LLM-tutorial/R.10%E5%88%86%E9%92%9F%E6%94%B9%E5%8F%98%E5%A4%A7%E6%A8%A1%E5%9E%8B%E8%87%AA%E6%88%91%E8%AE%A4%E7%9F%A5.ipynb)"
|
| 14 |
+
]
|
| 15 |
+
},
|
| 16 |
+
{
|
| 17 |
+
"cell_type": "code",
|
| 18 |
+
"execution_count": 1,
|
| 19 |
+
"metadata": {
|
| 20 |
+
"vscode": {
|
| 21 |
+
"languageId": "shellscript"
|
| 22 |
+
}
|
| 23 |
+
},
|
| 24 |
+
"outputs": [],
|
| 25 |
+
"source": [
|
| 26 |
+
"# # install ms-swift\n",
|
| 27 |
+
"# pip install ms-swift -U"
|
| 28 |
+
]
|
| 29 |
+
},
|
| 30 |
+
{
|
| 31 |
+
"cell_type": "code",
|
| 32 |
+
"execution_count": 2,
|
| 33 |
+
"metadata": {},
|
| 34 |
+
"outputs": [],
|
| 35 |
+
"source": [
|
| 36 |
+
"# import some libraries\n",
|
| 37 |
+
"import os\n",
|
| 38 |
+
"os.environ['CUDA_VISIBLE_DEVICES'] = '0'\n",
|
| 39 |
+
"\n",
|
| 40 |
+
"from swift.llm import get_model_tokenizer, load_dataset, get_template, EncodePreprocessor\n",
|
| 41 |
+
"from swift.utils import get_logger, find_all_linears, get_model_parameter_info, plot_images, seed_everything\n",
|
| 42 |
+
"from swift.tuners import Swift, LoraConfig\n",
|
| 43 |
+
"from swift.trainers import Seq2SeqTrainer, Seq2SeqTrainingArguments\n",
|
| 44 |
+
"from functools import partial\n",
|
| 45 |
+
"\n",
|
| 46 |
+
"logger = get_logger()\n",
|
| 47 |
+
"seed_everything(42)"
|
| 48 |
+
]
|
| 49 |
+
},
|
| 50 |
+
{
|
| 51 |
+
"cell_type": "code",
|
| 52 |
+
"execution_count": 3,
|
| 53 |
+
"metadata": {},
|
| 54 |
+
"outputs": [],
|
| 55 |
+
"source": [
|
| 56 |
+
"# Hyperparameters for training\n",
|
| 57 |
+
"# model\n",
|
| 58 |
+
"model_id_or_path = 'Qwen/Qwen2.5-3B-Instruct' # model_id or model_path\n",
|
| 59 |
+
"system = 'You are a helpful assistant.'\n",
|
| 60 |
+
"output_dir = 'output'\n",
|
| 61 |
+
"\n",
|
| 62 |
+
"# dataset\n",
|
| 63 |
+
"dataset = ['AI-ModelScope/alpaca-gpt4-data-zh#500', 'AI-ModelScope/alpaca-gpt4-data-en#500',\n",
|
| 64 |
+
" 'swift/self-cognition#500'] # dataset_id or dataset_path\n",
|
| 65 |
+
"data_seed = 42\n",
|
| 66 |
+
"max_length = 2048\n",
|
| 67 |
+
"split_dataset_ratio = 0.01 # Split validation set\n",
|
| 68 |
+
"num_proc = 4 # The number of processes for data loading.\n",
|
| 69 |
+
"# The following two parameters are used to override the placeholders in the self-cognition dataset.\n",
|
| 70 |
+
"model_name = ['小黄', 'Xiao Huang'] # The Chinese name and English name of the model\n",
|
| 71 |
+
"model_author = ['魔搭', 'ModelScope'] # The Chinese name and English name of the model author\n",
|
| 72 |
+
"\n",
|
| 73 |
+
"# lora\n",
|
| 74 |
+
"lora_rank = 8\n",
|
| 75 |
+
"lora_alpha = 32\n",
|
| 76 |
+
"\n",
|
| 77 |
+
"# training_args\n",
|
| 78 |
+
"training_args = Seq2SeqTrainingArguments(\n",
|
| 79 |
+
" output_dir=output_dir,\n",
|
| 80 |
+
" learning_rate=1e-4,\n",
|
| 81 |
+
" per_device_train_batch_size=1,\n",
|
| 82 |
+
" per_device_eval_batch_size=1,\n",
|
| 83 |
+
" gradient_checkpointing=True,\n",
|
| 84 |
+
" weight_decay=0.1,\n",
|
| 85 |
+
" lr_scheduler_type='cosine',\n",
|
| 86 |
+
" warmup_ratio=0.05,\n",
|
| 87 |
+
" report_to=['tensorboard'],\n",
|
| 88 |
+
" logging_first_step=True,\n",
|
| 89 |
+
" save_strategy='steps',\n",
|
| 90 |
+
" save_steps=50,\n",
|
| 91 |
+
" eval_strategy='steps',\n",
|
| 92 |
+
" eval_steps=50,\n",
|
| 93 |
+
" gradient_accumulation_steps=16,\n",
|
| 94 |
+
" num_train_epochs=1,\n",
|
| 95 |
+
" metric_for_best_model='loss',\n",
|
| 96 |
+
" save_total_limit=2,\n",
|
| 97 |
+
" logging_steps=5,\n",
|
| 98 |
+
" dataloader_num_workers=1,\n",
|
| 99 |
+
" data_seed=data_seed,\n",
|
| 100 |
+
")\n",
|
| 101 |
+
"\n",
|
| 102 |
+
"output_dir = os.path.abspath(os.path.expanduser(output_dir))\n",
|
| 103 |
+
"logger.info(f'output_dir: {output_dir}')"
|
| 104 |
+
]
|
| 105 |
+
},
|
| 106 |
+
{
|
| 107 |
+
"cell_type": "code",
|
| 108 |
+
"execution_count": 4,
|
| 109 |
+
"metadata": {},
|
| 110 |
+
"outputs": [],
|
| 111 |
+
"source": [
|
| 112 |
+
"# Obtain the model and template, and add a trainable Lora layer on the model.\n",
|
| 113 |
+
"model, tokenizer = get_model_tokenizer(model_id_or_path)\n",
|
| 114 |
+
"logger.info(f'model_info: {model.model_info}')\n",
|
| 115 |
+
"template = get_template(model.model_meta.template, tokenizer, default_system=system, max_length=max_length)\n",
|
| 116 |
+
"template.set_mode('train')\n",
|
| 117 |
+
"\n",
|
| 118 |
+
"target_modules = find_all_linears(model)\n",
|
| 119 |
+
"lora_config = LoraConfig(task_type='CAUSAL_LM', r=lora_rank, lora_alpha=lora_alpha,\n",
|
| 120 |
+
" target_modules=target_modules)\n",
|
| 121 |
+
"model = Swift.prepare_model(model, lora_config)\n",
|
| 122 |
+
"logger.info(f'lora_config: {lora_config}')\n",
|
| 123 |
+
"\n",
|
| 124 |
+
"# Print model structure and trainable parameters.\n",
|
| 125 |
+
"logger.info(f'model: {model}')\n",
|
| 126 |
+
"model_parameter_info = get_model_parameter_info(model)\n",
|
| 127 |
+
"logger.info(f'model_parameter_info: {model_parameter_info}')"
|
| 128 |
+
]
|
| 129 |
+
},
|
| 130 |
+
{
|
| 131 |
+
"cell_type": "code",
|
| 132 |
+
"execution_count": 5,
|
| 133 |
+
"metadata": {},
|
| 134 |
+
"outputs": [],
|
| 135 |
+
"source": [
|
| 136 |
+
"# Download and load the dataset, split it into a training set and a validation set,\n",
|
| 137 |
+
"# and encode the text data into tokens.\n",
|
| 138 |
+
"train_dataset, val_dataset = load_dataset(dataset, split_dataset_ratio=split_dataset_ratio, num_proc=num_proc,\n",
|
| 139 |
+
" model_name=model_name, model_author=model_author, seed=data_seed)\n",
|
| 140 |
+
"\n",
|
| 141 |
+
"logger.info(f'train_dataset: {train_dataset}')\n",
|
| 142 |
+
"logger.info(f'val_dataset: {val_dataset}')\n",
|
| 143 |
+
"logger.info(f'train_dataset[0]: {train_dataset[0]}')\n",
|
| 144 |
+
"\n",
|
| 145 |
+
"train_dataset = EncodePreprocessor(template=template)(train_dataset, num_proc=num_proc)\n",
|
| 146 |
+
"val_dataset = EncodePreprocessor(template=template)(val_dataset, num_proc=num_proc)\n",
|
| 147 |
+
"logger.info(f'encoded_train_dataset[0]: {train_dataset[0]}')\n",
|
| 148 |
+
"\n",
|
| 149 |
+
"# Print a sample\n",
|
| 150 |
+
"template.print_inputs(train_dataset[0])"
|
| 151 |
+
]
|
| 152 |
+
},
|
| 153 |
+
{
|
| 154 |
+
"cell_type": "code",
|
| 155 |
+
"execution_count": 6,
|
| 156 |
+
"metadata": {},
|
| 157 |
+
"outputs": [],
|
| 158 |
+
"source": [
|
| 159 |
+
"# Get the trainer and start the training.\n",
|
| 160 |
+
"model.enable_input_require_grads() # Compatible with gradient checkpointing\n",
|
| 161 |
+
"trainer = Seq2SeqTrainer(\n",
|
| 162 |
+
" model=model,\n",
|
| 163 |
+
" args=training_args,\n",
|
| 164 |
+
" data_collator=template.data_collator,\n",
|
| 165 |
+
" train_dataset=train_dataset,\n",
|
| 166 |
+
" eval_dataset=val_dataset,\n",
|
| 167 |
+
" template=template,\n",
|
| 168 |
+
")\n",
|
| 169 |
+
"trainer.train()\n",
|
| 170 |
+
"\n",
|
| 171 |
+
"last_model_checkpoint = trainer.state.last_model_checkpoint\n",
|
| 172 |
+
"logger.info(f'last_model_checkpoint: {last_model_checkpoint}')"
|
| 173 |
+
]
|
| 174 |
+
},
|
| 175 |
+
{
|
| 176 |
+
"cell_type": "code",
|
| 177 |
+
"execution_count": null,
|
| 178 |
+
"metadata": {},
|
| 179 |
+
"outputs": [],
|
| 180 |
+
"source": [
|
| 181 |
+
"# Visualize the training loss.\n",
|
| 182 |
+
"# You can also use the TensorBoard visualization interface during training by entering\n",
|
| 183 |
+
"# `tensorboard --logdir '{output_dir}/runs'` at the command line.\n",
|
| 184 |
+
"images_dir = os.path.join(output_dir, 'images')\n",
|
| 185 |
+
"logger.info(f'images_dir: {images_dir}')\n",
|
| 186 |
+
"plot_images(images_dir, training_args.logging_dir, ['train/loss'], 0.9) # save images\n",
|
| 187 |
+
"\n",
|
| 188 |
+
"# Read and display the image.\n",
|
| 189 |
+
"# The light yellow line represents the actual loss value,\n",
|
| 190 |
+
"# while the yellow line represents the loss value smoothed with a smoothing factor of 0.9.\n",
|
| 191 |
+
"from IPython.display import display\n",
|
| 192 |
+
"from PIL import Image\n",
|
| 193 |
+
"image = Image.open(os.path.join(images_dir, 'train_loss.png'))\n",
|
| 194 |
+
"display(image)"
|
| 195 |
+
]
|
| 196 |
+
}
|
| 197 |
+
],
|
| 198 |
+
"metadata": {
|
| 199 |
+
"kernelspec": {
|
| 200 |
+
"display_name": "py310",
|
| 201 |
+
"language": "python",
|
| 202 |
+
"name": "python3"
|
| 203 |
+
},
|
| 204 |
+
"language_info": {
|
| 205 |
+
"codemirror_mode": {
|
| 206 |
+
"name": "ipython",
|
| 207 |
+
"version": 3
|
| 208 |
+
},
|
| 209 |
+
"file_extension": ".py",
|
| 210 |
+
"mimetype": "text/x-python",
|
| 211 |
+
"name": "python",
|
| 212 |
+
"nbconvert_exporter": "python",
|
| 213 |
+
"pygments_lexer": "ipython3",
|
| 214 |
+
"version": "3.10.16"
|
| 215 |
+
}
|
| 216 |
+
},
|
| 217 |
+
"nbformat": 4,
|
| 218 |
+
"nbformat_minor": 2
|
| 219 |
+
}
|
examples/notebook/qwen2_5-self-cognition/sft.sh
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Here is the command-line style training code.
|
| 2 |
+
# 22GB
|
| 3 |
+
CUDA_VISIBLE_DEVICES=0 \
|
| 4 |
+
swift sft \
|
| 5 |
+
--model Qwen/Qwen2.5-3B-Instruct \
|
| 6 |
+
--train_type lora \
|
| 7 |
+
--dataset 'AI-ModelScope/alpaca-gpt4-data-zh#500' \
|
| 8 |
+
'AI-ModelScope/alpaca-gpt4-data-en#500' \
|
| 9 |
+
'swift/self-cognition#500' \
|
| 10 |
+
--torch_dtype bfloat16 \
|
| 11 |
+
--num_train_epochs 1 \
|
| 12 |
+
--per_device_train_batch_size 1 \
|
| 13 |
+
--per_device_eval_batch_size 1 \
|
| 14 |
+
--learning_rate 1e-4 \
|
| 15 |
+
--lora_rank 8 \
|
| 16 |
+
--lora_alpha 32 \
|
| 17 |
+
--target_modules all-linear \
|
| 18 |
+
--gradient_accumulation_steps 16 \
|
| 19 |
+
--eval_steps 50 \
|
| 20 |
+
--save_steps 50 \
|
| 21 |
+
--save_total_limit 2 \
|
| 22 |
+
--logging_steps 5 \
|
| 23 |
+
--max_length 2048 \
|
| 24 |
+
--output_dir output \
|
| 25 |
+
--system 'You are a helpful assistant.' \
|
| 26 |
+
--warmup_ratio 0.05 \
|
| 27 |
+
--dataloader_num_workers 4 \
|
| 28 |
+
--dataset_num_proc 4 \
|
| 29 |
+
--model_name 小黄 'Xiao Huang' \
|
| 30 |
+
--model_author '魔搭' 'ModelScope'
|
examples/notebook/qwen2_5-vl-grounding/zh.ipynb
ADDED
|
@@ -0,0 +1,261 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"cells": [
|
| 3 |
+
{
|
| 4 |
+
"cell_type": "markdown",
|
| 5 |
+
"metadata": {},
|
| 6 |
+
"source": [
|
| 7 |
+
"## Qwen2.5-VL Grounding任务\n",
|
| 8 |
+
"\n",
|
| 9 |
+
"这里介绍使用qwen2.5-vl进行grounding任务的全流程介绍。当然,你也可以使用internvl2.5或者qwen2-vl等多模态模型。\n",
|
| 10 |
+
"\n",
|
| 11 |
+
"我们使用[AI-ModelScope/coco](https://modelscope.cn/datasets/AI-ModelScope/coco)数据集来展示整个流程。\n",
|
| 12 |
+
"\n",
|
| 13 |
+
"如果需要使用自定义数据集,需要符合以下格式:"
|
| 14 |
+
]
|
| 15 |
+
},
|
| 16 |
+
{
|
| 17 |
+
"cell_type": "code",
|
| 18 |
+
"execution_count": null,
|
| 19 |
+
"metadata": {},
|
| 20 |
+
"outputs": [],
|
| 21 |
+
"source": [
|
| 22 |
+
"{\"messages\": [{\"role\": \"system\", \"content\": \"You are a helpful assistant.\"}, {\"role\": \"user\", \"content\": \"<image>描述图像\"}, {\"role\": \"assistant\", \"content\": \"<ref-object><bbox>和<ref-object><bbox>正在沙滩上玩耍\"}], \"images\": [\"/xxx/x.jpg\"], \"objects\": {\"ref\": [\"一只狗\", \"一个女人\"], \"bbox\": [[331.5, 761.4, 853.5, 1594.8], [676.5, 685.8, 1099.5, 1427.4]]}}\n",
|
| 23 |
+
"{\"messages\": [{\"role\": \"system\", \"content\": \"You are a helpful assistant.\"}, {\"role\": \"user\", \"content\": \"<image>找到图像中的<ref-object>\"}, {\"role\": \"assistant\", \"content\": \"<bbox><bbox>\"}], \"images\": [\"/xxx/x.jpg\"], \"objects\": {\"ref\": [\"羊\"], \"bbox\": [[90.9, 160.8, 135, 212.8], [360.9, 480.8, 495, 532.8]]}}\n",
|
| 24 |
+
"{\"messages\": [{\"role\": \"system\", \"content\": \"You are a helpful assistant.\"}, {\"role\": \"user\", \"content\": \"<image>帮我打开谷歌浏览器\"}, {\"role\": \"assistant\", \"content\": \"Action: click(start_box='<bbox>')\"}], \"images\": [\"/xxx/x.jpg\"], \"objects\": {\"ref\": [], \"bbox\": [[615, 226]]}}"
|
| 25 |
+
]
|
| 26 |
+
},
|
| 27 |
+
{
|
| 28 |
+
"cell_type": "markdown",
|
| 29 |
+
"metadata": {},
|
| 30 |
+
"source": [
|
| 31 |
+
"ms-swift在预处理数据集时,会使用模型特有的grounding任务格式,将objects中的ref填充`<ref-object>`,bbox会根据模型类型选择是否进行0-1000的归一化,并填充`<bbox>`。例如:qwen2-vl为`f'<|object_ref_start|>羊<|object_ref_end|>'`和`f'<|box_start|>(101,201),(150,266)<|box_end|>'`(qwen2.5-vl不进行归一化,只将float型转成int型),internvl2.5则为`f'<ref>羊</ref>'`和`f'<box>[[101, 201, 150, 266]]</box>'`等。\n",
|
| 32 |
+
"\n",
|
| 33 |
+
"\n",
|
| 34 |
+
"训练之前,你需要从main分支安装ms-swift:"
|
| 35 |
+
]
|
| 36 |
+
},
|
| 37 |
+
{
|
| 38 |
+
"cell_type": "code",
|
| 39 |
+
"execution_count": null,
|
| 40 |
+
"metadata": {
|
| 41 |
+
"vscode": {
|
| 42 |
+
"languageId": "shellscript"
|
| 43 |
+
}
|
| 44 |
+
},
|
| 45 |
+
"outputs": [],
|
| 46 |
+
"source": [
|
| 47 |
+
"# pip install git+https://github.com/modelscope/ms-swift.git\n",
|
| 48 |
+
"\n",
|
| 49 |
+
"git clone https://github.com/modelscope/ms-swift.git\n",
|
| 50 |
+
"cd ms-swift\n",
|
| 51 |
+
"pip install -e .\n",
|
| 52 |
+
"\n",
|
| 53 |
+
"# 如果'transformers>=4.49'已经发版,则无需从main分支安装\n",
|
| 54 |
+
"pip install git+https://github.com/huggingface/transformers.git"
|
| 55 |
+
]
|
| 56 |
+
},
|
| 57 |
+
{
|
| 58 |
+
"cell_type": "markdown",
|
| 59 |
+
"metadata": {},
|
| 60 |
+
"source": [
|
| 61 |
+
"然后,使用以下shell进行训练。MAX_PIXELS的参数含义可以查看[这里](https://swift.readthedocs.io/en/latest/Instruction/Command-line-parameters.html#specific-model-arguments)\n",
|
| 62 |
+
"\n",
|
| 63 |
+
"### 训练\n",
|
| 64 |
+
"\n",
|
| 65 |
+
"单卡训练:"
|
| 66 |
+
]
|
| 67 |
+
},
|
| 68 |
+
{
|
| 69 |
+
"cell_type": "code",
|
| 70 |
+
"execution_count": null,
|
| 71 |
+
"metadata": {
|
| 72 |
+
"vscode": {
|
| 73 |
+
"languageId": "shellscript"
|
| 74 |
+
}
|
| 75 |
+
},
|
| 76 |
+
"outputs": [],
|
| 77 |
+
"source": [
|
| 78 |
+
"# 显存资源:24GiB\n",
|
| 79 |
+
"CUDA_VISIBLE_DEVICES=0 \\\n",
|
| 80 |
+
"MAX_PIXELS=1003520 \\\n",
|
| 81 |
+
"swift sft \\\n",
|
| 82 |
+
" --model Qwen/Qwen2.5-VL-7B-Instruct \\\n",
|
| 83 |
+
" --dataset 'AI-ModelScope/coco#2000' \\\n",
|
| 84 |
+
" --train_type lora \\\n",
|
| 85 |
+
" --torch_dtype bfloat16 \\\n",
|
| 86 |
+
" --num_train_epochs 1 \\\n",
|
| 87 |
+
" --per_device_train_batch_size 1 \\\n",
|
| 88 |
+
" --per_device_eval_batch_size 1 \\\n",
|
| 89 |
+
" --learning_rate 1e-4 \\\n",
|
| 90 |
+
" --lora_rank 8 \\\n",
|
| 91 |
+
" --lora_alpha 32 \\\n",
|
| 92 |
+
" --target_modules all-linear \\\n",
|
| 93 |
+
" --freeze_vit true \\\n",
|
| 94 |
+
" --gradient_accumulation_steps 16 \\\n",
|
| 95 |
+
" --eval_steps 100 \\\n",
|
| 96 |
+
" --save_steps 100 \\\n",
|
| 97 |
+
" --save_total_limit 5 \\\n",
|
| 98 |
+
" --logging_steps 5 \\\n",
|
| 99 |
+
" --max_length 2048 \\\n",
|
| 100 |
+
" --output_dir output \\\n",
|
| 101 |
+
" --warmup_ratio 0.05 \\\n",
|
| 102 |
+
" --dataloader_num_workers 4 \\\n",
|
| 103 |
+
" --dataset_num_proc 4"
|
| 104 |
+
]
|
| 105 |
+
},
|
| 106 |
+
{
|
| 107 |
+
"cell_type": "markdown",
|
| 108 |
+
"metadata": {},
|
| 109 |
+
"source": [
|
| 110 |
+
"然后我们将训练的模型推送到ModelScope:"
|
| 111 |
+
]
|
| 112 |
+
},
|
| 113 |
+
{
|
| 114 |
+
"cell_type": "code",
|
| 115 |
+
"execution_count": null,
|
| 116 |
+
"metadata": {
|
| 117 |
+
"vscode": {
|
| 118 |
+
"languageId": "shellscript"
|
| 119 |
+
}
|
| 120 |
+
},
|
| 121 |
+
"outputs": [],
|
| 122 |
+
"source": [
|
| 123 |
+
"swift export \\\n",
|
| 124 |
+
" --adapters output/vx-xxx/checkpoint-xxx \\\n",
|
| 125 |
+
" --push_to_hub true \\\n",
|
| 126 |
+
" --hub_model_id '<model-id>' \\\n",
|
| 127 |
+
" --hub_token '<sdk-token>' \\\n",
|
| 128 |
+
" --use_hf false"
|
| 129 |
+
]
|
| 130 |
+
},
|
| 131 |
+
{
|
| 132 |
+
"cell_type": "markdown",
|
| 133 |
+
"metadata": {},
|
| 134 |
+
"source": [
|
| 135 |
+
"我们将训练的checkpoint推送到[swift/test_grounding](https://modelscope.cn/models/swift/test_grounding)。\n",
|
| 136 |
+
"\n",
|
| 137 |
+
"### 推理\n",
|
| 138 |
+
"\n",
|
| 139 |
+
"训练完成后,我们使用以下命令对训练时的验证集进行推理。这里`--adapters`需要替换成训练生成的last checkpoint文件夹。由于adapters文件夹中包含了训练的参数文件,因此不需要额外指定`--model`。\n",
|
| 140 |
+
"\n",
|
| 141 |
+
"若模型采用的是绝对坐标的方式进行输出,推理时请提前对图像进行缩放而不使用`MAX_PIXELS`或者`--max_pixels`。若是千分位坐标,则没有此约束。\n",
|
| 142 |
+
"\n",
|
| 143 |
+
"由于我们已经将训练后的checkpoint推送到了ModelScope上,以下推理脚本可以直接运行:"
|
| 144 |
+
]
|
| 145 |
+
},
|
| 146 |
+
{
|
| 147 |
+
"cell_type": "code",
|
| 148 |
+
"execution_count": null,
|
| 149 |
+
"metadata": {
|
| 150 |
+
"vscode": {
|
| 151 |
+
"languageId": "shellscript"
|
| 152 |
+
}
|
| 153 |
+
},
|
| 154 |
+
"outputs": [],
|
| 155 |
+
"source": [
|
| 156 |
+
"CUDA_VISIBLE_DEVICES=0 \\\n",
|
| 157 |
+
"swift infer \\\n",
|
| 158 |
+
" --adapters swift/test_grounding \\\n",
|
| 159 |
+
" --stream true \\\n",
|
| 160 |
+
" --load_data_args true \\\n",
|
| 161 |
+
" --max_new_tokens 512 \\\n",
|
| 162 |
+
" --dataset_num_proc 4"
|
| 163 |
+
]
|
| 164 |
+
},
|
| 165 |
+
{
|
| 166 |
+
"cell_type": "markdown",
|
| 167 |
+
"metadata": {},
|
| 168 |
+
"source": [
|
| 169 |
+
"我们也可以使用代码的方式进行推理:\n",
|
| 170 |
+
"\n",
|
| 171 |
+
"单样本推理的例子可以查看[这里](https://github.com/modelscope/ms-swift/blob/main/examples/infer/demo_grounding.py)。"
|
| 172 |
+
]
|
| 173 |
+
},
|
| 174 |
+
{
|
| 175 |
+
"cell_type": "code",
|
| 176 |
+
"execution_count": 1,
|
| 177 |
+
"metadata": {},
|
| 178 |
+
"outputs": [],
|
| 179 |
+
"source": [
|
| 180 |
+
"import os\n",
|
| 181 |
+
"os.environ['CUDA_VISIBLE_DEVICES'] = '0'\n",
|
| 182 |
+
"\n",
|
| 183 |
+
"import re\n",
|
| 184 |
+
"from typing import Literal\n",
|
| 185 |
+
"from swift.llm import (\n",
|
| 186 |
+
" PtEngine, RequestConfig, BaseArguments, InferRequest, safe_snapshot_download, draw_bbox, load_image, load_dataset, InferEngine\n",
|
| 187 |
+
")\n",
|
| 188 |
+
"from IPython.display import display\n",
|
| 189 |
+
"\n",
|
| 190 |
+
"def infer_stream(engine: InferEngine, infer_request: InferRequest):\n",
|
| 191 |
+
" request_config = RequestConfig(max_tokens=512, temperature=0, stream=True)\n",
|
| 192 |
+
" gen_list = engine.infer([infer_request], request_config)\n",
|
| 193 |
+
" query = infer_request.messages[0]['content']\n",
|
| 194 |
+
" print(f'query: {query}\\nresponse: ', end='')\n",
|
| 195 |
+
" response = ''\n",
|
| 196 |
+
" for resp in gen_list[0]:\n",
|
| 197 |
+
" if resp is None:\n",
|
| 198 |
+
" continue\n",
|
| 199 |
+
" delta = resp.choices[0].delta.content\n",
|
| 200 |
+
" response += delta\n",
|
| 201 |
+
" print(delta, end='', flush=True)\n",
|
| 202 |
+
" print()\n",
|
| 203 |
+
" return response\n",
|
| 204 |
+
"\n",
|
| 205 |
+
"def draw_bbox_qwen2_vl(image, response, norm_bbox: Literal['norm1000', 'none']):\n",
|
| 206 |
+
" matches = re.findall(\n",
|
| 207 |
+
" r'<\\|object_ref_start\\|>(.*?)<\\|object_ref_end\\|><\\|box_start\\|>\\((\\d+),(\\d+)\\),\\((\\d+),(\\d+)\\)<\\|box_end\\|>',\n",
|
| 208 |
+
" response)\n",
|
| 209 |
+
" ref = []\n",
|
| 210 |
+
" bbox = []\n",
|
| 211 |
+
" for match_ in matches:\n",
|
| 212 |
+
" ref.append(match_[0])\n",
|
| 213 |
+
" bbox.append(list(match_[1:]))\n",
|
| 214 |
+
" draw_bbox(image, ref, bbox, norm_bbox=norm_bbox)\n",
|
| 215 |
+
"\n",
|
| 216 |
+
"# 下载权重,并加载模型\n",
|
| 217 |
+
"output_dir = 'images_bbox'\n",
|
| 218 |
+
"model_id_or_path = 'swift/test_grounding'\n",
|
| 219 |
+
"output_dir = os.path.abspath(os.path.expanduser(output_dir))\n",
|
| 220 |
+
"adapter_path = safe_snapshot_download(model_id_or_path)\n",
|
| 221 |
+
"args = BaseArguments.from_pretrained(adapter_path)\n",
|
| 222 |
+
"engine = PtEngine(args.model, adapters=[adapter_path])\n",
|
| 223 |
+
"\n",
|
| 224 |
+
"# 获取验证集并推理\n",
|
| 225 |
+
"_, val_dataset = load_dataset(args.dataset, split_dataset_ratio=args.split_dataset_ratio, num_proc=4, seed=args.seed)\n",
|
| 226 |
+
"print(f'output_dir: {output_dir}')\n",
|
| 227 |
+
"os.makedirs(output_dir, exist_ok=True)\n",
|
| 228 |
+
"for i, data in enumerate(val_dataset):\n",
|
| 229 |
+
" image = data['images'][0]\n",
|
| 230 |
+
" image = load_image(image['bytes'] or image['path'])\n",
|
| 231 |
+
" display(image)\n",
|
| 232 |
+
" response = infer_stream(engine, InferRequest(**data))\n",
|
| 233 |
+
" draw_bbox_qwen2_vl(image, response, norm_bbox=args.norm_bbox)\n",
|
| 234 |
+
" print('-' * 50)\n",
|
| 235 |
+
" image.save(os.path.join(output_dir, f'{i}.png'))\n",
|
| 236 |
+
" display(image)"
|
| 237 |
+
]
|
| 238 |
+
}
|
| 239 |
+
],
|
| 240 |
+
"metadata": {
|
| 241 |
+
"kernelspec": {
|
| 242 |
+
"display_name": "test_py310",
|
| 243 |
+
"language": "python",
|
| 244 |
+
"name": "python3"
|
| 245 |
+
},
|
| 246 |
+
"language_info": {
|
| 247 |
+
"codemirror_mode": {
|
| 248 |
+
"name": "ipython",
|
| 249 |
+
"version": 3
|
| 250 |
+
},
|
| 251 |
+
"file_extension": ".py",
|
| 252 |
+
"mimetype": "text/x-python",
|
| 253 |
+
"name": "python",
|
| 254 |
+
"nbconvert_exporter": "python",
|
| 255 |
+
"pygments_lexer": "ipython3",
|
| 256 |
+
"version": "3.11.10"
|
| 257 |
+
}
|
| 258 |
+
},
|
| 259 |
+
"nbformat": 4,
|
| 260 |
+
"nbformat_minor": 2
|
| 261 |
+
}
|
examples/notebook/qwen2vl-ocr/infer.ipynb
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"cells": [
|
| 3 |
+
{
|
| 4 |
+
"cell_type": "markdown",
|
| 5 |
+
"metadata": {},
|
| 6 |
+
"source": [
|
| 7 |
+
"## Inference\n",
|
| 8 |
+
"We have trained a well-trained checkpoint through the `ocr-sft.ipynb` tutorial, and here we use `PtEngine` to do the inference on it."
|
| 9 |
+
]
|
| 10 |
+
},
|
| 11 |
+
{
|
| 12 |
+
"cell_type": "code",
|
| 13 |
+
"execution_count": null,
|
| 14 |
+
"metadata": {},
|
| 15 |
+
"outputs": [],
|
| 16 |
+
"source": [
|
| 17 |
+
"# import some libraries\n",
|
| 18 |
+
"import os\n",
|
| 19 |
+
"os.environ['CUDA_VISIBLE_DEVICES'] = '0'\n",
|
| 20 |
+
"\n",
|
| 21 |
+
"from swift.llm import (\n",
|
| 22 |
+
" InferEngine, InferRequest, PtEngine, RequestConfig, get_template, load_dataset, load_image\n",
|
| 23 |
+
")\n",
|
| 24 |
+
"from swift.utils import get_model_parameter_info, get_logger, seed_everything\n",
|
| 25 |
+
"logger = get_logger()\n",
|
| 26 |
+
"seed_everything(42)"
|
| 27 |
+
]
|
| 28 |
+
},
|
| 29 |
+
{
|
| 30 |
+
"cell_type": "code",
|
| 31 |
+
"execution_count": 2,
|
| 32 |
+
"metadata": {},
|
| 33 |
+
"outputs": [],
|
| 34 |
+
"source": [
|
| 35 |
+
"# Hyperparameters for inference\n",
|
| 36 |
+
"last_model_checkpoint = 'output/checkpoint-xxx'\n",
|
| 37 |
+
"\n",
|
| 38 |
+
"# model\n",
|
| 39 |
+
"model_id_or_path = 'Qwen/Qwen2-VL-2B-Instruct' # model_id or model_path\n",
|
| 40 |
+
"system = None\n",
|
| 41 |
+
"infer_backend = 'pt'\n",
|
| 42 |
+
"\n",
|
| 43 |
+
"# dataset\n",
|
| 44 |
+
"dataset = ['AI-ModelScope/LaTeX_OCR#20000']\n",
|
| 45 |
+
"data_seed = 42\n",
|
| 46 |
+
"split_dataset_ratio = 0.01\n",
|
| 47 |
+
"num_proc = 4\n",
|
| 48 |
+
"strict = False\n",
|
| 49 |
+
"\n",
|
| 50 |
+
"# generation_config\n",
|
| 51 |
+
"max_new_tokens = 512\n",
|
| 52 |
+
"temperature = 0\n",
|
| 53 |
+
"stream = True"
|
| 54 |
+
]
|
| 55 |
+
},
|
| 56 |
+
{
|
| 57 |
+
"cell_type": "code",
|
| 58 |
+
"execution_count": null,
|
| 59 |
+
"metadata": {},
|
| 60 |
+
"outputs": [],
|
| 61 |
+
"source": [
|
| 62 |
+
"# Get model and template, and load LoRA weights.\n",
|
| 63 |
+
"engine = PtEngine(model_id_or_path, adapters=[last_model_checkpoint])\n",
|
| 64 |
+
"template = get_template(engine.model_meta.template, engine.tokenizer, default_system=system)\n",
|
| 65 |
+
"# The default mode of the template is 'pt', so there is no need to make any changes.\n",
|
| 66 |
+
"# template.set_mode('pt')\n",
|
| 67 |
+
"\n",
|
| 68 |
+
"model_parameter_info = get_model_parameter_info(engine.model)\n",
|
| 69 |
+
"logger.info(f'model_parameter_info: {model_parameter_info}')"
|
| 70 |
+
]
|
| 71 |
+
},
|
| 72 |
+
{
|
| 73 |
+
"cell_type": "code",
|
| 74 |
+
"execution_count": null,
|
| 75 |
+
"metadata": {},
|
| 76 |
+
"outputs": [],
|
| 77 |
+
"source": [
|
| 78 |
+
"# Due to the data_seed setting, the validation set here is the same as the validation set used during training.\n",
|
| 79 |
+
"_, val_dataset = load_dataset(dataset, split_dataset_ratio=split_dataset_ratio, num_proc=num_proc,\n",
|
| 80 |
+
" strict=strict, seed=data_seed)\n",
|
| 81 |
+
"val_dataset = val_dataset.select(range(10)) # Take the first 10 items"
|
| 82 |
+
]
|
| 83 |
+
},
|
| 84 |
+
{
|
| 85 |
+
"cell_type": "code",
|
| 86 |
+
"execution_count": null,
|
| 87 |
+
"metadata": {},
|
| 88 |
+
"outputs": [],
|
| 89 |
+
"source": [
|
| 90 |
+
"# Streaming inference and save images from the validation set.\n",
|
| 91 |
+
"# The batch processing code can be found here: https://github.com/modelscope/ms-swift/blob/main/examples/infer/demo_mllm.py\n",
|
| 92 |
+
"def infer_stream(engine: InferEngine, infer_request: InferRequest):\n",
|
| 93 |
+
" request_config = RequestConfig(max_tokens=max_new_tokens, temperature=temperature, stream=True)\n",
|
| 94 |
+
" gen_list = engine.infer([infer_request], request_config)\n",
|
| 95 |
+
" query = infer_request.messages[0]['content']\n",
|
| 96 |
+
" print(f'query: {query}\\nresponse: ', end='')\n",
|
| 97 |
+
" for resp in gen_list[0]:\n",
|
| 98 |
+
" if resp is None:\n",
|
| 99 |
+
" continue\n",
|
| 100 |
+
" print(resp.choices[0].delta.content, end='', flush=True)\n",
|
| 101 |
+
" print()\n",
|
| 102 |
+
"\n",
|
| 103 |
+
"from IPython.display import display\n",
|
| 104 |
+
"os.makedirs('images', exist_ok=True)\n",
|
| 105 |
+
"for i, data in enumerate(val_dataset):\n",
|
| 106 |
+
" image = data['images'][0]\n",
|
| 107 |
+
" image = load_image(image['bytes'] or image['path'])\n",
|
| 108 |
+
" image.save(f'images/{i}.png')\n",
|
| 109 |
+
" display(image)\n",
|
| 110 |
+
" infer_stream(engine, InferRequest(**data))\n",
|
| 111 |
+
" print('-' * 50)"
|
| 112 |
+
]
|
| 113 |
+
}
|
| 114 |
+
],
|
| 115 |
+
"metadata": {
|
| 116 |
+
"kernelspec": {
|
| 117 |
+
"display_name": "test_py310",
|
| 118 |
+
"language": "python",
|
| 119 |
+
"name": "python3"
|
| 120 |
+
},
|
| 121 |
+
"language_info": {
|
| 122 |
+
"codemirror_mode": {
|
| 123 |
+
"name": "ipython",
|
| 124 |
+
"version": 3
|
| 125 |
+
},
|
| 126 |
+
"file_extension": ".py",
|
| 127 |
+
"mimetype": "text/x-python",
|
| 128 |
+
"name": "python",
|
| 129 |
+
"nbconvert_exporter": "python",
|
| 130 |
+
"pygments_lexer": "ipython3",
|
| 131 |
+
"version": "3.10.15"
|
| 132 |
+
}
|
| 133 |
+
},
|
| 134 |
+
"nbformat": 4,
|
| 135 |
+
"nbformat_minor": 2
|
| 136 |
+
}
|
examples/notebook/qwen2vl-ocr/ocr-sft.ipynb
ADDED
|
@@ -0,0 +1,226 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"cells": [
|
| 3 |
+
{
|
| 4 |
+
"cell_type": "markdown",
|
| 5 |
+
"metadata": {},
|
| 6 |
+
"source": [
|
| 7 |
+
"## Latex-OCR SFT\n",
|
| 8 |
+
"\n",
|
| 9 |
+
"Here is a demonstration of using python to perform Latex-OCR SFT of Qwen2-VL-2B-Instruct. Through this tutorial, you can quickly understand some details of swift sft, which will be of great help in customizing ms-swift for you~\n",
|
| 10 |
+
"\n",
|
| 11 |
+
"Are you ready? Let's begin the journey..."
|
| 12 |
+
]
|
| 13 |
+
},
|
| 14 |
+
{
|
| 15 |
+
"cell_type": "code",
|
| 16 |
+
"execution_count": 7,
|
| 17 |
+
"metadata": {
|
| 18 |
+
"vscode": {
|
| 19 |
+
"languageId": "shellscript"
|
| 20 |
+
}
|
| 21 |
+
},
|
| 22 |
+
"outputs": [],
|
| 23 |
+
"source": [
|
| 24 |
+
"# # install ms-swift\n",
|
| 25 |
+
"# pip install ms-swift -U"
|
| 26 |
+
]
|
| 27 |
+
},
|
| 28 |
+
{
|
| 29 |
+
"cell_type": "code",
|
| 30 |
+
"execution_count": null,
|
| 31 |
+
"metadata": {},
|
| 32 |
+
"outputs": [],
|
| 33 |
+
"source": [
|
| 34 |
+
"# import some libraries\n",
|
| 35 |
+
"import os\n",
|
| 36 |
+
"os.environ['CUDA_VISIBLE_DEVICES'] = '0'\n",
|
| 37 |
+
"\n",
|
| 38 |
+
"from swift.llm import (\n",
|
| 39 |
+
" get_model_tokenizer, load_dataset, get_template, EncodePreprocessor, get_model_arch,\n",
|
| 40 |
+
" get_multimodal_target_regex, LazyLLMDataset\n",
|
| 41 |
+
")\n",
|
| 42 |
+
"from swift.utils import get_logger, get_model_parameter_info, plot_images, seed_everything\n",
|
| 43 |
+
"from swift.tuners import Swift, LoraConfig\n",
|
| 44 |
+
"from swift.trainers import Seq2SeqTrainer, Seq2SeqTrainingArguments\n",
|
| 45 |
+
"from functools import partial\n",
|
| 46 |
+
"\n",
|
| 47 |
+
"logger = get_logger()\n",
|
| 48 |
+
"seed_everything(42)"
|
| 49 |
+
]
|
| 50 |
+
},
|
| 51 |
+
{
|
| 52 |
+
"cell_type": "code",
|
| 53 |
+
"execution_count": null,
|
| 54 |
+
"metadata": {},
|
| 55 |
+
"outputs": [],
|
| 56 |
+
"source": [
|
| 57 |
+
"# Hyperparameters for training\n",
|
| 58 |
+
"# model\n",
|
| 59 |
+
"model_id_or_path = 'Qwen/Qwen2-VL-2B-Instruct'\n",
|
| 60 |
+
"system = None # Using the default system defined in the template.\n",
|
| 61 |
+
"output_dir = 'output'\n",
|
| 62 |
+
"\n",
|
| 63 |
+
"# dataset\n",
|
| 64 |
+
"dataset = ['AI-ModelScope/LaTeX_OCR#20000'] # dataset_id or dataset_path. Sampling 20000 data points\n",
|
| 65 |
+
"data_seed = 42\n",
|
| 66 |
+
"max_length = 2048\n",
|
| 67 |
+
"split_dataset_ratio = 0.01 # Split validation set\n",
|
| 68 |
+
"num_proc = 4 # The number of processes for data loading.\n",
|
| 69 |
+
"\n",
|
| 70 |
+
"# lora\n",
|
| 71 |
+
"lora_rank = 8\n",
|
| 72 |
+
"lora_alpha = 32\n",
|
| 73 |
+
"freeze_llm = False\n",
|
| 74 |
+
"freeze_vit = True\n",
|
| 75 |
+
"freeze_aligner = True\n",
|
| 76 |
+
"\n",
|
| 77 |
+
"# training_args\n",
|
| 78 |
+
"training_args = Seq2SeqTrainingArguments(\n",
|
| 79 |
+
" output_dir=output_dir,\n",
|
| 80 |
+
" learning_rate=1e-4,\n",
|
| 81 |
+
" per_device_train_batch_size=1,\n",
|
| 82 |
+
" per_device_eval_batch_size=1,\n",
|
| 83 |
+
" gradient_checkpointing=True,\n",
|
| 84 |
+
" weight_decay=0.1,\n",
|
| 85 |
+
" lr_scheduler_type='cosine',\n",
|
| 86 |
+
" warmup_ratio=0.05,\n",
|
| 87 |
+
" report_to=['tensorboard'],\n",
|
| 88 |
+
" logging_first_step=True,\n",
|
| 89 |
+
" save_strategy='steps',\n",
|
| 90 |
+
" save_steps=50,\n",
|
| 91 |
+
" eval_strategy='steps',\n",
|
| 92 |
+
" eval_steps=50,\n",
|
| 93 |
+
" gradient_accumulation_steps=16,\n",
|
| 94 |
+
" # To observe the training results more quickly, this is set to 1 here. \n",
|
| 95 |
+
" # Under normal circumstances, a larger number should be used.\n",
|
| 96 |
+
" num_train_epochs=1,\n",
|
| 97 |
+
" metric_for_best_model='loss',\n",
|
| 98 |
+
" save_total_limit=5,\n",
|
| 99 |
+
" logging_steps=5,\n",
|
| 100 |
+
" dataloader_num_workers=4,\n",
|
| 101 |
+
" data_seed=data_seed,\n",
|
| 102 |
+
" remove_unused_columns=False,\n",
|
| 103 |
+
")\n",
|
| 104 |
+
"\n",
|
| 105 |
+
"output_dir = os.path.abspath(os.path.expanduser(output_dir))\n",
|
| 106 |
+
"logger.info(f'output_dir: {output_dir}')"
|
| 107 |
+
]
|
| 108 |
+
},
|
| 109 |
+
{
|
| 110 |
+
"cell_type": "code",
|
| 111 |
+
"execution_count": null,
|
| 112 |
+
"metadata": {},
|
| 113 |
+
"outputs": [],
|
| 114 |
+
"source": [
|
| 115 |
+
"# Obtain the model and template\n",
|
| 116 |
+
"model, processor = get_model_tokenizer(model_id_or_path)\n",
|
| 117 |
+
"logger.info(f'model_info: {model.model_info}')\n",
|
| 118 |
+
"template = get_template(model.model_meta.template, processor, default_system=system, max_length=max_length)\n",
|
| 119 |
+
"template.set_mode('train')\n",
|
| 120 |
+
"if template.use_model:\n",
|
| 121 |
+
" template.model = model\n",
|
| 122 |
+
"\n",
|
| 123 |
+
"# Get target_modules and add trainable LoRA modules to the model.\n",
|
| 124 |
+
"target_modules = get_multimodal_target_regex(model, freeze_llm=freeze_llm, freeze_vit=freeze_vit, \n",
|
| 125 |
+
" freeze_aligner=freeze_aligner)\n",
|
| 126 |
+
"lora_config = LoraConfig(task_type='CAUSAL_LM', r=lora_rank, lora_alpha=lora_alpha,\n",
|
| 127 |
+
" target_modules=target_modules)\n",
|
| 128 |
+
"model = Swift.prepare_model(model, lora_config)\n",
|
| 129 |
+
"logger.info(f'lora_config: {lora_config}')\n",
|
| 130 |
+
"\n",
|
| 131 |
+
"# Print model structure and trainable parameters.\n",
|
| 132 |
+
"logger.info(f'model: {model}')\n",
|
| 133 |
+
"model_parameter_info = get_model_parameter_info(model)\n",
|
| 134 |
+
"logger.info(f'model_parameter_info: {model_parameter_info}')"
|
| 135 |
+
]
|
| 136 |
+
},
|
| 137 |
+
{
|
| 138 |
+
"cell_type": "code",
|
| 139 |
+
"execution_count": null,
|
| 140 |
+
"metadata": {},
|
| 141 |
+
"outputs": [],
|
| 142 |
+
"source": [
|
| 143 |
+
"# Download and load the dataset, split it into a training set and a validation set,\n",
|
| 144 |
+
"# and encode the text data into tokens.\n",
|
| 145 |
+
"train_dataset, val_dataset = load_dataset(dataset, split_dataset_ratio=split_dataset_ratio, num_proc=num_proc,\n",
|
| 146 |
+
" seed=data_seed)\n",
|
| 147 |
+
"\n",
|
| 148 |
+
"logger.info(f'train_dataset: {train_dataset}')\n",
|
| 149 |
+
"logger.info(f'val_dataset: {val_dataset}')\n",
|
| 150 |
+
"logger.info(f'train_dataset[0]: {train_dataset[0]}')\n",
|
| 151 |
+
"\n",
|
| 152 |
+
"train_dataset = LazyLLMDataset(train_dataset, template.encode, random_state=data_seed)\n",
|
| 153 |
+
"val_dataset = LazyLLMDataset(val_dataset, template.encode, random_state=data_seed)\n",
|
| 154 |
+
"data = train_dataset[0]\n",
|
| 155 |
+
"logger.info(f'encoded_train_dataset[0]: {data}')\n",
|
| 156 |
+
"\n",
|
| 157 |
+
"template.print_inputs(data)"
|
| 158 |
+
]
|
| 159 |
+
},
|
| 160 |
+
{
|
| 161 |
+
"cell_type": "code",
|
| 162 |
+
"execution_count": null,
|
| 163 |
+
"metadata": {},
|
| 164 |
+
"outputs": [],
|
| 165 |
+
"source": [
|
| 166 |
+
"# Get the trainer and start the training.\n",
|
| 167 |
+
"model.enable_input_require_grads() # Compatible with gradient checkpointing\n",
|
| 168 |
+
"trainer = Seq2SeqTrainer(\n",
|
| 169 |
+
" model=model,\n",
|
| 170 |
+
" args=training_args,\n",
|
| 171 |
+
" data_collator=template.data_collator,\n",
|
| 172 |
+
" train_dataset=train_dataset,\n",
|
| 173 |
+
" eval_dataset=val_dataset,\n",
|
| 174 |
+
" template=template,\n",
|
| 175 |
+
")\n",
|
| 176 |
+
"trainer.train()\n",
|
| 177 |
+
"\n",
|
| 178 |
+
"last_model_checkpoint = trainer.state.last_model_checkpoint\n",
|
| 179 |
+
"logger.info(f'last_model_checkpoint: {last_model_checkpoint}')"
|
| 180 |
+
]
|
| 181 |
+
},
|
| 182 |
+
{
|
| 183 |
+
"cell_type": "code",
|
| 184 |
+
"execution_count": null,
|
| 185 |
+
"metadata": {},
|
| 186 |
+
"outputs": [],
|
| 187 |
+
"source": [
|
| 188 |
+
"# Visualize the training loss.\n",
|
| 189 |
+
"# You can also use the TensorBoard visualization interface during training by entering\n",
|
| 190 |
+
"# `tensorboard --logdir '{output_dir}/runs'` at the command line.\n",
|
| 191 |
+
"images_dir = os.path.join(output_dir, 'images')\n",
|
| 192 |
+
"logger.info(f'images_dir: {images_dir}')\n",
|
| 193 |
+
"plot_images(images_dir, training_args.logging_dir, ['train/loss'], 0.9) # save images\n",
|
| 194 |
+
"\n",
|
| 195 |
+
"# Read and display the image.\n",
|
| 196 |
+
"# The light yellow line represents the actual loss value,\n",
|
| 197 |
+
"# while the yellow line represents the loss value smoothed with a smoothing factor of 0.9.\n",
|
| 198 |
+
"from IPython.display import display\n",
|
| 199 |
+
"from PIL import Image\n",
|
| 200 |
+
"image = Image.open(os.path.join(images_dir, 'train_loss.png'))\n",
|
| 201 |
+
"display(image)"
|
| 202 |
+
]
|
| 203 |
+
}
|
| 204 |
+
],
|
| 205 |
+
"metadata": {
|
| 206 |
+
"kernelspec": {
|
| 207 |
+
"display_name": "py310",
|
| 208 |
+
"language": "python",
|
| 209 |
+
"name": "python3"
|
| 210 |
+
},
|
| 211 |
+
"language_info": {
|
| 212 |
+
"codemirror_mode": {
|
| 213 |
+
"name": "ipython",
|
| 214 |
+
"version": 3
|
| 215 |
+
},
|
| 216 |
+
"file_extension": ".py",
|
| 217 |
+
"mimetype": "text/x-python",
|
| 218 |
+
"name": "python",
|
| 219 |
+
"nbconvert_exporter": "python",
|
| 220 |
+
"pygments_lexer": "ipython3",
|
| 221 |
+
"version": "3.11.11"
|
| 222 |
+
}
|
| 223 |
+
},
|
| 224 |
+
"nbformat": 4,
|
| 225 |
+
"nbformat_minor": 2
|
| 226 |
+
}
|
examples/sampler/distill/distill.sh
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
OPENAI_API_KEY="xxx" \
|
| 2 |
+
swift sample \
|
| 3 |
+
--sampler_type distill \
|
| 4 |
+
--sampler_engine client \
|
| 5 |
+
--model deepseek-r1 \
|
| 6 |
+
--stream true \
|
| 7 |
+
--dataset tastelikefeet/competition_math#5 \
|
| 8 |
+
--num_return_sequences 1 \
|
| 9 |
+
--temperature 0.6 \
|
| 10 |
+
--top_p 0.95 \
|
| 11 |
+
--engine_kwargs '{"base_url":"https://dashscope.aliyuncs.com/compatible-mode/v1"}'
|
examples/sampler/mcts/mcts.py
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
import subprocess
|
| 3 |
+
import time
|
| 4 |
+
from typing import List
|
| 5 |
+
|
| 6 |
+
import json
|
| 7 |
+
from modelscope.msdatasets import MsDataset
|
| 8 |
+
|
| 9 |
+
conda_prefix = ''
|
| 10 |
+
|
| 11 |
+
|
| 12 |
+
def client_sample(model: str, orm: str, dataset_path: str, iter: int, device_count: int, output_dir: str):
|
| 13 |
+
handlers = []
|
| 14 |
+
# Sampling cache
|
| 15 |
+
api_key = os.getenv('DASHSCOPE_API_KEY')
|
| 16 |
+
|
| 17 |
+
for device in range(device_count):
|
| 18 |
+
|
| 19 |
+
output_file = f'iter_{iter}_proc_{device}.jsonl'
|
| 20 |
+
cache_file = f'iter_{iter}_proc_{device}_cache.jsonl'
|
| 21 |
+
dataset = f'train_{device:02}.jsonl'
|
| 22 |
+
|
| 23 |
+
# output_file_path = os.path.join(output_dir, output_file)
|
| 24 |
+
cache_file_path = os.path.join(output_dir, cache_file)
|
| 25 |
+
single_dataset_path = os.path.join(dataset_path, dataset)
|
| 26 |
+
|
| 27 |
+
if not os.path.exists(cache_file_path):
|
| 28 |
+
open(cache_file_path, 'w').close()
|
| 29 |
+
sample_cmd = (f'USE_OPENCOMPASS_EVALUATOR=True '
|
| 30 |
+
f'swift sample '
|
| 31 |
+
f'--model {model} '
|
| 32 |
+
f'--orm_model {orm} '
|
| 33 |
+
f'--sampler_type mcts '
|
| 34 |
+
f'--process_reward_rate 0 '
|
| 35 |
+
f'--stop_words ки '
|
| 36 |
+
f'--seed 42 '
|
| 37 |
+
f'--api_key {api_key} '
|
| 38 |
+
f'--dataset {single_dataset_path} '
|
| 39 |
+
f'--max_length 2048 '
|
| 40 |
+
f'--system ./scripts/sampler/system_prompt.txt '
|
| 41 |
+
f'--load_args false '
|
| 42 |
+
f'--sampler_engine client '
|
| 43 |
+
f'--max_new_tokens 768 '
|
| 44 |
+
f'--override_exist_file true '
|
| 45 |
+
f'--num_sampling_per_gpu_batch_size 1 '
|
| 46 |
+
f'--num_return_sequences 8 '
|
| 47 |
+
f'--exploration_rate 0.2 '
|
| 48 |
+
f'--max_iterations 200 '
|
| 49 |
+
f'--output_dir {output_dir} '
|
| 50 |
+
f'--cache_files {cache_file} '
|
| 51 |
+
f'--output_file {output_file} '
|
| 52 |
+
f'--temperature 1.0 ')
|
| 53 |
+
print(f'Sampling caches of iter {iter}, part {device}.', flush=True)
|
| 54 |
+
# env['CUDA_VISIBLE_DEVICES'] = str(device)
|
| 55 |
+
handler = subprocess.Popen(
|
| 56 |
+
f'{sample_cmd}' + f' > mcts_logs/sample_iter_{iter}_proc_{device}_cache.log 2>&1',
|
| 57 |
+
env=os.environ.copy(),
|
| 58 |
+
shell=True,
|
| 59 |
+
executable='/bin/bash')
|
| 60 |
+
handlers.append(handler)
|
| 61 |
+
|
| 62 |
+
datasets = []
|
| 63 |
+
for proc, handler in enumerate(handlers):
|
| 64 |
+
handler.wait()
|
| 65 |
+
assert os.path.exists(os.path.join(output_dir, f'iter_{iter}_proc_{proc}.jsonl'))
|
| 66 |
+
datasets.append(os.path.join('sample_output', f'iter_{iter}_proc_{proc}.jsonl'))
|
| 67 |
+
print(f'Sampling done, files:{datasets}', flush=True)
|
| 68 |
+
|
| 69 |
+
|
| 70 |
+
def split_dataset(ds, split_size, out_path):
|
| 71 |
+
data_size = int(len(ds) / split_size) + 1
|
| 72 |
+
|
| 73 |
+
for i in range(split_size):
|
| 74 |
+
file_name = f'train_{i:02}.jsonl'
|
| 75 |
+
file_path = os.path.join(out_path, file_name)
|
| 76 |
+
print(file_path)
|
| 77 |
+
ds_split = ds[data_size * i:min(data_size * (i + 1), len(ds))]
|
| 78 |
+
print(f"split_size: {len(ds_split['problem'])}")
|
| 79 |
+
with open(file_path, 'w', encoding='utf-8') as file:
|
| 80 |
+
for problem, solution in zip(ds_split['problem'], ds_split['solution']):
|
| 81 |
+
message = {
|
| 82 |
+
'messages': [
|
| 83 |
+
{
|
| 84 |
+
'role': 'user',
|
| 85 |
+
'content': problem,
|
| 86 |
+
},
|
| 87 |
+
{
|
| 88 |
+
'role': 'assistant',
|
| 89 |
+
'content': solution,
|
| 90 |
+
},
|
| 91 |
+
]
|
| 92 |
+
}
|
| 93 |
+
file.write(json.dumps(message, ensure_ascii=False) + '\n')
|
| 94 |
+
|
| 95 |
+
|
| 96 |
+
def main():
|
| 97 |
+
server_model = 'qwen-max'
|
| 98 |
+
orm = 'math'
|
| 99 |
+
device_count = 20
|
| 100 |
+
output_dir = 'output/sampler/client_mcts/'
|
| 101 |
+
dataset_dir = 'datasets/competition_math/'
|
| 102 |
+
log_dir = 'mcts_logs/'
|
| 103 |
+
|
| 104 |
+
os.makedirs(output_dir, exist_ok=True)
|
| 105 |
+
os.makedirs(dataset_dir, exist_ok=True)
|
| 106 |
+
os.makedirs(log_dir, exist_ok=True)
|
| 107 |
+
ds = MsDataset.load('tastelikefeet/competition_math', subset_name='default', split='train')
|
| 108 |
+
split_dataset(ds, device_count, dataset_dir)
|
| 109 |
+
|
| 110 |
+
ts = time.time()
|
| 111 |
+
client_sample(server_model, orm, dataset_dir, 0, device_count, output_dir)
|
| 112 |
+
print(f'do sample cost: {(time.time() - ts) / 60:.1f} minutes.', flush=True)
|
| 113 |
+
|
| 114 |
+
|
| 115 |
+
if __name__ == '__main__':
|
| 116 |
+
main()
|
examples/sampler/mcts/mcts.sh
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
export CUDA_VISIBLE_DEVICES=0
|
| 2 |
+
export USE_OPENCOMPASS_EVALUATOR=True
|
| 3 |
+
|
| 4 |
+
swift sample \
|
| 5 |
+
--model ./output/Qwen2.5-Math-7B-Instruct/v40-20250126-161112/checkpoint-20 \
|
| 6 |
+
--orm_model math \
|
| 7 |
+
--sampler_type mcts \
|
| 8 |
+
--sampler_engine vllm \
|
| 9 |
+
--output_dir ./output/sampler/mcts \
|
| 10 |
+
--system ./examples/sampler/system_prompt.txt \
|
| 11 |
+
--stop_words ки \
|
| 12 |
+
--dataset ./datasets/competition_math/small_test.jsonl \
|
| 13 |
+
--num_return_sequences 2 \
|
| 14 |
+
--process_reward_rate 0 \
|
| 15 |
+
--max_new_tokens 2048
|
| 16 |
+
|
| 17 |
+
## Train
|
| 18 |
+
# nproc_per_node=8
|
| 19 |
+
# NPROC_PER_NODE=$nproc_per_node \
|
| 20 |
+
# swift sft \
|
| 21 |
+
# --model Qwen/Qwen2.5-Math-7B-Instruct \
|
| 22 |
+
# --train_type full \
|
| 23 |
+
# --torch_dtype bfloat16 \
|
| 24 |
+
# --dataset 'datasets/gen_V5.jsonl' \
|
| 25 |
+
# --num_train_epochs 1 \
|
| 26 |
+
# --per_device_train_batch_size 1 \
|
| 27 |
+
# --learning_rate 1e-5 \
|
| 28 |
+
# --gradient_accumulation_steps $(expr 128 / $nproc_per_node) \
|
| 29 |
+
# --eval_steps 1000 \
|
| 30 |
+
# --save_steps 10 \
|
| 31 |
+
# --save_total_limit 100 \
|
| 32 |
+
# --max_length 10000 \
|
| 33 |
+
# --logging_steps 5 \
|
| 34 |
+
# --gradient_checkpointing_kwargs '{"use_reentrant": false}' \
|
| 35 |
+
# --deepspeed zero3
|
examples/sampler/mcts/system_prompt.txt
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
You are a math model, you should **think step by step** carefully. Each step should **end with \"ки\”**. Final answer should be in a ‘\boxed()’.
|
| 2 |
+
|
| 3 |
+
## Example:
|
| 4 |
+
Step1: XXX. ки\n
|
| 5 |
+
Step2: XXX. ки\n
|
| 6 |
+
Step3: XXX. ки\n
|
| 7 |
+
Answer: \boxed(answer). ки\n
|
examples/train/agent/deepseek_r1.sh
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
CUDA_VISIBLE_DEVICES=0 \
|
| 2 |
+
swift sft \
|
| 3 |
+
--model deepseek-ai/DeepSeek-R1-Distill-Qwen-1.5B \
|
| 4 |
+
--train_type full \
|
| 5 |
+
--dataset AI-ModelScope/function-calling-chatml \
|
| 6 |
+
--agent_template react_en \
|
| 7 |
+
--loss_scale react \
|
| 8 |
+
--response_prefix '' \
|
| 9 |
+
--torch_dtype bfloat16 \
|
| 10 |
+
--num_train_epochs 2 \
|
| 11 |
+
--per_device_train_batch_size 1 \
|
| 12 |
+
--per_device_eval_batch_size 1 \
|
| 13 |
+
--learning_rate 1e-5 \
|
| 14 |
+
--gradient_accumulation_steps 8 \
|
| 15 |
+
--eval_steps 100 \
|
| 16 |
+
--save_steps 100 \
|
| 17 |
+
--save_total_limit 2 \
|
| 18 |
+
--logging_steps 5 \
|
| 19 |
+
--max_length 8192 \
|
| 20 |
+
--save_only_model true \
|
| 21 |
+
--packing true \
|
| 22 |
+
--use_liger_kernel true \
|
| 23 |
+
--output_dir output \
|
| 24 |
+
--warmup_ratio 0.05 \
|
| 25 |
+
--attn_impl flash_attn \
|
| 26 |
+
--dataloader_num_workers 4 \
|
| 27 |
+
--dataset_num_proc 16
|
examples/train/agent/glm4.sh
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# 4 * 80GiB
|
| 2 |
+
NPROC_PER_NODE=4 \
|
| 3 |
+
CUDA_VISIBLE_DEVICES=0,1,2,3 \
|
| 4 |
+
swift sft \
|
| 5 |
+
--model ZhipuAI/GLM-4-9B-0414 \
|
| 6 |
+
--train_type full \
|
| 7 |
+
--dataset AI-ModelScope/function-calling-chatml \
|
| 8 |
+
--agent_template hermes \
|
| 9 |
+
--torch_dtype bfloat16 \
|
| 10 |
+
--num_train_epochs 2 \
|
| 11 |
+
--per_device_train_batch_size 1 \
|
| 12 |
+
--per_device_eval_batch_size 1 \
|
| 13 |
+
--learning_rate 1e-5 \
|
| 14 |
+
--gradient_accumulation_steps 2 \
|
| 15 |
+
--eval_steps 100 \
|
| 16 |
+
--save_steps 100 \
|
| 17 |
+
--save_total_limit 2 \
|
| 18 |
+
--logging_steps 5 \
|
| 19 |
+
--max_length 8192 \
|
| 20 |
+
--save_only_model true \
|
| 21 |
+
--packing true \
|
| 22 |
+
--deepspeed zero3 \
|
| 23 |
+
--use_liger_kernel true \
|
| 24 |
+
--output_dir output \
|
| 25 |
+
--warmup_ratio 0.05 \
|
| 26 |
+
--attn_impl flash_attn \
|
| 27 |
+
--dataloader_num_workers 4 \
|
| 28 |
+
--dataset_num_proc 16
|
examples/train/agent/loss_scale/infer_lora.py
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright (c) Alibaba, Inc. and its affiliates.
|
| 2 |
+
import os
|
| 3 |
+
|
| 4 |
+
os.environ['CUDA_VISIBLE_DEVICES'] = '0'
|
| 5 |
+
# os.environ['SWIFT_DEBUG'] = '1'
|
| 6 |
+
|
| 7 |
+
|
| 8 |
+
def infer(engine: 'InferEngine', infer_request: 'InferRequest'):
|
| 9 |
+
stop = [engine.default_template.agent_template.keyword.observation] # compat react_en
|
| 10 |
+
request_config = RequestConfig(max_tokens=512, temperature=0, stop=stop)
|
| 11 |
+
resp_list = engine.infer([infer_request], request_config)
|
| 12 |
+
query = infer_request.messages[0]['content']
|
| 13 |
+
response = resp_list[0].choices[0].message.content
|
| 14 |
+
print(f'query: {query}')
|
| 15 |
+
print(f'response: {response}')
|
| 16 |
+
print(f'tool_calls: {resp_list[0].choices[0].message.tool_calls}')
|
| 17 |
+
|
| 18 |
+
tool = '{"temperature": 32, "condition": "Sunny", "humidity": 50}'
|
| 19 |
+
print(f'tool_response: {tool}')
|
| 20 |
+
infer_request.messages += [{'role': 'assistant', 'content': response}, {'role': 'tool', 'content': tool}]
|
| 21 |
+
resp_list = engine.infer([infer_request], request_config)
|
| 22 |
+
response2 = resp_list[0].choices[0].message.content
|
| 23 |
+
print(f'response2: {response2}')
|
| 24 |
+
|
| 25 |
+
|
| 26 |
+
def infer_stream(engine: 'InferEngine', infer_request: 'InferRequest'):
|
| 27 |
+
stop = [engine.default_template.agent_template.keyword.observation]
|
| 28 |
+
request_config = RequestConfig(max_tokens=512, temperature=0, stream=True, stop=stop)
|
| 29 |
+
gen_list = engine.infer([infer_request], request_config)
|
| 30 |
+
query = infer_request.messages[0]['content']
|
| 31 |
+
response = ''
|
| 32 |
+
print(f'query: {query}\nresponse: ', end='')
|
| 33 |
+
for resp in gen_list[0]:
|
| 34 |
+
if resp is None:
|
| 35 |
+
continue
|
| 36 |
+
delta = resp.choices[0].delta.content
|
| 37 |
+
response += delta
|
| 38 |
+
print(delta, end='', flush=True)
|
| 39 |
+
print()
|
| 40 |
+
print(f'tool_calls: {resp.choices[0].delta.tool_calls}')
|
| 41 |
+
|
| 42 |
+
tool = '{"temperature": 32, "condition": "Sunny", "humidity": 50}'
|
| 43 |
+
print(f'tool_response: {tool}\nresponse2: ', end='')
|
| 44 |
+
infer_request.messages += [{'role': 'assistant', 'content': response}, {'role': 'tool', 'content': tool}]
|
| 45 |
+
gen_list = engine.infer([infer_request], request_config)
|
| 46 |
+
for resp in gen_list[0]:
|
| 47 |
+
if resp is None:
|
| 48 |
+
continue
|
| 49 |
+
print(resp.choices[0].delta.content, end='', flush=True)
|
| 50 |
+
print()
|
| 51 |
+
|
| 52 |
+
|
| 53 |
+
def get_infer_request():
|
| 54 |
+
return InferRequest(
|
| 55 |
+
messages=[{
|
| 56 |
+
'role': 'user',
|
| 57 |
+
'content': "How's the weather in Beijing today?"
|
| 58 |
+
}],
|
| 59 |
+
tools=[{
|
| 60 |
+
'name': 'get_current_weather',
|
| 61 |
+
'description': 'Get the current weather in a given location',
|
| 62 |
+
'parameters': {
|
| 63 |
+
'type': 'object',
|
| 64 |
+
'properties': {
|
| 65 |
+
'location': {
|
| 66 |
+
'type': 'string',
|
| 67 |
+
'description': 'The city and state, e.g. San Francisco, CA'
|
| 68 |
+
},
|
| 69 |
+
'unit': {
|
| 70 |
+
'type': 'string',
|
| 71 |
+
'enum': ['celsius', 'fahrenheit']
|
| 72 |
+
}
|
| 73 |
+
},
|
| 74 |
+
'required': ['location']
|
| 75 |
+
}
|
| 76 |
+
}])
|
| 77 |
+
|
| 78 |
+
|
| 79 |
+
if __name__ == '__main__':
|
| 80 |
+
from swift.llm import InferEngine, InferRequest, PtEngine, RequestConfig
|
| 81 |
+
from swift.plugin import agent_templates
|
| 82 |
+
model = 'Qwen/Qwen2.5-3B'
|
| 83 |
+
adapters = ['output/vx-xxx/checkpoint-xxx']
|
| 84 |
+
engine = PtEngine(model, adapters=adapters, max_batch_size=8)
|
| 85 |
+
|
| 86 |
+
# agent_template = agent_templates['hermes']() # react_en/qwen_en/qwen_en_parallel
|
| 87 |
+
# engine.default_template.agent_template = agent_template
|
| 88 |
+
|
| 89 |
+
infer(engine, get_infer_request())
|
| 90 |
+
infer_stream(engine, get_infer_request())
|
examples/train/agent/loss_scale/train.sh
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# 20GB
|
| 2 |
+
CUDA_VISIBLE_DEVICES=0 \
|
| 3 |
+
swift sft \
|
| 4 |
+
--model Qwen/Qwen2.5-3B \
|
| 5 |
+
--train_type lora \
|
| 6 |
+
--dataset AI-ModelScope/function-calling-chatml#10000 \
|
| 7 |
+
--loss_scale hermes \
|
| 8 |
+
--agent_template hermes \
|
| 9 |
+
--torch_dtype bfloat16 \
|
| 10 |
+
--num_train_epochs 2 \
|
| 11 |
+
--per_device_train_batch_size 1 \
|
| 12 |
+
--per_device_eval_batch_size 1 \
|
| 13 |
+
--learning_rate 1e-4 \
|
| 14 |
+
--lora_rank 8 \
|
| 15 |
+
--lora_alpha 32 \
|
| 16 |
+
--target_modules all-linear \
|
| 17 |
+
--modules_to_save embed_tokens lm_head \
|
| 18 |
+
--gradient_accumulation_steps 16 \
|
| 19 |
+
--eval_steps 100 \
|
| 20 |
+
--save_steps 100 \
|
| 21 |
+
--save_total_limit 2 \
|
| 22 |
+
--logging_steps 5 \
|
| 23 |
+
--max_length 2048 \
|
| 24 |
+
--use_liger_kernel true \
|
| 25 |
+
--output_dir output \
|
| 26 |
+
--warmup_ratio 0.05 \
|
| 27 |
+
--dataloader_num_workers 4 \
|
| 28 |
+
--dataset_num_proc 16
|
examples/train/agent/qwen2_5.sh
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# 35GiB
|
| 2 |
+
CUDA_VISIBLE_DEVICES=0 \
|
| 3 |
+
swift sft \
|
| 4 |
+
--model Qwen/Qwen2.5-3B \
|
| 5 |
+
--train_type full \
|
| 6 |
+
--dataset AI-ModelScope/function-calling-chatml \
|
| 7 |
+
--agent_template hermes \
|
| 8 |
+
--torch_dtype bfloat16 \
|
| 9 |
+
--num_train_epochs 2 \
|
| 10 |
+
--per_device_train_batch_size 1 \
|
| 11 |
+
--per_device_eval_batch_size 1 \
|
| 12 |
+
--learning_rate 1e-5 \
|
| 13 |
+
--gradient_accumulation_steps 8 \
|
| 14 |
+
--eval_steps 100 \
|
| 15 |
+
--save_steps 100 \
|
| 16 |
+
--save_total_limit 2 \
|
| 17 |
+
--logging_steps 5 \
|
| 18 |
+
--max_length 8192 \
|
| 19 |
+
--save_only_model true \
|
| 20 |
+
--packing true \
|
| 21 |
+
--use_liger_kernel true \
|
| 22 |
+
--output_dir output \
|
| 23 |
+
--warmup_ratio 0.05 \
|
| 24 |
+
--attn_impl flash_attn \
|
| 25 |
+
--dataloader_num_workers 4 \
|
| 26 |
+
--dataset_num_proc 16
|
examples/train/all_to_all/infer.sh
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# 53GiB
|
| 2 |
+
CUDA_VISIBLE_DEVICES=0 \
|
| 3 |
+
swift infer \
|
| 4 |
+
--model BAAI/Emu3-Gen \
|
| 5 |
+
--infer_backend pt \
|
| 6 |
+
--stream False \
|
| 7 |
+
--use_chat_template False \
|
| 8 |
+
--top_k 2048 \
|
| 9 |
+
--max_new_tokens 40960
|
examples/train/all_to_all/train.sh
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# 70 GiB * 2
|
| 2 |
+
nproc_per_node=2
|
| 3 |
+
NPROC_PER_NODE=$nproc_per_node \
|
| 4 |
+
CUDA_VISIBLE_DEVICES=0,2 \
|
| 5 |
+
max_position_embeddings=10240 \
|
| 6 |
+
image_area=518400 \
|
| 7 |
+
swift sft \
|
| 8 |
+
--model BAAI/Emu3-Gen \
|
| 9 |
+
--train_type lora \
|
| 10 |
+
--dataset 'swift/TextCaps#40' \
|
| 11 |
+
--torch_dtype bfloat16 \
|
| 12 |
+
--num_train_epochs 10 \
|
| 13 |
+
--per_device_train_batch_size 1 \
|
| 14 |
+
--learning_rate 1e-5 \
|
| 15 |
+
--gradient_accumulation_steps 4 \
|
| 16 |
+
--warmup_ratio 0.03 \
|
| 17 |
+
--eval_steps 500 \
|
| 18 |
+
--save_steps 500 \
|
| 19 |
+
--save_total_limit 2 \
|
| 20 |
+
--logging_steps 5 \
|
| 21 |
+
--max_length 1024 \
|
| 22 |
+
--weight_decay 0.1 \
|
| 23 |
+
--gradient_checkpointing_kwargs '{"use_reentrant": false}'
|
examples/train/base_to_chat/full.sh
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
nproc_per_node=2
|
| 2 |
+
|
| 3 |
+
CUDA_VISIBLE_DEVICES=0,1 \
|
| 4 |
+
NPROC_PER_NODE=$nproc_per_node \
|
| 5 |
+
swift sft \
|
| 6 |
+
--model Qwen/Qwen2.5-1.5B \
|
| 7 |
+
--train_type full \
|
| 8 |
+
--dataset 'AI-ModelScope/alpaca-gpt4-data-zh#500' \
|
| 9 |
+
'AI-ModelScope/alpaca-gpt4-data-en#500' \
|
| 10 |
+
'swift/self-cognition' \
|
| 11 |
+
--torch_dtype bfloat16 \
|
| 12 |
+
--num_train_epochs 10 \
|
| 13 |
+
--per_device_train_batch_size 1 \
|
| 14 |
+
--per_device_eval_batch_size 1 \
|
| 15 |
+
--learning_rate 1e-5 \
|
| 16 |
+
--gradient_accumulation_steps $(expr 16 / $nproc_per_node) \
|
| 17 |
+
--eval_steps 200 \
|
| 18 |
+
--save_steps 200 \
|
| 19 |
+
--save_total_limit 2 \
|
| 20 |
+
--logging_steps 5 \
|
| 21 |
+
--max_length 2048 \
|
| 22 |
+
--output_dir output \
|
| 23 |
+
--system 'You are a helpful assistant.' \
|
| 24 |
+
--warmup_ratio 0.05 \
|
| 25 |
+
--dataloader_num_workers 4 \
|
| 26 |
+
--model_author swift \
|
| 27 |
+
--model_name swift-robot \
|
| 28 |
+
--deepspeed zero2
|
examples/train/base_to_chat/lora.sh
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Use `--template default`
|
| 2 |
+
nproc_per_node=2
|
| 3 |
+
|
| 4 |
+
CUDA_VISIBLE_DEVICES=0,1 \
|
| 5 |
+
MASTER_PORT=29501 \
|
| 6 |
+
NPROC_PER_NODE=$nproc_per_node \
|
| 7 |
+
swift sft \
|
| 8 |
+
--model Qwen/Qwen2.5-1.5B \
|
| 9 |
+
--train_type lora \
|
| 10 |
+
--dataset 'AI-ModelScope/alpaca-gpt4-data-zh#500' \
|
| 11 |
+
'AI-ModelScope/alpaca-gpt4-data-en#500' \
|
| 12 |
+
'swift/self-cognition' \
|
| 13 |
+
--torch_dtype bfloat16 \
|
| 14 |
+
--template default \
|
| 15 |
+
--num_train_epochs 10 \
|
| 16 |
+
--per_device_train_batch_size 1 \
|
| 17 |
+
--per_device_eval_batch_size 1 \
|
| 18 |
+
--learning_rate 1e-4 \
|
| 19 |
+
--lora_rank 8 \
|
| 20 |
+
--lora_alpha 32 \
|
| 21 |
+
--target_modules all-linear \
|
| 22 |
+
--gradient_accumulation_steps $(expr 16 / $nproc_per_node) \
|
| 23 |
+
--eval_steps 50 \
|
| 24 |
+
--save_steps 50 \
|
| 25 |
+
--save_total_limit 2 \
|
| 26 |
+
--logging_steps 5 \
|
| 27 |
+
--max_length 2048 \
|
| 28 |
+
--output_dir output \
|
| 29 |
+
--system 'You are a helpful assistant.' \
|
| 30 |
+
--warmup_ratio 0.05 \
|
| 31 |
+
--dataloader_num_workers 4 \
|
| 32 |
+
--model_author swift \
|
| 33 |
+
--model_name swift-robot \
|
| 34 |
+
--deepspeed zero2
|
examples/train/base_to_chat/lora2.sh
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Use `--target_modules all-linear embed_tokens lm_head`
|
| 2 |
+
# Please adjust the `lm_head` according to the model.
|
| 3 |
+
nproc_per_node=2
|
| 4 |
+
|
| 5 |
+
CUDA_VISIBLE_DEVICES=0,1 \
|
| 6 |
+
NPROC_PER_NODE=$nproc_per_node \
|
| 7 |
+
swift sft \
|
| 8 |
+
--model Qwen/Qwen2.5-1.5B \
|
| 9 |
+
--train_type lora \
|
| 10 |
+
--dataset 'AI-ModelScope/alpaca-gpt4-data-zh#500' \
|
| 11 |
+
'AI-ModelScope/alpaca-gpt4-data-en#500' \
|
| 12 |
+
'swift/self-cognition' \
|
| 13 |
+
--torch_dtype bfloat16 \
|
| 14 |
+
--num_train_epochs 10 \
|
| 15 |
+
--per_device_train_batch_size 1 \
|
| 16 |
+
--per_device_eval_batch_size 1 \
|
| 17 |
+
--learning_rate 1e-4 \
|
| 18 |
+
--lora_rank 8 \
|
| 19 |
+
--lora_alpha 32 \
|
| 20 |
+
--target_modules all-linear embed_tokens lm_head \
|
| 21 |
+
--gradient_accumulation_steps $(expr 16 / $nproc_per_node) \
|
| 22 |
+
--eval_steps 50 \
|
| 23 |
+
--save_steps 50 \
|
| 24 |
+
--save_total_limit 2 \
|
| 25 |
+
--logging_steps 5 \
|
| 26 |
+
--max_length 2048 \
|
| 27 |
+
--output_dir output \
|
| 28 |
+
--system 'You are a helpful assistant.' \
|
| 29 |
+
--warmup_ratio 0.05 \
|
| 30 |
+
--dataloader_num_workers 4 \
|
| 31 |
+
--model_author swift \
|
| 32 |
+
--model_name swift-robot \
|
| 33 |
+
--deepspeed zero2
|
examples/train/embedding/train_gme.sh
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
nproc_per_node=8
|
| 2 |
+
|
| 3 |
+
# losses: plugin/loss.py
|
| 4 |
+
# 8*40G
|
| 5 |
+
MAX_PIXELS=1003520 \
|
| 6 |
+
NPROC_PER_NODE=$nproc_per_node \
|
| 7 |
+
swift sft \
|
| 8 |
+
--model iic/gme-Qwen2-VL-2B-Instruct \
|
| 9 |
+
--train_type lora \
|
| 10 |
+
--dataset 'swift/TextCaps:emb' \
|
| 11 |
+
--torch_dtype bfloat16 \
|
| 12 |
+
--num_train_epochs 1 \
|
| 13 |
+
--per_device_train_batch_size 2 \
|
| 14 |
+
--per_device_eval_batch_size 2 \
|
| 15 |
+
--gradient_accumulation_steps $(expr 64 / $nproc_per_node) \
|
| 16 |
+
--eval_steps 100 \
|
| 17 |
+
--save_steps 100 \
|
| 18 |
+
--eval_strategy steps \
|
| 19 |
+
--save_total_limit 2 \
|
| 20 |
+
--logging_steps 5 \
|
| 21 |
+
--output_dir output \
|
| 22 |
+
--lazy_tokenize true \
|
| 23 |
+
--warmup_ratio 0.05 \
|
| 24 |
+
--learning_rate 5e-6 \
|
| 25 |
+
--deepspeed zero3 \
|
| 26 |
+
--dataloader_num_workers 4 \
|
| 27 |
+
--task_type embedding \
|
| 28 |
+
--loss_type infonce \
|
| 29 |
+
--dataloader_drop_last true
|
examples/train/embedding/train_gte.sh
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
nproc_per_node=8
|
| 2 |
+
# 4*12G
|
| 3 |
+
# losses: plugin/loss.py
|
| 4 |
+
# data format: docs/source_en/Customization/Custom-dataset.md
|
| 5 |
+
# --use_chat_template must be false to use generation template
|
| 6 |
+
# --dataloader_drop_last must be true or eval gather will throw error
|
| 7 |
+
# --model iic/gte-modernbert-base modernbert also supported
|
| 8 |
+
NPROC_PER_NODE=$nproc_per_node \
|
| 9 |
+
swift sft \
|
| 10 |
+
--model iic/gte_Qwen2-7B-instruct \
|
| 11 |
+
--train_type lora \
|
| 12 |
+
--dataset 'sentence-transformers/stsb' \
|
| 13 |
+
--torch_dtype bfloat16 \
|
| 14 |
+
--num_train_epochs 1 \
|
| 15 |
+
--per_device_train_batch_size 2 \
|
| 16 |
+
--per_device_eval_batch_size 1 \
|
| 17 |
+
--gradient_accumulation_steps $(expr 64 / $nproc_per_node) \
|
| 18 |
+
--eval_steps 100 \
|
| 19 |
+
--save_steps 100 \
|
| 20 |
+
--eval_strategy steps \
|
| 21 |
+
--use_chat_template false \
|
| 22 |
+
--save_total_limit 2 \
|
| 23 |
+
--logging_steps 5 \
|
| 24 |
+
--output_dir output \
|
| 25 |
+
--warmup_ratio 0.05 \
|
| 26 |
+
--learning_rate 5e-6 \
|
| 27 |
+
--deepspeed zero3 \
|
| 28 |
+
--dataloader_num_workers 4 \
|
| 29 |
+
--task_type embedding \
|
| 30 |
+
--loss_type cosine_similarity \
|
| 31 |
+
--dataloader_drop_last true \
|
examples/train/full/infer.sh
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# If you are using the validation set for inference, add the parameter `--load_data_args true`.
|
| 2 |
+
CUDA_VISIBLE_DEVICES=0 \
|
| 3 |
+
swift infer \
|
| 4 |
+
--model output/vx-xxx/checkpoint-xxx \
|
| 5 |
+
--stream true \
|
| 6 |
+
--temperature 0 \
|
| 7 |
+
--max_new_tokens 2048
|
examples/train/full/qwen2_5_32b.sh
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# 8 * 80GiB
|
| 2 |
+
NPROC_PER_NODE=8 \
|
| 3 |
+
CUDA_VISIBLE_DEVICES=0,1,2,3,4,5,6,7 \
|
| 4 |
+
swift sft \
|
| 5 |
+
--model Qwen/Qwen2.5-32B \
|
| 6 |
+
--train_type full \
|
| 7 |
+
--dataset 'liucong/Chinese-DeepSeek-R1-Distill-data-110k-SFT' \
|
| 8 |
+
--torch_dtype bfloat16 \
|
| 9 |
+
--max_steps 2000 \
|
| 10 |
+
--streaming true \
|
| 11 |
+
--per_device_train_batch_size 1 \
|
| 12 |
+
--per_device_eval_batch_size 1 \
|
| 13 |
+
--learning_rate 1e-5 \
|
| 14 |
+
--gradient_accumulation_steps 2 \
|
| 15 |
+
--packing true \
|
| 16 |
+
--eval_steps 200 \
|
| 17 |
+
--save_steps 200 \
|
| 18 |
+
--logging_steps 5 \
|
| 19 |
+
--max_length 8192 \
|
| 20 |
+
--warmup_ratio 0.05 \
|
| 21 |
+
--dataloader_num_workers 8 \
|
| 22 |
+
--dataset_num_proc 8 \
|
| 23 |
+
--save_total_limit 2 \
|
| 24 |
+
--save_only_model true \
|
| 25 |
+
--output_dir output/Qwen2.5-32B \
|
| 26 |
+
--deepspeed zero3 \
|
| 27 |
+
--use_liger_kernel true \
|
| 28 |
+
--attn_impl flash_attn
|
examples/train/full/train.sh
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# 76GiB
|
| 2 |
+
CUDA_VISIBLE_DEVICES=0 \
|
| 3 |
+
swift sft \
|
| 4 |
+
--model Qwen/Qwen2.5-7B-Instruct \
|
| 5 |
+
--train_type full \
|
| 6 |
+
--dataset 'AI-ModelScope/alpaca-gpt4-data-zh#500' \
|
| 7 |
+
'AI-ModelScope/alpaca-gpt4-data-en#500' \
|
| 8 |
+
'swift/self-cognition#500' \
|
| 9 |
+
--torch_dtype bfloat16 \
|
| 10 |
+
--num_train_epochs 1 \
|
| 11 |
+
--per_device_train_batch_size 1 \
|
| 12 |
+
--per_device_eval_batch_size 1 \
|
| 13 |
+
--learning_rate 1e-5 \
|
| 14 |
+
--gradient_accumulation_steps 16 \
|
| 15 |
+
--eval_steps 100 \
|
| 16 |
+
--save_steps 100 \
|
| 17 |
+
--save_total_limit 2 \
|
| 18 |
+
--logging_steps 5 \
|
| 19 |
+
--max_length 2048 \
|
| 20 |
+
--output_dir output \
|
| 21 |
+
--system 'You are a helpful assistant.' \
|
| 22 |
+
--warmup_ratio 0.05 \
|
| 23 |
+
--dataloader_num_workers 4 \
|
| 24 |
+
--model_author swift \
|
| 25 |
+
--model_name swift-robot
|
examples/train/grpo/external/README.md
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# README: GRPO External Mode Execution Scripts
|
| 2 |
+
|
| 3 |
+
---
|
| 4 |
+
|
| 5 |
+
> **Note**: External mode requires vLLM version 0.8.3 or higher.
|
| 6 |
+
|
| 7 |
+
|
| 8 |
+
## **Introduction**
|
| 9 |
+
|
| 10 |
+
The GRPO (Gradient-based Reinforcement Policy Optimization) training framework supports high-performance inference engines like vLLM to accelerate the sampling process. The **External Mode** allows you to connect to an external vLLM inference server, separating the inference service from the training process. This mode is ideal for scenarios where you want to offload inference to dedicated hardware or servers, improving resource utilization and scalability.
|
| 11 |
+
|
| 12 |
+
This folder contains scripts and instructions for running GRPO in **External Mode**, enabling integration with an external vLLM server.
|
| 13 |
+
|
| 14 |
+
Before running the scripts, ensure the following:
|
| 15 |
+
|
| 16 |
+
1. **vLLM Server Deployment**:
|
| 17 |
+
- An external vLLM server must be deployed and accessible.
|
| 18 |
+
- Use the `swift rollout` command to deploy the vLLM server.
|
| 19 |
+
|
| 20 |
+
2. **Network Connectivity**:
|
| 21 |
+
- Ensure the training nodes can communicate with the vLLM server over the network.
|
| 22 |
+
|
| 23 |
+
## **Deploying the vLLM Server**
|
| 24 |
+
|
| 25 |
+
To deploy an external vLLM server, use the following command:
|
| 26 |
+
|
| 27 |
+
```bash
|
| 28 |
+
CUDA_VISIBLE_DEVICES=0 \
|
| 29 |
+
swift rollout \
|
| 30 |
+
--model Qwen/Qwen3-8B
|
| 31 |
+
|
| 32 |
+
# tp
|
| 33 |
+
CUDA_VISIBLE_DEVICES=0,1 \
|
| 34 |
+
swift rollout \
|
| 35 |
+
--model Qwen/Qwen3-8B \
|
| 36 |
+
--tensor_parallel_size 2
|
| 37 |
+
```
|
| 38 |
+
|
| 39 |
+
## Training with External vLLM Server
|
| 40 |
+
```bash
|
| 41 |
+
--vllm_server_host <server ip> \
|
| 42 |
+
--vllm_server_port <server port> \
|
| 43 |
+
--vllm_server_timeout <Timeout duration> \
|
| 44 |
+
```
|
| 45 |
+
Configuration Parameters
|
| 46 |
+
When using an external vLLM server, configure the following parameters:
|
examples/train/grpo/external/grpo.sh
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
CUDA_VISIBLE_DEVICES=0,1,2,3,4,5,6,7 \
|
| 2 |
+
NPROC_PER_NODE=8 \
|
| 3 |
+
swift rlhf \
|
| 4 |
+
--rlhf_type grpo \
|
| 5 |
+
--model Qwen/Qwen2.5-32B-Instruct \
|
| 6 |
+
--reward_funcs accuracy \
|
| 7 |
+
--use_vllm true \
|
| 8 |
+
--vllm_server_host xxx \
|
| 9 |
+
--vllm_server_port 8000 \
|
| 10 |
+
--train_type full \
|
| 11 |
+
--torch_dtype bfloat16 \
|
| 12 |
+
--dataset AI-MO/NuminaMath-TIR#1000 \
|
| 13 |
+
--max_completion_length 2048 \
|
| 14 |
+
--num_train_epochs 3 \
|
| 15 |
+
--per_device_train_batch_size 1 \
|
| 16 |
+
--per_device_eval_batch_size 1 \
|
| 17 |
+
--learning_rate 1e-6 \
|
| 18 |
+
--gradient_accumulation_steps 1 \
|
| 19 |
+
--save_total_limit 2 \
|
| 20 |
+
--logging_steps 1 \
|
| 21 |
+
--warmup_ratio 0.05 \
|
| 22 |
+
--dataloader_num_workers 4 \
|
| 23 |
+
--dataset_num_proc 4 \
|
| 24 |
+
--num_generations 8 \
|
| 25 |
+
--temperature 1.0 \
|
| 26 |
+
--top_p 0.9 \
|
| 27 |
+
--top_k 50 \
|
| 28 |
+
--deepspeed zero3 \
|
| 29 |
+
--log_completions true \
|
| 30 |
+
--num_iterations 1 \
|
| 31 |
+
--num_infer_workers 1 \
|
| 32 |
+
--report_to tensorboard wandb \
|
| 33 |
+
--beta 0.0
|