Skip to content

Commit 22e2137

Browse files
authored
fix qwen2.5 finetune precision with sdpa (#2138)
1 parent f62edfd commit 22e2137

File tree

7 files changed

+150
-162
lines changed

7 files changed

+150
-162
lines changed

examples/transformers/peft/lora/Qwen2.5-7B-Instruct-Lora.ipynb

Lines changed: 5 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,6 @@
1818
"outputs": [],
1919
"source": [
2020
"import mindnlp\n",
21-
"import mindspore\n",
22-
"\n",
23-
"# mindspore.set_context(pynative_synchronize=True)\n",
2421
"from datasets import Dataset\n",
2522
"import pandas as pd\n",
2623
"from transformers import AutoTokenizer, AutoModelForCausalLM, DataCollatorForSeq2Seq, TrainingArguments, Trainer, GenerationConfig"
@@ -167,8 +164,7 @@
167164
"source": [
168165
"import torch\n",
169166
"\n",
170-
"model = AutoModelForCausalLM.from_pretrained('Qwen/Qwen2.5-7B-Instruct', torch_dtype=torch.float16)\n",
171-
"model = model.npu()"
167+
"model = AutoModelForCausalLM.from_pretrained('Qwen/Qwen2.5-7B-Instruct', torch_dtype=torch.float16, device_map='auto')"
172168
]
173169
},
174170
{
@@ -250,22 +246,6 @@
250246
"model.print_trainable_parameters()"
251247
]
252248
},
253-
{
254-
"cell_type": "code",
255-
"execution_count": null,
256-
"id": "6b6aebd2",
257-
"metadata": {},
258-
"outputs": [],
259-
"source": [
260-
"# 待训练的lora参数需转成fp32\n",
261-
"print_flag = True\n",
262-
"for param in filter(lambda p: p.requires_grad, model.parameters()):\n",
263-
" if print_flag:\n",
264-
" print(param.data.dtype)\n",
265-
" print_flag = False\n",
266-
" param.data = param.data.to(torch.float32)"
267-
]
268-
},
269249
{
270250
"cell_type": "markdown",
271251
"id": "ca055683-837f-4865-9c57-9164ba60c00f",
@@ -362,11 +342,14 @@
362342
"tokenizer = AutoTokenizer.from_pretrained(mode_path, trust_remote_code=True)\n",
363343
"\n",
364344
"# 加载模型\n",
365-
"model = AutoModelForCausalLM.from_pretrained(mode_path, device_map=\"auto\",torch_dtype=torch.bfloat16, trust_remote_code=True).eval()\n",
345+
"model = AutoModelForCausalLM.from_pretrained(mode_path, torch_dtype=torch.float16, trust_remote_code=True).eval()\n",
366346
"\n",
367347
"# 加载lora权重\n",
368348
"model = PeftModel.from_pretrained(model, model_id=lora_path)\n",
369349
"\n",
350+
"# host to device\n",
351+
"model = model.npu()\n",
352+
"\n",
370353
"prompt = \"你是谁?\"\n",
371354
"inputs = tokenizer.apply_chat_template([{\"role\": \"user\", \"content\": \"假设你是皇帝身边的女人--甄嬛。\"},{\"role\": \"user\", \"content\": prompt}],\n",
372355
" add_generation_prompt=True,\n",

examples/transformers/peft/lora/Qwen2.5-7B-Instruct-Lora.py

Lines changed: 11 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,7 @@
1-
#!/usr/bin/env python
1+
# !/usr/bin/env python
22
# coding: utf-8
33

4-
# # 导入环境
5-
6-
# In[ ]:
7-
8-
4+
# 导入环境
95
import mindnlp
106
import mindspore
117

@@ -14,30 +10,12 @@
1410
import pandas as pd
1511
from transformers import AutoTokenizer, AutoModelForCausalLM, DataCollatorForSeq2Seq, TrainingArguments, Trainer, GenerationConfig
1612

17-
18-
1913
# 将JSON文件转换为CSV文件
2014
df = pd.read_json('/home/lvyufeng/lvyufeng/mindnlp/examples/transformers/peft/lora/huanhuan.json')
2115
ds = Dataset.from_pandas(df)
2216

23-
24-
# In[ ]:
25-
26-
27-
ds[:3]
28-
29-
30-
# # 处理数据集
31-
32-
# In[ ]:
33-
34-
17+
# 处理数据集
3518
tokenizer = AutoTokenizer.from_pretrained('Qwen/Qwen2.5-7B-Instruct', use_fast=False, trust_remote_code=True)
36-
tokenizer
37-
38-
39-
# In[ ]:
40-
4119

4220
def process_func(example):
4321
MAX_LENGTH = 384 # Llama分词器会将一个中文字切分为多个token,因此需要放开一些最大长度,保证数据的完整性
@@ -57,55 +35,14 @@ def process_func(example):
5735
"labels": labels
5836
}
5937

60-
61-
# In[ ]:
62-
63-
6438
tokenized_id = ds.map(process_func, remove_columns=ds.column_names)
6539

66-
print(len(tokenized_id))
67-
68-
# In[ ]:
69-
70-
71-
tokenizer.decode(tokenized_id[0]['input_ids'])
72-
73-
74-
# In[ ]:
75-
76-
77-
tokenizer.decode(list(filter(lambda x: x != -100, tokenized_id[1]["labels"])))
78-
79-
80-
# # 创建模型
81-
82-
# In[ ]:
83-
8440

8541
import torch
86-
87-
model = AutoModelForCausalLM.from_pretrained('Qwen/Qwen2.5-7B-Instruct', torch_dtype=torch.float16, attn_implementation='eager')
88-
# model = AutoModelForCausalLM.from_pretrained('Qwen/Qwen2.5-7B-Instruct', torch_dtype=torch.float16)
89-
model = model.npu()
90-
91-
92-
# In[ ]:
93-
94-
42+
model = AutoModelForCausalLM.from_pretrained('Qwen/Qwen2.5-7B-Instruct', torch_dtype=torch.float16, device_map=0)
9543
model.enable_input_require_grads() # 开启梯度检查点时,要执行该方法
9644

97-
98-
# In[ ]:
99-
100-
101-
model.dtype
102-
103-
104-
# # lora
105-
106-
# In[ ]:
107-
108-
45+
# lora
10946
from peft import LoraConfig, TaskType, get_peft_model
11047

11148
config = LoraConfig(
@@ -116,30 +53,11 @@ def process_func(example):
11653
lora_alpha=32, # Lora alaph,具体作用参见 Lora 原理
11754
lora_dropout=0.1# Dropout 比例
11855
)
119-
config
120-
121-
122-
# In[ ]:
123-
12456

12557
model = get_peft_model(model, config)
126-
config
127-
128-
129-
# In[ ]:
130-
131-
13258
model.print_trainable_parameters()
13359

134-
135-
# In[ ]:
136-
137-
138-
# # 配置训练参数
139-
140-
# In[ ]:
141-
142-
60+
# 配置训练参数
14361
args = TrainingArguments(
14462
output_dir="./output/Qwen2.5_instruct_lora",
14563
per_device_train_batch_size=4,
@@ -149,39 +67,21 @@ def process_func(example):
14967
save_steps=100,
15068
learning_rate=1e-4,
15169
save_on_each_node=True,
152-
# fp16=True,
15370
# gradient_checkpointing=True
15471
)
15572

156-
157-
# In[ ]:
158-
159-
16073
trainer = Trainer(
16174
model=model,
16275
args=args,
16376
train_dataset=tokenized_id,
16477
data_collator=DataCollatorForSeq2Seq(tokenizer=tokenizer, padding=True),
16578
)
16679

167-
168-
# In[ ]:
169-
170-
171-
trainer.accelerator.state
172-
173-
174-
# In[ ]:
175-
176-
17780
trainer.train()
17881

82+
# 合并加载模型
17983

180-
# # 合并加载模型
181-
182-
# In[ ]:
183-
184-
84+
import mindnlp
18585
from transformers import AutoModelForCausalLM, AutoTokenizer
18686
import torch
18787
from peft import PeftModel
@@ -193,11 +93,13 @@ def process_func(example):
19393
tokenizer = AutoTokenizer.from_pretrained(mode_path, trust_remote_code=True)
19494

19595
# 加载模型
196-
model = AutoModelForCausalLM.from_pretrained(mode_path, device_map="auto",torch_dtype=torch.bfloat16, trust_remote_code=True).eval()
96+
model = AutoModelForCausalLM.from_pretrained(mode_path, torch_dtype=torch.float16, trust_remote_code=True).eval()
19797

19898
# 加载lora权重
19999
model = PeftModel.from_pretrained(model, model_id=lora_path)
200100

101+
model = model.npu()
102+
201103
prompt = "你是谁?"
202104
inputs = tokenizer.apply_chat_template([{"role": "user", "content": "假设你是皇帝身边的女人--甄嬛。"},{"role": "user", "content": prompt}],
203105
add_generation_prompt=True,

mindnlp/core/_C/__init__.py

Lines changed: 85 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from typing import Any
2-
from mindspore import Generator as msGenerator
32
import mindspore
3+
from mindspore.ops.operations._inner_ops import Generator as GeneratorOp
44

55
from mindnlp import core
66
from . import _nn
@@ -105,19 +105,101 @@ def __exit__(self, type: Any, value: Any, traceback: Any):
105105

106106
device_ = device
107107

108-
class Generator(msGenerator):
108+
STEP = 0
109+
SEED = 1
110+
GET_STATE = 2
111+
SET_STATE = 3
112+
MANUAL_SEED = 4
113+
INITIAL_SEED = 5
114+
115+
class Generator:
109116
def __init__(self, device='cpu'):
110-
super().__init__()
111117
if device == 'cuda' and DEVICE_TARGET == 'Ascend':
112118
device = 'npu'
113119
self._device = device_(device) if isinstance(device, str) else device
114120

121+
self._seed = mindspore.Tensor(0)
122+
self._offset = mindspore.Tensor(0)
123+
self._generator = GeneratorOp().set_device("CPU")
124+
self._generator.add_prim_attr("manual_seed", False)
125+
126+
115127
@property
116128
def device(self):
117129
if hasattr(self, '_device'):
118130
return self._device
119131
return device('cpu')
120132

133+
def set_state(self, state):
134+
"""
135+
Sets the generator state.
136+
137+
Args:
138+
state (tensor): target state of the generator.
139+
"""
140+
self._generator(SET_STATE, (self._seed, self._offset, state))
141+
142+
def get_state(self):
143+
"""
144+
Get the generator state.
145+
146+
Returns:
147+
Tensor, generator state.
148+
"""
149+
return self._generator(GET_STATE, (self._seed, self._offset))[2]
150+
151+
def seed(self): # pylint: disable=redefined-outer-name
152+
"""
153+
Seed generator with random number.
154+
155+
Returns:
156+
Randomly generated seeds, the type is int.
157+
"""
158+
current_seed = self._generator(
159+
SEED, (self._seed, self._offset))[0]
160+
return current_seed.item()
161+
162+
def manual_seed(self, seed): # pylint: disable=redefined-outer-name
163+
"""
164+
Set the generator seed.
165+
166+
Args:
167+
seed (int): Set the generator seed.
168+
169+
Returns:
170+
Generator, the generator instance.
171+
"""
172+
if not isinstance(seed, int):
173+
raise TypeError("Seed must be an integer.")
174+
seed = mindspore.Tensor(seed, mindspore.int64)
175+
self._generator(MANUAL_SEED, (self._seed, self._offset, seed))
176+
self._generator.add_prim_attr("manual_seed", True)
177+
return self
178+
179+
def initial_seed(self):
180+
"""
181+
Return the initial seed of generator.
182+
183+
Returns:
184+
The initial seed of generator.
185+
"""
186+
current_seed = self._generator(
187+
INITIAL_SEED, (self._seed, self._offset))[0]
188+
return current_seed.item()
189+
190+
191+
def _step(self, step):
192+
"""
193+
Return current seed and offset, and update offset for the next call.
194+
195+
Args:
196+
step (Tensor): Update offset by step.
197+
198+
Returns:
199+
Current seed and offset.
200+
"""
201+
return self._generator(STEP, (self._seed, self._offset, step,))[:2]
202+
121203
default_generator = Generator()
122204

123205
class Tag: pass

mindnlp/core/__init__.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,12 @@
4343

4444

4545

46-
from ._C import *
47-
from ._C.size import Size
4846
from ._dtype import *
49-
from .ops import *
5047
from ._tensor import Tensor, tensor, is_tensor, \
5148
LongTensor, FloatTensor, BoolTensor, HalfTensor, BFloat16Tensor, IntTensor
49+
from ._C import *
50+
from ._C.size import Size
51+
from .ops import *
5252
from ._tensor import enable_mindspore_patch
5353
enable_mindspore_patch()
5454

0 commit comments

Comments
 (0)