YeungNLP commited on
Commit
568a444
1 Parent(s): c17c664

Update README.md

Browse files
Files changed (1) hide show
  1. README.md +144 -1
README.md CHANGED
@@ -1,3 +1,146 @@
1
  使用[Firefly](https://github.com/yangjianxin1/Firefly)项目微调ChatGLM2,训练时基本上沿袭官方的多轮对话数据组织格式,并且使用一种更加充分高效的方法训练多轮对话能力。训练数据约为一百万多轮对话数据,包括项目分享的moss数据+2万条school math数据。
2
 
3
- 更多详情见项目[Firefly](https://github.com/yangjianxin1/Firefly)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  使用[Firefly](https://github.com/yangjianxin1/Firefly)项目微调ChatGLM2,训练时基本上沿袭官方的多轮对话数据组织格式,并且使用一种更加充分高效的方法训练多轮对话能力。训练数据约为一百万多轮对话数据,包括项目分享的moss数据+2万条school math数据。
2
 
3
+ 更多详情见项目[Firefly](https://github.com/yangjianxin1/Firefly)
4
+
5
+ 单轮对话:
6
+ ```python
7
+ from transformers import AutoModelForCausalLM, AutoTokenizer
8
+ import torch
9
+ """
10
+ 单轮对话,不具有对话历史的记忆功能
11
+ """
12
+
13
+
14
+ def main():
15
+ model_name = 'YeungNLP/firefly-chatglm2-6b'
16
+
17
+ max_new_tokens = 500
18
+ top_p = 0.9
19
+ temperature = 0.35
20
+ repetition_penalty = 1.0
21
+ device = 'cuda'
22
+ model = AutoModelForCausalLM.from_pretrained(
23
+ model_name,
24
+ trust_remote_code=True,
25
+ low_cpu_mem_usage=True,
26
+ torch_dtype=torch.float16,
27
+ device_map='auto'
28
+ ).to(device).eval()
29
+ tokenizer = AutoTokenizer.from_pretrained(
30
+ model_name,
31
+ trust_remote_code=True,
32
+ # llama不支持fast
33
+ use_fast=False if model.config.model_type == 'llama' else True
34
+ )
35
+ # QWenTokenizer比较特殊,pad_token_id、bos_token_id、eos_token_id均为None。eod_id对应的token为<|endoftext|>
36
+ if tokenizer.__class__.__name__ == 'QWenTokenizer':
37
+ tokenizer.pad_token_id = tokenizer.eod_id
38
+ tokenizer.bos_token_id = tokenizer.eod_id
39
+ tokenizer.eos_token_id = tokenizer.eod_id
40
+
41
+ text = input('User:')
42
+ while True:
43
+ text = text.strip()
44
+ # chatglm使用官方的数据组织格式
45
+ if model.config.model_type == 'chatglm':
46
+ text = '[Round 1]\n\n问:{}\n\n答:'.format(text)
47
+ input_ids = tokenizer(text, return_tensors="pt", add_special_tokens=False).input_ids.to(device)
48
+ # 为了兼容qwen-7b,因为其对eos_token进行tokenize,无法得到对应的eos_token_id
49
+ else:
50
+ input_ids = tokenizer(text, return_tensors="pt", add_special_tokens=False).input_ids.to(device)
51
+ bos_token_id = torch.tensor([[tokenizer.bos_token_id]], dtype=torch.long).to(device)
52
+ eos_token_id = torch.tensor([[tokenizer.eos_token_id]], dtype=torch.long).to(device)
53
+ input_ids = torch.concat([bos_token_id, input_ids, eos_token_id], dim=1)
54
+ with torch.no_grad():
55
+ outputs = model.generate(
56
+ input_ids=input_ids, max_new_tokens=max_new_tokens, do_sample=True,
57
+ top_p=top_p, temperature=temperature, repetition_penalty=repetition_penalty,
58
+ eos_token_id=tokenizer.eos_token_id
59
+ )
60
+ outputs = outputs.tolist()[0][len(input_ids[0]):]
61
+ response = tokenizer.decode(outputs)
62
+ response = response.strip().replace(tokenizer.eos_token, "").strip()
63
+ print("Firefly:{}".format(response))
64
+ text = input('User:')
65
+
66
+
67
+ if __name__ == '__main__':
68
+ main()
69
+ ```
70
+
71
+
72
+ 多轮对话:
73
+ ```python
74
+ from transformers import AutoModelForCausalLM, AutoTokenizer
75
+ import torch
76
+
77
+
78
+ def main():
79
+ model_name = 'YeungNLP/firefly-chatglm2-6b'
80
+
81
+ device = 'cuda'
82
+ max_new_tokens = 500 # 每轮对话最多生成多少个token
83
+ history_max_len = 1000 # 模型记忆的最大token长度
84
+ top_p = 0.9
85
+ temperature = 0.35
86
+ repetition_penalty = 1.0
87
+
88
+ # 加载模型
89
+ model = AutoModelForCausalLM.from_pretrained(
90
+ model_name,
91
+ trust_remote_code=True,
92
+ low_cpu_mem_usage=True,
93
+ torch_dtype=torch.float16,
94
+ device_map='auto'
95
+ ).to(device).eval()
96
+ tokenizer = AutoTokenizer.from_pretrained(
97
+ model_name,
98
+ trust_remote_code=True,
99
+ # llama不支持fast
100
+ use_fast=False if model.config.model_type == 'llama' else True
101
+ )
102
+ # QWenTokenizer比较特殊,pad_token_id、bos_token_id、eos_token_id均为None。eod_id对应的token为<|endoftext|>
103
+ if tokenizer.__class__.__name__ == 'QWenTokenizer':
104
+ tokenizer.pad_token_id = tokenizer.eod_id
105
+ tokenizer.bos_token_id = tokenizer.eod_id
106
+ tokenizer.eos_token_id = tokenizer.eod_id
107
+
108
+ # 记录所有历史记录
109
+ if model.config.model_type != 'chatglm':
110
+ history_token_ids = torch.tensor([[tokenizer.bos_token_id]], dtype=torch.long)
111
+ else:
112
+ history_token_ids = torch.tensor([[]], dtype=torch.long)
113
+
114
+ # 开始对话
115
+ utterance_id = 0 # 记录当前是第几轮对话,为了契合chatglm的数据组织格式
116
+ user_input = input('User:')
117
+ while True:
118
+ utterance_id += 1
119
+ # chatglm使用官方的数据组织格式
120
+ if model.config.model_type == 'chatglm':
121
+ user_input = '[Round {}]\n\n问:{}\n\n答:'.format(utterance_id, user_input)
122
+ user_input_ids = tokenizer(user_input, return_tensors="pt", add_special_tokens=False).input_ids
123
+ # firefly的数据��织格式
124
+ # 为了兼容qwen-7b,因为其对eos_token进行tokenize,无法得到对应的eos_token_id
125
+ else:
126
+ input_ids = tokenizer(user_input, return_tensors="pt", add_special_tokens=False).input_ids
127
+ eos_token_id = torch.tensor([[tokenizer.eos_token_id]], dtype=torch.long)
128
+ user_input_ids = torch.concat([input_ids, eos_token_id], dim=1)
129
+ history_token_ids = torch.concat((history_token_ids, user_input_ids), dim=1)
130
+ model_input_ids = history_token_ids[:, -history_max_len:].to(device)
131
+ with torch.no_grad():
132
+ outputs = model.generate(
133
+ input_ids=model_input_ids, max_new_tokens=max_new_tokens, do_sample=True, top_p=top_p,
134
+ temperature=temperature, repetition_penalty=repetition_penalty, eos_token_id=tokenizer.eos_token_id
135
+ )
136
+ model_input_ids_len = model_input_ids.size(1)
137
+ response_ids = outputs[:, model_input_ids_len:]
138
+ history_token_ids = torch.concat((history_token_ids, response_ids.cpu()), dim=1)
139
+ response = tokenizer.batch_decode(response_ids)
140
+ print("Firefly:" + response[0].strip().replace(tokenizer.eos_token, ""))
141
+ user_input = input('User:')
142
+
143
+
144
+ if __name__ == '__main__':
145
+ main()
146
+ ```