woywan commited on
Commit
f4731fe
·
verified ·
1 Parent(s): 3da3e2d

Update pretrain_inference.py

Browse files
Files changed (1) hide show
  1. pretrain_inference.py +159 -130
pretrain_inference.py CHANGED
@@ -1,131 +1,160 @@
1
- import torch
2
- import torch.nn.functional as F
3
- from tokenizers import Tokenizer
4
- import intel_extension_for_pytorch as ipex
5
- from novel_model import NovelTransformer
6
-
7
- # 配置参数
8
- VOCAB_SIZE = 8000
9
- D_MODEL = 128
10
- NHEAD = 4
11
- NUM_LAYERS = 4
12
- DIM_FEEDFORWARD = 512
13
- DROPOUT = 0.1
14
- MAX_LEN = 4096
15
- MODEL_PATH = "d:/图像/novel_model/best_model.pt"
16
- TOKENIZER_PATH = "d:/图像/novel_tokenizer.json"
17
-
18
- def generate_text(model, tokenizer, prompt, max_length=100, temperature=0.8, top_k=50, top_p=0.9, device="cpu"):
19
- """生成文本"""
20
- model.eval()
21
-
22
- # 编码提示
23
- input_ids = torch.tensor(tokenizer.encode(prompt).ids, dtype=torch.long).unsqueeze(0).to(device)
24
-
25
- # 生成文本
26
- with torch.no_grad():
27
- for _ in range(max_length):
28
- # 如果序列太长,截断
29
- if input_ids.size(1) > MAX_LEN:
30
- input_ids = input_ids[:, -MAX_LEN:]
31
-
32
- # 获取模型输出
33
- outputs = model(input_ids)
34
- next_token_logits = outputs[:, -1, :] / temperature
35
-
36
- # 应用top-k过滤
37
- if top_k > 0:
38
- indices_to_remove = next_token_logits < torch.topk(next_token_logits, top_k)[0][..., -1, None]
39
- next_token_logits[indices_to_remove] = float('-inf')
40
-
41
- # 应用top-p过滤
42
- if top_p < 1.0:
43
- sorted_logits, sorted_indices = torch.sort(next_token_logits, descending=True)
44
- cumulative_probs = torch.cumsum(F.softmax(sorted_logits, dim=-1), dim=-1)
45
-
46
- # 移除概率累积超过阈值的token
47
- sorted_indices_to_remove = cumulative_probs > top_p
48
- sorted_indices_to_remove[..., 1:] = sorted_indices_to_remove[..., :-1].clone()
49
- sorted_indices_to_remove[..., 0] = 0
50
-
51
- indices_to_remove = sorted_indices[sorted_indices_to_remove]
52
- next_token_logits[0, indices_to_remove] = float('-inf')
53
-
54
- # 采样下一个token
55
- probs = F.softmax(next_token_logits, dim=-1)
56
- next_token = torch.multinomial(probs, num_samples=1)
57
-
58
- # 添加到输入序列
59
- input_ids = torch.cat([input_ids, next_token], dim=1)
60
-
61
- # 如果生成了结束标记,停止生成
62
- if next_token.item() == tokenizer.token_to_id("</s>"):
63
- break
64
-
65
- # 解码生成的ID
66
- output = tokenizer.decode(input_ids[0].tolist())
67
- return output
68
-
69
- def main():
70
- # 设置设备
71
- device = torch.device("xpu" if torch.xpu.is_available() else "cpu")
72
- print(f"使用设备: {device}")
73
-
74
- # 加载分词器
75
- tokenizer = Tokenizer.from_file(TOKENIZER_PATH)
76
-
77
- # 加载模型
78
- checkpoint = torch.load(MODEL_PATH, map_location=device)
79
-
80
- model = NovelTransformer(
81
- vocab_size=VOCAB_SIZE,
82
- d_model=D_MODEL,
83
- nhead=NHEAD,
84
- num_layers=NUM_LAYERS,
85
- dim_feedforward=DIM_FEEDFORWARD,
86
- dropout=DROPOUT,
87
- max_len=MAX_LEN
88
- )
89
-
90
- model.load_state_dict(checkpoint['model_state_dict'])
91
- model = model.to(device)
92
-
93
- # 设置为评估模式
94
- model.eval()
95
-
96
- # 对于推理,不传递优化器参数
97
- # 在较旧版本的IPEX中,可以使用以下方式优化推理
98
- with torch.no_grad():
99
- model = ipex.optimize(model)
100
-
101
- # 交互式生成
102
- print("预训练小说语言模型已加载。输入提示进行生成,输入'exit'退出。")
103
-
104
- # 测试模型困惑度
105
- test_text = "从前有座山,山上有座庙,庙里有个"
106
- print(f"\n测试文本: {test_text}")
107
-
108
- # 生成文本
109
- generated = generate_text(model, tokenizer, test_text, max_length=50, device=device)
110
- print("\n生成的文本:")
111
- print(generated)
112
-
113
- # 交互式生成
114
- while True:
115
- prompt = input("\n输入提示 (或输入'exit'退出): ")
116
- if prompt.lower() == 'exit':
117
- break
118
-
119
- # 生成参数
120
- length = int(input("生成长度 (默认100): ") or "100")
121
- temp = float(input("温度 (0.1-1.0, 默认0.8): ") or "0.8")
122
-
123
- # 生成文本
124
- generated = generate_text(model, tokenizer, prompt, max_length=length,
125
- temperature=temp, device=device)
126
-
127
- print("\n生成的文本:")
128
- print(generated)
129
-
130
- if __name__ == "__main__":
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
131
  main()
 
1
+ import torch
2
+ import torch.nn.functional as F
3
+ from tokenizers import Tokenizer
4
+ from novel_model import NovelTransformer
5
+
6
+ # 配置参数
7
+ VOCAB_SIZE = 8000
8
+ D_MODEL = 128
9
+ NHEAD = 4
10
+ NUM_LAYERS = 4
11
+ DIM_FEEDFORWARD = 512
12
+ DROPOUT = 0.1
13
+ MAX_LEN = 4096
14
+ MODEL_PATH = "d:/图像/novel_model/best_model.pt"
15
+ TOKENIZER_PATH = "d:/图像/novel_tokenizer.json"
16
+
17
+ def generate_text(model, tokenizer, prompt, max_length=100, temperature=0.8, top_k=50, top_p=0.9, device="cuda"):
18
+ """生成文本"""
19
+ model.eval()
20
+
21
+ # 编码提示
22
+ input_ids = torch.tensor(tokenizer.encode(prompt).ids, dtype=torch.long).unsqueeze(0).to(device)
23
+
24
+ # 生成文本
25
+ with torch.no_grad():
26
+ for _ in range(max_length):
27
+ # 如果序列太长,截断
28
+ if input_ids.size(1) > MAX_LEN:
29
+ input_ids = input_ids[:, -MAX_LEN:]
30
+
31
+ # 获取模型输出
32
+ outputs = model(input_ids)
33
+ next_token_logits = outputs[:, -1, :] / temperature
34
+
35
+ # 应用top-k过滤
36
+ if top_k > 0:
37
+ indices_to_remove = next_token_logits < torch.topk(next_token_logits, top_k)[0][..., -1, None]
38
+ next_token_logits[indices_to_remove] = float('-inf')
39
+
40
+ # 应用top-p过滤
41
+ if top_p < 1.0:
42
+ sorted_logits, sorted_indices = torch.sort(next_token_logits, descending=True)
43
+ cumulative_probs = torch.cumsum(F.softmax(sorted_logits, dim=-1), dim=-1)
44
+
45
+ # 移除概率累积超过阈值的token
46
+ sorted_indices_to_remove = cumulative_probs > top_p
47
+ sorted_indices_to_remove[..., 1:] = sorted_indices_to_remove[..., :-1].clone()
48
+ sorted_indices_to_remove[..., 0] = 0
49
+
50
+ indices_to_remove = sorted_indices[sorted_indices_to_remove]
51
+ next_token_logits[0, indices_to_remove] = float('-inf')
52
+
53
+ # 采样下一个token
54
+ probs = F.softmax(next_token_logits, dim=-1)
55
+ next_token = torch.multinomial(probs, num_samples=1)
56
+
57
+ # 添加到输入序列
58
+ input_ids = torch.cat([input_ids, next_token], dim=1)
59
+
60
+ # 如果生成了结束标记,停止生成
61
+ if next_token.item() == tokenizer.token_to_id("</s>"):
62
+ break
63
+
64
+ # 解码生成的ID
65
+ output = tokenizer.decode(input_ids[0].tolist())
66
+ return output
67
+
68
+ def main():
69
+ # 设置设备
70
+ device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
71
+ print(f"使用设备: {device}")
72
+
73
+ # 显示CUDA信息
74
+ if device.type == 'cuda':
75
+ print(f"CUDA设备: {torch.cuda.get_device_name(0)}")
76
+ print(f"CUDA版本: {torch.version.cuda}")
77
+ print(f"当前GPU内存使用: {torch.cuda.memory_allocated(0)/1024**2:.2f} MB")
78
+
79
+ # 加载分词器
80
+ tokenizer = Tokenizer.from_file(TOKENIZER_PATH)
81
+
82
+ # 加载模型
83
+ checkpoint = torch.load(MODEL_PATH, map_location=device)
84
+
85
+ model = NovelTransformer(
86
+ vocab_size=VOCAB_SIZE,
87
+ d_model=D_MODEL,
88
+ nhead=NHEAD,
89
+ num_layers=NUM_LAYERS,
90
+ dim_feedforward=DIM_FEEDFORWARD,
91
+ dropout=DROPOUT,
92
+ max_len=MAX_LEN
93
+ )
94
+
95
+ model.load_state_dict(checkpoint['model_state_dict'])
96
+ model = model.to(device)
97
+
98
+ # 设置为评估模式
99
+ model.eval()
100
+
101
+ # 启用CUDA优化
102
+ if device.type == 'cuda':
103
+ torch.backends.cudnn.benchmark = True
104
+
105
+ # 测试模型困惑度
106
+ test_text = "从前有座山,山上有座庙,庙里有个"
107
+ print(f"\n测试文本: {test_text}")
108
+
109
+ # 生成文本
110
+ generated = generate_text(model, tokenizer, test_text, max_length=50, device=device)
111
+ print("\n生成的文本:")
112
+ print(generated)
113
+
114
+ # 交互式生成
115
+ print("\n预训练小说语言模型已加载。输入提示进行生成,输入'exit'退出")
116
+
117
+ while True:
118
+ prompt = input("\n请输入提示 (或输入'exit'退出): ")
119
+ if prompt.lower() == 'exit':
120
+ break
121
+
122
+ # 生成参数
123
+ length = int(input("生成长度 (默认100): ") or "100")
124
+ temp = float(input("温度 (0.1-1.0, 默认0.8): ") or "0.8")
125
+ top_k_val = int(input("Top-K (默认50): ") or "50")
126
+ top_p_val = float(input("Top-P (0.0-1.0, 默认0.9): ") or "0.9")
127
+
128
+ # 记录生成开始时间
129
+ start_time = torch.cuda.Event(enable_timing=True)
130
+ end_time = torch.cuda.Event(enable_timing=True)
131
+
132
+ start_time.record()
133
+
134
+ # 生成文本
135
+ generated = generate_text(
136
+ model,
137
+ tokenizer,
138
+ prompt,
139
+ max_length=length,
140
+ temperature=temp,
141
+ top_k=top_k_val,
142
+ top_p=top_p_val,
143
+ device=device
144
+ )
145
+
146
+ end_time.record()
147
+
148
+ # 等待CUDA操作完成
149
+ torch.cuda.synchronize()
150
+
151
+ # 计算生成时间
152
+ generation_time = start_time.elapsed_time(end_time) / 1000 # 转换为秒
153
+
154
+ print("\n生成的文本:")
155
+ print(generated)
156
+ print(f"\n生成时间: {generation_time:.2f} 秒")
157
+ print(f"生成速度: {length/generation_time:.2f} 字符/秒")
158
+
159
+ if __name__ == "__main__":
160
  main()