.gitignore ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ *venv
2
+ *.DS_Store
3
+ *.idea/
README.md CHANGED
@@ -10,20 +10,16 @@ tags:
10
  - chatglm
11
  - thudm
12
  inference: false
13
- pipeline_tag: text-generation
14
  ---
15
 
16
  # GLM-4-9B-Chat
 
17
 
18
- Read this in [English](README_en.md)
19
-
20
- GLM-4-9B 是智谱 AI 推出的最新一代预训练模型 GLM-4 系列中的开源版本。 在语义、数学、推理、代码和知识等多方面的数据集测评中,
21
- **GLM-4-9B** 及其人类偏好对齐的版本 **GLM-4-9B-Chat** 均表现出超越 Llama-3-8B 的卓越性能。除了能进行多轮对话,GLM-4-9B-Chat
22
- 还具备网页浏览、代码执行、自定义工具调用(Function Call)和长文本推理(支持最大 128K 上下文)等高级功能。本代模型增加了多语言支持,支持包括日语,韩语,德语在内的
23
- 26 种语言。我们还推出了支持 1M 上下文长度(约 200 万中文字符)的 **GLM-4-9B-Chat-1M** 模型和基于 GLM-4-9B 的多模态模型
24
- GLM-4V-9B。**GLM-4V-9B** 具备 1120 * 1120 高分辨率下的中英双语多轮对话能力,在中英文综合能力、感知推理、文字识别、图表理解等多方面多模态评测中,GLM-4V-9B
25
- 表现出超越 GPT-4-turbo-2024-04-09、Gemini
26
- 1.0 Pro、Qwen-VL-Max 和 Claude 3 Opus 的卓越性能。
27
 
28
  ## 评测结果
29
 
@@ -35,6 +31,7 @@ GLM-4V-9B。**GLM-4V-9B** 具备 1120 * 1120 高分辨率下的中英双语多
35
  | ChatGLM3-6B | 3.97 | 5.50 | 28.1 | 66.4 | 69.0 | 72.3 | 25.7 | 58.5 | 11.3 |
36
  | GLM-4-9B-Chat | 6.61 | 8.35 | 69.0 | 72.4 | 75.6 | 79.6 | 50.6 | 71.8 | 32.2 |
37
 
 
38
  ### 长文本
39
 
40
  在 1M 的上下文长度下进行[大海捞针实验](https://github.com/LargeWorldModel/LWM/blob/main/scripts/eval_needle.py),结果如下:
@@ -49,19 +46,20 @@ GLM-4V-9B。**GLM-4V-9B** 具备 1120 * 1120 高分辨率下的中英双语多
49
 
50
  在六个多语言数据集上对 GLM-4-9B-Chat 和 Llama-3-8B-Instruct 进行了测试,测试结果及数据集对应选取语言如下表
51
 
52
- | Dataset | Llama-3-8B-Instruct | GLM-4-9B-Chat | Languages |
53
  |:------------|:-------------------:|:-------------:|:----------------------------------------------------------------------------------------------:|
54
- | M-MMLU | 49.6 | 56.6 | all |
55
- | FLORES | 25.0 | 28.8 | ru, es, de, fr, it, pt, pl, ja, nl, ar, tr, cs, vi, fa, hu, el, ro, sv, uk, fi, ko, da, bg, no |
56
- | MGSM | 54.0 | 65.3 | zh, en, bn, de, es, fr, ja, ru, sw, te, th |
57
- | XWinograd | 61.7 | 73.1 | zh, en, fr, jp, ru, pt |
58
- | XStoryCloze | 84.7 | 90.7 | zh, en, ar, es, eu, hi, id, my, ru, sw, te |
59
- | XCOPA | 73.3 | 80.1 | zh, et, ht, id, it, qu, sw, ta, th, tr, vi |
 
 
60
 
61
  ### 工具调用能力
62
 
63
- 我们在 [Berkeley Function Calling Leaderboard](https://github.com/ShishirPatil/gorilla/tree/main/berkeley-function-call-leaderboard)
64
- 上进行了测试并得到了以��结果:
65
 
66
  | Model | Overall Acc. | AST Summary | Exec Summary | Relevance |
67
  |:-----------------------|:------------:|:-----------:|:------------:|:---------:|
@@ -74,7 +72,9 @@ GLM-4V-9B。**GLM-4V-9B** 具备 1120 * 1120 高分辨率下的中英双语多
74
 
75
  ## 运行模型
76
 
77
- 使用 transformers 后端进行推理:
 
 
78
 
79
  ```python
80
  import torch
@@ -82,7 +82,7 @@ from transformers import AutoModelForCausalLM, AutoTokenizer
82
 
83
  device = "cuda"
84
 
85
- tokenizer = AutoTokenizer.from_pretrained("THUDM/glm-4-9b-chat", trust_remote_code=True)
86
 
87
  query = "你好"
88
 
@@ -147,25 +147,18 @@ print(outputs[0].outputs[0].text)
147
 
148
  GLM-4 模型的权重的使用则需要遵循 [LICENSE](LICENSE)。
149
 
 
150
  ## 引用
151
 
152
  如果你觉得我们的工作有帮助的话,请考虑引用下列论文。
153
 
154
  ```
155
- @article{zeng2022glm,
156
- title={Glm-130b: An open bilingual pre-trained model},
157
- author={Zeng, Aohan and Liu, Xiao and Du, Zhengxiao and Wang, Zihan and Lai, Hanyu and Ding, Ming and Yang, Zhuoyi and Xu, Yifan and Zheng, Wendi and Xia, Xiao and others},
158
- journal={arXiv preprint arXiv:2210.02414},
159
- year={2022}
 
 
160
  }
161
  ```
162
-
163
- ```
164
- @inproceedings{du2022glm,
165
- title={GLM: General Language Model Pretraining with Autoregressive Blank Infilling},
166
- author={Du, Zhengxiao and Qian, Yujie and Liu, Xiao and Ding, Ming and Qiu, Jiezhong and Yang, Zhilin and Tang, Jie},
167
- booktitle={Proceedings of the 60th Annual Meeting of the Association for Computational Linguistics (Volume 1: Long Papers)},
168
- pages={320--335},
169
- year={2022}
170
- }
171
- ```
 
10
  - chatglm
11
  - thudm
12
  inference: false
 
13
  ---
14
 
15
  # GLM-4-9B-Chat
16
+ Read this in [English](README_en.md).
17
 
18
+ GLM-4-9B 是智谱 AI 推出的最新一代预训练模型 GLM-4 系列中的开源版本。
19
+ 在语义、数学、推理、代码和知识等多方面的数据集测评中,GLM-4-9B 及其人类偏好对齐的版本 GLM-4-9B-Chat 均表现出较高的性能。
20
+ 除了能进行多轮对话,GLM-4-9B-Chat 还具备网页浏览、代码执行、自定义工具调用(Function Call)和长文本推理(支持最大 128K
21
+ 上下文)等高级功能。
22
+ 本代模型增加了多语言支持,支持包括日语,韩语,德语在内的 26 种语言。我们还推出了支持 1M 上下文长度(约 200 万中文字符)的模型。
 
 
 
 
23
 
24
  ## 评测结果
25
 
 
31
  | ChatGLM3-6B | 3.97 | 5.50 | 28.1 | 66.4 | 69.0 | 72.3 | 25.7 | 58.5 | 11.3 |
32
  | GLM-4-9B-Chat | 6.61 | 8.35 | 69.0 | 72.4 | 75.6 | 79.6 | 50.6 | 71.8 | 32.2 |
33
 
34
+
35
  ### 长文本
36
 
37
  在 1M 的上下文长度下进行[大海捞针实验](https://github.com/LargeWorldModel/LWM/blob/main/scripts/eval_needle.py),结果如下:
 
46
 
47
  在六个多语言数据集上对 GLM-4-9B-Chat 和 Llama-3-8B-Instruct 进行了测试,测试结果及数据集对应选取语言如下表
48
 
49
+ | Dataset | Llama-3-8B-Instruct | GLM-4-9B-Chat | Languages
50
  |:------------|:-------------------:|:-------------:|:----------------------------------------------------------------------------------------------:|
51
+ | M-MMLU | 49.6 | 56.6 | all
52
+ | FLORES | 25.0 | 28.8 | ru, es, de, fr, it, pt, pl, ja, nl, ar, tr, cs, vi, fa, hu, el, ro, sv, uk, fi, ko, da, bg, no
53
+ | MGSM | 54.0 | 65.3 | zh, en, bn, de, es, fr, ja, ru, sw, te, th
54
+ | XWinograd | 61.7 | 73.1 | zh, en, fr, jp, ru, pt
55
+ | XStoryCloze | 84.7 | 90.7 | zh, en, ar, es, eu, hi, id, my, ru, sw, te
56
+ | XCOPA | 73.3 | 80.1 | zh, et, ht, id, it, qu, sw, ta, th, tr, vi
57
+
58
+
59
 
60
  ### 工具调用能力
61
 
62
+ 我们在 [Berkeley Function Calling Leaderboard](https://github.com/ShishirPatil/gorilla/tree/main/berkeley-function-call-leaderboard)上进行了测试并得到了以下结果:
 
63
 
64
  | Model | Overall Acc. | AST Summary | Exec Summary | Relevance |
65
  |:-----------------------|:------------:|:-----------:|:------------:|:---------:|
 
72
 
73
  ## 运行模型
74
 
75
+ 更多推理代码和依赖信息,请访问我们的 [github](https://github.com/THUDM/GLM-4)
76
+
77
+ ### 使用 transformers 后端进行推理:
78
 
79
  ```python
80
  import torch
 
82
 
83
  device = "cuda"
84
 
85
+ tokenizer = AutoTokenizer.from_pretrained("THUDM/glm-4-9b-chat",trust_remote_code=True)
86
 
87
  query = "你好"
88
 
 
147
 
148
  GLM-4 模型的权重的使用则需要遵循 [LICENSE](LICENSE)。
149
 
150
+
151
  ## 引用
152
 
153
  如果你觉得我们的工作有帮助的话,请考虑引用下列论文。
154
 
155
  ```
156
+ @misc{glm2024chatglm,
157
+ title={ChatGLM: A Family of Large Language Models from GLM-130B to GLM-4 All Tools},
158
+ author={Team GLM and Aohan Zeng and Bin Xu and Bowen Wang and Chenhui Zhang and Da Yin and Diego Rojas and Guanyu Feng and Hanlin Zhao and Hanyu Lai and Hao Yu and Hongning Wang and Jiadai Sun and Jiajie Zhang and Jiale Cheng and Jiayi Gui and Jie Tang and Jing Zhang and Juanzi Li and Lei Zhao and Lindong Wu and Lucen Zhong and Mingdao Liu and Minlie Huang and Peng Zhang and Qinkai Zheng and Rui Lu and Shuaiqi Duan and Shudan Zhang and Shulin Cao and Shuxun Yang and Weng Lam Tam and Wenyi Zhao and Xiao Liu and Xiao Xia and Xiaohan Zhang and Xiaotao Gu and Xin Lv and Xinghan Liu and Xinyi Liu and Xinyue Yang and Xixuan Song and Xunkai Zhang and Yifan An and Yifan Xu and Yilin Niu and Yuantao Yang and Yueyan Li and Yushi Bai and Yuxiao Dong and Zehan Qi and Zhaoyu Wang and Zhen Yang and Zhengxiao Du and Zhenyu Hou and Zihan Wang},
159
+ year={2024},
160
+ eprint={2406.12793},
161
+ archivePrefix={arXiv},
162
+ primaryClass={id='cs.CL' full_name='Computation and Language' is_active=True alt_name='cmp-lg' in_archive='cs' is_general=False description='Covers natural language processing. Roughly includes material in ACM Subject Class I.2.7. Note that work on artificial languages (programming languages, logics, formal systems) that does not explicitly address natural-language issues broadly construed (natural-language processing, computational linguistics, speech, text retrieval, etc.) is not appropriate for this area.'}
163
  }
164
  ```
 
 
 
 
 
 
 
 
 
 
README_en.md CHANGED
@@ -64,9 +64,9 @@ on [Berkeley Function Calling Leaderboard](https://github.com/ShishirPatil/goril
64
 
65
  **This repository is the model repository of GLM-4-9B-Chat, supporting `128K` context length.**
66
 
67
- ## Quick call
68
 
69
- **For hardware configuration and system requirements, please check [here](basic_demo/README_en.md).**
70
 
71
  ### Use the following method to quickly call the GLM-4-9B-Chat language model
72
 
@@ -135,7 +135,6 @@ sampling_params = SamplingParams(temperature=0.95, max_tokens=1024, stop_token_i
135
 
136
  inputs = tokenizer.apply_chat_template(prompt, tokenize=False, add_generation_prompt=True)
137
  outputs = llm.generate(prompts=inputs, sampling_params=sampling_params)
138
-
139
  print(outputs[0].outputs[0].text)
140
  ```
141
 
@@ -148,20 +147,12 @@ The weights of the GLM-4 model are available under the terms of [LICENSE](LICENS
148
  If you find our work useful, please consider citing the following paper.
149
 
150
  ```
151
- @article{zeng2022glm,
152
- title={Glm-130b: An open bilingual pre-trained model},
153
- author={Zeng, Aohan and Liu, Xiao and Du, Zhengxiao and Wang, Zihan and Lai, Hanyu and Ding, Ming and Yang, Zhuoyi and Xu, Yifan and Zheng, Wendi and Xia, Xiao and others},
154
- journal={arXiv preprint arXiv:2210.02414},
155
- year={2022}
156
- }
157
- ```
158
-
159
- ```
160
- @inproceedings{du2022glm,
161
- title={GLM: General Language Model Pretraining with Autoregressive Blank Infilling},
162
- author={Du, Zhengxiao and Qian, Yujie and Liu, Xiao and Ding, Ming and Qiu, Jiezhong and Yang, Zhilin and Tang, Jie},
163
- booktitle={Proceedings of the 60th Annual Meeting of the Association for Computational Linguistics (Volume 1: Long Papers)},
164
- pages={320--335},
165
- year={2022}
166
  }
167
  ```
 
64
 
65
  **This repository is the model repository of GLM-4-9B-Chat, supporting `128K` context length.**
66
 
67
+ ## Quick Start
68
 
69
+ For more inference code and requirements, please visit our [github page](https://github.com/THUDM/GLM-4).
70
 
71
  ### Use the following method to quickly call the GLM-4-9B-Chat language model
72
 
 
135
 
136
  inputs = tokenizer.apply_chat_template(prompt, tokenize=False, add_generation_prompt=True)
137
  outputs = llm.generate(prompts=inputs, sampling_params=sampling_params)
 
138
  print(outputs[0].outputs[0].text)
139
  ```
140
 
 
147
  If you find our work useful, please consider citing the following paper.
148
 
149
  ```
150
+ @misc{glm2024chatglm,
151
+ title={ChatGLM: A Family of Large Language Models from GLM-130B to GLM-4 All Tools},
152
+ author={Team GLM and Aohan Zeng and Bin Xu and Bowen Wang and Chenhui Zhang and Da Yin and Diego Rojas and Guanyu Feng and Hanlin Zhao and Hanyu Lai and Hao Yu and Hongning Wang and Jiadai Sun and Jiajie Zhang and Jiale Cheng and Jiayi Gui and Jie Tang and Jing Zhang and Juanzi Li and Lei Zhao and Lindong Wu and Lucen Zhong and Mingdao Liu and Minlie Huang and Peng Zhang and Qinkai Zheng and Rui Lu and Shuaiqi Duan and Shudan Zhang and Shulin Cao and Shuxun Yang and Weng Lam Tam and Wenyi Zhao and Xiao Liu and Xiao Xia and Xiaohan Zhang and Xiaotao Gu and Xin Lv and Xinghan Liu and Xinyi Liu and Xinyue Yang and Xixuan Song and Xunkai Zhang and Yifan An and Yifan Xu and Yilin Niu and Yuantao Yang and Yueyan Li and Yushi Bai and Yuxiao Dong and Zehan Qi and Zhaoyu Wang and Zhen Yang and Zhengxiao Du and Zhenyu Hou and Zihan Wang},
153
+ year={2024},
154
+ eprint={2406.12793},
155
+ archivePrefix={arXiv},
156
+ primaryClass={id='cs.CL' full_name='Computation and Language' is_active=True alt_name='cmp-lg' in_archive='cs' is_general=False description='Covers natural language processing. Roughly includes material in ACM Subject Class I.2.7. Note that work on artificial languages (programming languages, logics, formal systems) that does not explicitly address natural-language issues broadly construed (natural-language processing, computational linguistics, speech, text retrieval, etc.) is not appropriate for this area.'}
 
 
 
 
 
 
 
 
157
  }
158
  ```
config.json CHANGED
@@ -1,5 +1,5 @@
1
  {
2
- "_name_or_path": "THUDM/glm4-9b-chat",
3
  "model_type": "chatglm",
4
  "architectures": [
5
  "ChatGLMModel"
@@ -17,6 +17,7 @@
17
  "apply_residual_connection_post_layernorm": false,
18
  "attention_dropout": 0.0,
19
  "attention_softmax_in_fp32": true,
 
20
  "bias_dropout_fusion": true,
21
  "ffn_hidden_size": 13696,
22
  "fp32_residual_connection": false,
@@ -37,9 +38,8 @@
37
  "seq_length": 131072,
38
  "use_cache": true,
39
  "torch_dtype": "bfloat16",
40
- "transformers_version": "4.30.2",
41
  "tie_word_embeddings": false,
42
  "eos_token_id": [151329, 151336, 151338],
43
  "pad_token_id": 151329
44
- }
45
-
 
1
  {
2
+ "_name_or_path": "THUDM/glm-4-9b-chat",
3
  "model_type": "chatglm",
4
  "architectures": [
5
  "ChatGLMModel"
 
17
  "apply_residual_connection_post_layernorm": false,
18
  "attention_dropout": 0.0,
19
  "attention_softmax_in_fp32": true,
20
+ "attn_implementation": "sdpa",
21
  "bias_dropout_fusion": true,
22
  "ffn_hidden_size": 13696,
23
  "fp32_residual_connection": false,
 
38
  "seq_length": 131072,
39
  "use_cache": true,
40
  "torch_dtype": "bfloat16",
41
+ "transformers_version": "4.40.2",
42
  "tie_word_embeddings": false,
43
  "eos_token_id": [151329, 151336, 151338],
44
  "pad_token_id": 151329
45
+ }
 
generation_config.json CHANGED
@@ -9,5 +9,5 @@
9
  "temperature": 0.8,
10
  "max_length": 128000,
11
  "top_p": 0.8,
12
- "transformers_version": "4.38.2"
13
  }
 
9
  "temperature": 0.8,
10
  "max_length": 128000,
11
  "top_p": 0.8,
12
+ "transformers_version": "4.40.2"
13
  }
modeling_chatglm.py CHANGED
@@ -21,12 +21,17 @@ from transformers.modeling_outputs import (
21
  SequenceClassifierOutputWithPast,
22
  )
23
  from transformers.modeling_utils import PreTrainedModel
24
- from transformers.utils import logging, is_torch_npu_available
 
25
  from transformers.generation.logits_process import LogitsProcessor
26
  from transformers.generation.utils import LogitsProcessorList, StoppingCriteriaList, GenerationConfig, ModelOutput
27
 
28
  from .configuration_chatglm import ChatGLMConfig
29
 
 
 
 
 
30
  # flags required to enable jit fusion kernels
31
 
32
  if sys.platform != 'darwin' and not is_torch_npu_available():
@@ -40,6 +45,7 @@ logger = logging.get_logger(__name__)
40
  _CHECKPOINT_FOR_DOC = "THUDM/ChatGLM"
41
  _CONFIG_FOR_DOC = "ChatGLMConfig"
42
 
 
43
  def default_init(cls, *args, **kwargs):
44
  return cls(*args, **kwargs)
45
 
@@ -159,12 +165,13 @@ class RMSNorm(torch.nn.Module):
159
  class CoreAttention(torch.nn.Module):
160
  def __init__(self, config: ChatGLMConfig, layer_number):
161
  super(CoreAttention, self).__init__()
162
-
163
  self.apply_query_key_layer_scaling = config.apply_query_key_layer_scaling
164
  self.attention_softmax_in_fp32 = config.attention_softmax_in_fp32
165
  if self.apply_query_key_layer_scaling:
166
  self.attention_softmax_in_fp32 = True
167
  self.layer_number = max(1, layer_number)
 
168
 
169
  projection_size = config.kv_channels * config.num_attention_heads
170
 
@@ -183,91 +190,198 @@ class CoreAttention(torch.nn.Module):
183
  self.attention_dropout = torch.nn.Dropout(config.attention_dropout)
184
 
185
  def forward(self, query_layer, key_layer, value_layer, attention_mask):
186
- pytorch_major_version = int(torch.__version__.split('.')[0])
187
- if pytorch_major_version >= 2:
188
- if attention_mask is None and query_layer.shape[2] == key_layer.shape[2]:
189
- context_layer = torch.nn.functional.scaled_dot_product_attention(query_layer, key_layer, value_layer,
190
- is_causal=True)
191
- else:
192
- if attention_mask is not None:
193
- attention_mask = ~attention_mask
194
- context_layer = torch.nn.functional.scaled_dot_product_attention(query_layer, key_layer, value_layer,
195
- attention_mask)
196
- context_layer = context_layer.transpose(1, 2).contiguous()
197
- new_context_layer_shape = context_layer.size()[:-2] + (self.hidden_size_per_partition,)
198
- context_layer = context_layer.reshape(*new_context_layer_shape)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
199
  else:
200
- # Raw attention scores
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
201
 
202
- # [b, np, sq, sk]
203
- output_size = (query_layer.size(0), query_layer.size(1), query_layer.size(2), key_layer.size(2))
204
 
205
- # [b, np, sq, hn] -> [b * np, sq, hn]
206
- query_layer = query_layer.view(output_size[0] * output_size[1], output_size[2], -1)
207
- # [b, np, sk, hn] -> [b * np, sk, hn]
208
- key_layer = key_layer.view(output_size[0] * output_size[1], output_size[3], -1)
 
209
 
210
- # preallocting input tensor: [b * np, sq, sk]
211
- matmul_input_buffer = torch.empty(
212
- output_size[0] * output_size[1], output_size[2], output_size[3], dtype=query_layer.dtype,
213
- device=query_layer.device
 
 
 
 
 
 
 
 
 
 
 
214
  )
215
 
216
- # Raw attention scores. [b * np, sq, sk]
217
- matmul_result = torch.baddbmm(
218
- matmul_input_buffer,
219
- query_layer, # [b * np, sq, hn]
220
- key_layer.transpose(1, 2), # [b * np, hn, sk]
221
- beta=0.0,
222
- alpha=(1.0 / self.norm_factor),
 
 
 
 
 
 
 
223
  )
224
 
225
- # change view to [b, np, sq, sk]
226
- attention_scores = matmul_result.view(*output_size)
227
-
228
- # ===========================
229
- # Attention probs and dropout
230
- # ===========================
231
-
232
- # attention scores and attention mask [b, np, sq, sk]
233
- if self.attention_softmax_in_fp32:
234
- attention_scores = attention_scores.float()
235
- if self.coeff is not None:
236
- attention_scores = attention_scores * self.coeff
237
- if attention_mask is None and attention_scores.shape[2] == attention_scores.shape[3]:
238
- attention_mask = torch.ones(output_size[0], 1, output_size[2], output_size[3],
239
- device=attention_scores.device, dtype=torch.bool)
240
- attention_mask.tril_()
241
- attention_mask = ~attention_mask
242
- if attention_mask is not None:
243
- attention_scores = attention_scores.masked_fill(attention_mask, float("-inf"))
244
- attention_probs = F.softmax(attention_scores, dim=-1)
245
- attention_probs = attention_probs.type_as(value_layer)
246
-
247
- # This is actually dropping out entire tokens to attend to, which might
248
- # seem a bit unusual, but is taken from the original Transformer paper.
249
- attention_probs = self.attention_dropout(attention_probs)
250
-
251
- # query layer shape: [b * np, sq, hn]
252
- # value layer shape: [b, np, sk, hn]
253
- # attention shape: [b, np, sq, sk]
254
- # context layer shape: [b, np, sq, hn]
255
- output_size = (value_layer.size(0), value_layer.size(1), query_layer.size(1), value_layer.size(3))
256
- # change view [b * np, sk, hn]
257
- value_layer = value_layer.view(output_size[0] * output_size[1], value_layer.size(2), -1)
258
- # change view [b * np, sq, sk]
259
- attention_probs = attention_probs.view(output_size[0] * output_size[1], output_size[2], -1)
260
- # matmul: [b * np, sq, hn]
261
- context_layer = torch.bmm(attention_probs, value_layer)
262
- # change view [b, np, sq, hn]
263
- context_layer = context_layer.view(*output_size)
264
- # [b, np, sq, hn] --> [b, sq, np, hn]
265
- context_layer = context_layer.transpose(1, 2).contiguous()
266
- # [b, sq, np, hn] --> [b, sq, hp]
267
- new_context_layer_shape = context_layer.size()[:-2] + (self.hidden_size_per_partition,)
268
- context_layer = context_layer.reshape(*new_context_layer_shape)
269
 
270
- return context_layer
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
271
 
272
 
273
  class SelfAttention(torch.nn.Module):
@@ -299,7 +413,7 @@ class SelfAttention(torch.nn.Module):
299
  device=device, **_config_to_kwargs(config)
300
  )
301
 
302
- self.core_attention = CoreAttention(config, self.layer_number)
303
 
304
  # Output.
305
  self.dense = nn.Linear(self.projection_size, config.hidden_size, bias=config.add_bias_linear,
@@ -378,7 +492,8 @@ class SelfAttention(torch.nn.Module):
378
  value_layer = torch.cat((cache_v, value_layer), dim=2)
379
  if use_cache:
380
  if kv_cache is None:
381
- kv_cache = torch.cat((key_layer.unsqueeze(0).unsqueeze(0), value_layer.unsqueeze(0).unsqueeze(0)), dim=1)
 
382
  else:
383
  kv_cache = (key_layer, value_layer)
384
  else:
@@ -644,12 +759,18 @@ class ChatGLMPreTrainedModel(PreTrainedModel):
644
  config_class = ChatGLMConfig
645
  base_model_prefix = "transformer"
646
  _no_split_modules = ["GLMBlock"]
 
 
647
 
648
  def _init_weights(self, module: nn.Module):
649
  """Initialize the weights."""
650
  return
651
 
652
  def get_masks(self, input_ids, past_key_values, padding_mask=None):
 
 
 
 
653
  batch_size, seq_length = input_ids.shape
654
  full_attention_mask = torch.ones(batch_size, seq_length, seq_length, device=input_ids.device)
655
  full_attention_mask.tril_()
@@ -724,7 +845,8 @@ class ChatGLMModel(ChatGLMPreTrainedModel):
724
  config.hidden_size // config.num_attention_heads if config.kv_channels is None else config.kv_channels
725
  )
726
 
727
- self.rotary_pos_emb = RotaryEmbedding(rotary_dim // 2, rope_ratio=config.rope_ratio, original_impl=config.original_rope,
 
728
  device=device, dtype=config.torch_dtype)
729
  self.encoder = init_method(GLMTransformer, config, **init_kwargs)
730
  self.output_layer = init_method(nn.Linear, config.hidden_size, config.padded_vocab_size, bias=False,
@@ -745,6 +867,7 @@ class ChatGLMModel(ChatGLMPreTrainedModel):
745
  past_key_values: Optional[Tuple[Tuple[torch.Tensor, torch.Tensor], ...]] = None,
746
  inputs_embeds: Optional[torch.Tensor] = None,
747
  use_cache: Optional[bool] = None,
 
748
  output_hidden_states: Optional[bool] = None,
749
  return_dict: Optional[bool] = None,
750
  ):
@@ -1156,6 +1279,7 @@ class ChatGLMForSequenceClassification(ChatGLMPreTrainedModel):
1156
  inputs_embeds: Optional[torch.LongTensor] = None,
1157
  labels: Optional[torch.LongTensor] = None,
1158
  use_cache: Optional[bool] = None,
 
1159
  output_hidden_states: Optional[bool] = None,
1160
  return_dict: Optional[bool] = None,
1161
  ) -> Union[Tuple[torch.Tensor, ...], SequenceClassifierOutputWithPast]:
@@ -1169,6 +1293,7 @@ class ChatGLMForSequenceClassification(ChatGLMPreTrainedModel):
1169
  past_key_values=past_key_values,
1170
  inputs_embeds=inputs_embeds,
1171
  use_cache=use_cache,
 
1172
  output_hidden_states=output_hidden_states,
1173
  return_dict=return_dict,
1174
  )
 
21
  SequenceClassifierOutputWithPast,
22
  )
23
  from transformers.modeling_utils import PreTrainedModel
24
+ from transformers.utils import logging, is_torch_npu_available, is_flash_attn_greater_or_equal_2_10, \
25
+ is_flash_attn_2_available
26
  from transformers.generation.logits_process import LogitsProcessor
27
  from transformers.generation.utils import LogitsProcessorList, StoppingCriteriaList, GenerationConfig, ModelOutput
28
 
29
  from .configuration_chatglm import ChatGLMConfig
30
 
31
+ if is_flash_attn_2_available():
32
+ from flash_attn import flash_attn_func, flash_attn_varlen_func
33
+ from flash_attn.bert_padding import index_first_axis, pad_input, unpad_input # noqa
34
+
35
  # flags required to enable jit fusion kernels
36
 
37
  if sys.platform != 'darwin' and not is_torch_npu_available():
 
45
  _CHECKPOINT_FOR_DOC = "THUDM/ChatGLM"
46
  _CONFIG_FOR_DOC = "ChatGLMConfig"
47
 
48
+
49
  def default_init(cls, *args, **kwargs):
50
  return cls(*args, **kwargs)
51
 
 
165
  class CoreAttention(torch.nn.Module):
166
  def __init__(self, config: ChatGLMConfig, layer_number):
167
  super(CoreAttention, self).__init__()
168
+ self.config = config
169
  self.apply_query_key_layer_scaling = config.apply_query_key_layer_scaling
170
  self.attention_softmax_in_fp32 = config.attention_softmax_in_fp32
171
  if self.apply_query_key_layer_scaling:
172
  self.attention_softmax_in_fp32 = True
173
  self.layer_number = max(1, layer_number)
174
+ self.is_causal = True
175
 
176
  projection_size = config.kv_channels * config.num_attention_heads
177
 
 
190
  self.attention_dropout = torch.nn.Dropout(config.attention_dropout)
191
 
192
  def forward(self, query_layer, key_layer, value_layer, attention_mask):
193
+ # [b, np, sq, sk]
194
+ output_size = (query_layer.size(0), query_layer.size(1), query_layer.size(2), key_layer.size(2))
195
+
196
+ # [b, np, sq, hn] -> [b * np, sq, hn]
197
+ query_layer = query_layer.view(output_size[0] * output_size[1], output_size[2], -1)
198
+ # [b, np, sk, hn] -> [b * np, sk, hn]
199
+ key_layer = key_layer.view(output_size[0] * output_size[1], output_size[3], -1)
200
+
201
+ # preallocting input tensor: [b * np, sq, sk]
202
+ matmul_input_buffer = torch.empty(
203
+ output_size[0] * output_size[1], output_size[2], output_size[3], dtype=query_layer.dtype,
204
+ device=query_layer.device
205
+ )
206
+
207
+ # Raw attention scores. [b * np, sq, sk]
208
+ matmul_result = torch.baddbmm(
209
+ matmul_input_buffer,
210
+ query_layer, # [b * np, sq, hn]
211
+ key_layer.transpose(1, 2), # [b * np, hn, sk]
212
+ beta=0.0,
213
+ alpha=(1.0 / self.norm_factor),
214
+ )
215
+
216
+ # change view to [b, np, sq, sk]
217
+ attention_scores = matmul_result.view(*output_size)
218
+
219
+ # ===========================
220
+ # Attention probs and dropout
221
+ # ===========================
222
+
223
+ # attention scores and attention mask [b, np, sq, sk]
224
+ if self.attention_softmax_in_fp32:
225
+ attention_scores = attention_scores.float()
226
+ if self.coeff is not None:
227
+ attention_scores = attention_scores * self.coeff
228
+ if attention_mask is None and attention_scores.shape[2] == attention_scores.shape[3]:
229
+ attention_mask = torch.ones(output_size[0], 1, output_size[2], output_size[3],
230
+ device=attention_scores.device, dtype=torch.bool)
231
+ attention_mask.tril_()
232
+ attention_mask = ~attention_mask
233
+ if attention_mask is not None:
234
+ attention_scores = attention_scores.masked_fill(attention_mask, float("-inf"))
235
+ attention_probs = F.softmax(attention_scores, dim=-1)
236
+ attention_probs = attention_probs.type_as(value_layer)
237
+
238
+ # This is actually dropping out entire tokens to attend to, which might
239
+ # seem a bit unusual, but is taken from the original Transformer paper.
240
+ attention_probs = self.attention_dropout(attention_probs)
241
+
242
+ # query layer shape: [b * np, sq, hn]
243
+ # value layer shape: [b, np, sk, hn]
244
+ # attention shape: [b, np, sq, sk]
245
+ # context layer shape: [b, np, sq, hn]
246
+ output_size = (value_layer.size(0), value_layer.size(1), query_layer.size(1), value_layer.size(3))
247
+ # change view [b * np, sk, hn]
248
+ value_layer = value_layer.view(output_size[0] * output_size[1], value_layer.size(2), -1)
249
+ # change view [b * np, sq, sk]
250
+ attention_probs = attention_probs.view(output_size[0] * output_size[1], output_size[2], -1)
251
+ # matmul: [b * np, sq, hn]
252
+ context_layer = torch.bmm(attention_probs, value_layer)
253
+ # change view [b, np, sq, hn]
254
+ context_layer = context_layer.view(*output_size)
255
+ # [b, np, sq, hn] --> [b, sq, np, hn]
256
+ context_layer = context_layer.transpose(1, 2).contiguous()
257
+ # [b, sq, np, hn] --> [b, sq, hp]
258
+ new_context_layer_shape = context_layer.size()[:-2] + (self.hidden_size_per_partition,)
259
+ context_layer = context_layer.reshape(*new_context_layer_shape)
260
+
261
+ return context_layer
262
+
263
+
264
+ class SdpaAttention(CoreAttention):
265
+ def forward(self, query_layer, key_layer, value_layer, attention_mask):
266
+ if attention_mask is None and query_layer.shape[2] == key_layer.shape[2]:
267
+ context_layer = torch.nn.functional.scaled_dot_product_attention(query_layer, key_layer, value_layer,
268
+ is_causal=True,
269
+ dropout_p=self.config.attention_dropout if self.training else 0.0)
270
  else:
271
+ if attention_mask is not None:
272
+ attention_mask = ~attention_mask
273
+ context_layer = torch.nn.functional.scaled_dot_product_attention(query_layer, key_layer, value_layer,
274
+ attention_mask,
275
+ dropout_p=self.config.attention_dropout if self.training else 0.0)
276
+ context_layer = context_layer.transpose(1, 2).contiguous()
277
+ new_context_layer_shape = context_layer.size()[:-2] + (self.hidden_size_per_partition,)
278
+ context_layer = context_layer.reshape(*new_context_layer_shape)
279
+ return context_layer
280
+
281
+
282
+ def _get_unpad_data(attention_mask):
283
+ seqlens_in_batch = attention_mask.sum(dim=-1, dtype=torch.int32)
284
+ indices = torch.nonzero(attention_mask.flatten(), as_tuple=False).flatten()
285
+ max_seqlen_in_batch = seqlens_in_batch.max().item()
286
+ cu_seqlens = F.pad(torch.cumsum(seqlens_in_batch, dim=0, dtype=torch.int32), (1, 0))
287
+ return (
288
+ indices,
289
+ cu_seqlens,
290
+ max_seqlen_in_batch,
291
+ )
292
 
 
 
293
 
294
+ # Copied from transformers.models.llama.modeling_llama.LlamaFlashAttention2
295
+ class FlashAttention2(CoreAttention):
296
+ def __init__(self, *args, **kwargs):
297
+ super().__init__(*args, **kwargs)
298
+ self._flash_attn_uses_top_left_mask = not is_flash_attn_greater_or_equal_2_10()
299
 
300
+ def forward(self, query_states, key_states, value_states, attention_mask):
301
+ query_states = query_states.transpose(1, 2)
302
+ key_states = key_states.transpose(1, 2)
303
+ value_states = value_states.transpose(1, 2)
304
+ batch_size, query_length = query_states.shape[:2]
305
+ if not self._flash_attn_uses_top_left_mask:
306
+ causal = self.is_causal
307
+ else:
308
+ # TODO: Remove the `query_length != 1` check once Flash Attention for RoCm is bumped to 2.1. For details, please see the comment in LlamaFlashAttention2 __init__.
309
+ causal = self.is_causal and query_length != 1
310
+ dropout = self.config.attention_dropout if self.training else 0.0
311
+ # Contains at least one padding token in the sequence
312
+ if attention_mask is not None:
313
+ query_states, key_states, value_states, indices_q, cu_seq_lens, max_seq_lens = self._upad_input(
314
+ query_states, key_states, value_states, attention_mask, query_length
315
  )
316
 
317
+ cu_seqlens_q, cu_seqlens_k = cu_seq_lens
318
+ max_seqlen_in_batch_q, max_seqlen_in_batch_k = max_seq_lens
319
+
320
+ attn_output_unpad = flash_attn_varlen_func(
321
+ query_states,
322
+ key_states,
323
+ value_states,
324
+ cu_seqlens_q=cu_seqlens_q,
325
+ cu_seqlens_k=cu_seqlens_k,
326
+ max_seqlen_q=max_seqlen_in_batch_q,
327
+ max_seqlen_k=max_seqlen_in_batch_k,
328
+ dropout_p=dropout,
329
+ softmax_scale=None,
330
+ causal=causal,
331
  )
332
 
333
+ attn_output = pad_input(attn_output_unpad, indices_q, batch_size, query_length)
334
+ else:
335
+ attn_output = flash_attn_func(
336
+ query_states, key_states, value_states, dropout, softmax_scale=None, causal=causal
337
+ )
338
+ attn_output = attn_output.reshape(batch_size, query_length, self.hidden_size_per_partition).contiguous()
339
+ return attn_output
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
340
 
341
+ def _upad_input(self, query_layer, key_layer, value_layer, attention_mask, query_length):
342
+ indices_k, cu_seqlens_k, max_seqlen_in_batch_k = _get_unpad_data(attention_mask)
343
+ batch_size, kv_seq_len, num_key_value_heads, head_dim = key_layer.shape
344
+
345
+ key_layer = index_first_axis(
346
+ key_layer.reshape(batch_size * kv_seq_len, num_key_value_heads, head_dim), indices_k
347
+ )
348
+ value_layer = index_first_axis(
349
+ value_layer.reshape(batch_size * kv_seq_len, num_key_value_heads, head_dim), indices_k
350
+ )
351
+ if query_length == kv_seq_len:
352
+ query_layer = index_first_axis(
353
+ query_layer.reshape(batch_size * kv_seq_len, self.num_attention_heads_per_partition, head_dim), indices_k
354
+ )
355
+ cu_seqlens_q = cu_seqlens_k
356
+ max_seqlen_in_batch_q = max_seqlen_in_batch_k
357
+ indices_q = indices_k
358
+ elif query_length == 1:
359
+ max_seqlen_in_batch_q = 1
360
+ cu_seqlens_q = torch.arange(
361
+ batch_size + 1, dtype=torch.int32, device=query_layer.device
362
+ ) # There is a memcpy here, that is very bad.
363
+ indices_q = cu_seqlens_q[:-1]
364
+ query_layer = query_layer.squeeze(1)
365
+ else:
366
+ # The -q_len: slice assumes left padding.
367
+ attention_mask = attention_mask[:, -query_length:]
368
+ query_layer, indices_q, cu_seqlens_q, max_seqlen_in_batch_q = unpad_input(query_layer, attention_mask)
369
+
370
+ return (
371
+ query_layer,
372
+ key_layer,
373
+ value_layer,
374
+ indices_q,
375
+ (cu_seqlens_q, cu_seqlens_k),
376
+ (max_seqlen_in_batch_q, max_seqlen_in_batch_k),
377
+ )
378
+
379
+
380
+ CORE_ATTENTION_CLASSES = {
381
+ "eager": CoreAttention,
382
+ "sdpa": SdpaAttention,
383
+ "flash_attention_2": FlashAttention2
384
+ }
385
 
386
 
387
  class SelfAttention(torch.nn.Module):
 
413
  device=device, **_config_to_kwargs(config)
414
  )
415
 
416
+ self.core_attention = CORE_ATTENTION_CLASSES[config._attn_implementation](config, self.layer_number)
417
 
418
  # Output.
419
  self.dense = nn.Linear(self.projection_size, config.hidden_size, bias=config.add_bias_linear,
 
492
  value_layer = torch.cat((cache_v, value_layer), dim=2)
493
  if use_cache:
494
  if kv_cache is None:
495
+ kv_cache = torch.cat((key_layer.unsqueeze(0).unsqueeze(0), value_layer.unsqueeze(0).unsqueeze(0)),
496
+ dim=1)
497
  else:
498
  kv_cache = (key_layer, value_layer)
499
  else:
 
759
  config_class = ChatGLMConfig
760
  base_model_prefix = "transformer"
761
  _no_split_modules = ["GLMBlock"]
762
+ _supports_flash_attn_2 = True
763
+ _supports_sdpa = True
764
 
765
  def _init_weights(self, module: nn.Module):
766
  """Initialize the weights."""
767
  return
768
 
769
  def get_masks(self, input_ids, past_key_values, padding_mask=None):
770
+ if self.config._attn_implementation == "flash_attention_2":
771
+ if padding_mask is not None and not padding_mask.all():
772
+ return padding_mask
773
+ return None
774
  batch_size, seq_length = input_ids.shape
775
  full_attention_mask = torch.ones(batch_size, seq_length, seq_length, device=input_ids.device)
776
  full_attention_mask.tril_()
 
845
  config.hidden_size // config.num_attention_heads if config.kv_channels is None else config.kv_channels
846
  )
847
 
848
+ self.rotary_pos_emb = RotaryEmbedding(rotary_dim // 2, rope_ratio=config.rope_ratio,
849
+ original_impl=config.original_rope,
850
  device=device, dtype=config.torch_dtype)
851
  self.encoder = init_method(GLMTransformer, config, **init_kwargs)
852
  self.output_layer = init_method(nn.Linear, config.hidden_size, config.padded_vocab_size, bias=False,
 
867
  past_key_values: Optional[Tuple[Tuple[torch.Tensor, torch.Tensor], ...]] = None,
868
  inputs_embeds: Optional[torch.Tensor] = None,
869
  use_cache: Optional[bool] = None,
870
+ output_attentions: Optional[bool] = None,
871
  output_hidden_states: Optional[bool] = None,
872
  return_dict: Optional[bool] = None,
873
  ):
 
1279
  inputs_embeds: Optional[torch.LongTensor] = None,
1280
  labels: Optional[torch.LongTensor] = None,
1281
  use_cache: Optional[bool] = None,
1282
+ output_attentions: Optional[bool] = None,
1283
  output_hidden_states: Optional[bool] = None,
1284
  return_dict: Optional[bool] = None,
1285
  ) -> Union[Tuple[torch.Tensor, ...], SequenceClassifierOutputWithPast]:
 
1293
  past_key_values=past_key_values,
1294
  inputs_embeds=inputs_embeds,
1295
  use_cache=use_cache,
1296
+ output_attentions=output_attentions,
1297
  output_hidden_states=output_hidden_states,
1298
  return_dict=return_dict,
1299
  )
tokenization_chatglm.py CHANGED
@@ -141,98 +141,98 @@ class ChatGLM4Tokenizer(PreTrainedTokenizer):
141
  else:
142
  return str(f"<|{role}|>{metadata}\n{message}")
143
 
144
- def apply_chat_template(
145
- self,
146
- conversation: Union[List[Dict[str, str]], List[List[Dict[str, str]]], "Conversation"],
147
- add_generation_prompt: bool = False,
148
- tokenize: bool = True,
149
- padding: bool = False,
150
- truncation: bool = False,
151
- max_length: Optional[int] = None,
152
- return_tensors: Optional[Union[str, TensorType]] = None,
153
- return_dict: bool = False,
154
- tokenizer_kwargs: Optional[Dict[str, Any]] = None,
155
- add_special_tokens: bool = True,
156
- **kwargs,
157
- ) -> Union[str, List[int], List[str], List[List[int]], BatchEncoding]:
158
-
159
- if return_dict and not tokenize:
160
- raise ValueError(
161
- "`return_dict=True` is incompatible with `tokenize=False`, because there is no dict "
162
- "of tokenizer outputs to return."
163
- )
164
-
165
- def handle_single_conversation(conversation):
166
- input_ids = self.get_prefix_tokens() if add_special_tokens else []
167
- input_message = "[gMASK]<sop>" if add_special_tokens else ""
168
- for item in conversation:
169
- if item.get("tools"):
170
- tools = item["tools"]
171
- content = "你是一个名为 GLM-4 的人工智能助手。你是基于智谱AI训练的语言模型 GLM-4 模型开发的,你的任务是针对用户的问题和要求提供适当的答复和支持。"
172
- for tool in tools:
173
- if tool["type"] == "function":
174
- function = tool["function"]
175
- content += f"\n\n## {function['name']}\n\n{json.dumps(function, ensure_ascii=False, indent=4)}"
176
- content += "\n在调用上述函数时,请使用 Json 格式表示调用的参数。"
177
- elif tool["type"] == "python":
178
- content += "\n\n## python\n\n当你向 `python` 发送包含 Python 代码的消息时,该代码将会在一个有状态的 Jupyter notebook 环境中执行。\n`python` 返回代码执行的输出,或在执行 60 秒后返回超时。\n`/mnt/data` 将会持久化存储你的文件。在此会话中,`python` 无法访问互联网。不要使用 `python` 进行任何网络请求或者在线 API 调用,这些在线内容的访问将不会成功。"
179
- elif tool["type"] == "simple_browser":
180
- content += "\n\n## simple_browser\n\n你可以使用 `simple_browser` 工具。该工具支持以下函数:\n`search(query: str, recency_days: int)`:使用搜索引擎进行查询并显示结果,可以使用 `recency_days` 参数控制搜索内容的时效性。\n`mclick(ids: list[int])`:获取一系列指定 id 的页面内容。每次调用时,须选择3-10个页面。选择多个角度的页面,同时尽可能选择可信任的信息来源。考虑到部分页面是无法加载的,你也可以多打开一些可能有用的页面而不用担心内容过多。\n`open_url(url: str)`:打开指定的 URL。\n\n使用 `【{引用 id}†{引用文本}】` 来引用内容。\n\n操作步骤:1. 使用 `search` 来获得信息列表; 2. 使用 `mclick` 来获取指定 ID 页面的内容; 3. 根据获得的内容进行回复。在回复中应当引用信息来源。\n 如果用户提供了 URL,也可以用 `open_url` 直接打开页面。\n如果初次搜索结果没有找到合适的信息,也可以再次使用 `search` 进行搜索。"
181
- elif tool["type"] == "cogview":
182
- content += "\n\n## cogview\n\n如果用户的请求中包含了对图像的描述,你可以使用 `cogview` 来生成图像并展示给用户。你需要向 `cogview` 发送图像描述,规则:\n- 发送给 `cogview` 的消息必须使用英语。用户的中文描述必须完全翻译为英语。\n- 应当尽可能详细地描述图像生成的需求,需求描述约 100 英文单词。\n- 保持用户原始描述的意图。不要虚构内容或者没见过的人物。\n- 如无特殊说明,所在地为中国,持有中国立场并遵循中国社会主义价值观。"
183
- else:
184
- raise NotImplementedError(f"Unknown tool type {tool['type']}")
185
- input = self.build_single_message("system", "", content, tokenize=tokenize)
186
- if tokenize:
187
- input_ids.extend(input)
188
- else:
189
- input_message += input
190
- if item["content"]:
191
- input = self.build_single_message(
192
- item["role"],
193
- item.get("metadata", ""),
194
- item["content"],
195
- tokenize=tokenize
196
- )
197
- if tokenize:
198
- input_ids.extend(input)
199
- else:
200
- input_message += input
201
- if add_generation_prompt:
202
- if tokenize:
203
- input_ids.extend([self.convert_tokens_to_ids("<|assistant|>")])
204
- else:
205
- input_message += "<|assistant|>"
206
-
207
- return input_ids if tokenize else input_message
208
-
209
- # Main logic to handle different conversation formats
210
- if isinstance(conversation, list) and all(isinstance(i, dict) for i in conversation):
211
- result = handle_single_conversation(conversation)
212
- elif isinstance(conversation, list) and all(isinstance(i, list) for i in conversation):
213
- result = [handle_single_conversation(c) for c in conversation]
214
- elif hasattr(conversation, "messages"):
215
- result = handle_single_conversation(conversation.messages)
216
- else:
217
- raise ValueError("Invalid conversation format")
218
-
219
- if tokenize:
220
- output = self.batch_encode_plus(
221
- [result] if isinstance(result[0], int) else result,
222
- padding=padding,
223
- truncation=truncation,
224
- max_length=max_length,
225
- return_tensors=return_tensors,
226
- is_split_into_words=True,
227
- add_special_tokens=False
228
- )
229
- if return_dict:
230
- return output
231
- else:
232
- return output["input_ids"]
233
- else:
234
- return result
235
-
236
 
237
  def build_inputs_with_special_tokens(
238
  self, token_ids_0: List[int], token_ids_1: Optional[List[int]] = None
 
141
  else:
142
  return str(f"<|{role}|>{metadata}\n{message}")
143
 
144
+ # Use Jinja Template in tokenizer_config.json
145
+ # def apply_chat_template(
146
+ # self,
147
+ # conversation: Union[List[Dict[str, str]], List[List[Dict[str, str]]], "Conversation"],
148
+ # add_generation_prompt: bool = False,
149
+ # tokenize: bool = True,
150
+ # padding: bool = False,
151
+ # truncation: bool = False,
152
+ # max_length: Optional[int] = None,
153
+ # return_tensors: Optional[Union[str, TensorType]] = None,
154
+ # return_dict: bool = False,
155
+ # tokenizer_kwargs: Optional[Dict[str, Any]] = None,
156
+ # add_special_tokens: bool = True,
157
+ # **kwargs,
158
+ # ) -> Union[str, List[int], List[str], List[List[int]], BatchEncoding]:
159
+ #
160
+ # if return_dict and not tokenize:
161
+ # raise ValueError(
162
+ # "`return_dict=True` is incompatible with `tokenize=False`, because there is no dict "
163
+ # "of tokenizer outputs to return."
164
+ # )
165
+ #
166
+ # def handle_single_conversation(conversation):
167
+ # input_ids = self.get_prefix_tokens() if add_special_tokens else []
168
+ # input_message = "[gMASK]<sop>" if add_special_tokens else ""
169
+ # for item in conversation:
170
+ # if item.get("tools"):
171
+ # tools = item["tools"]
172
+ # content = "你是一个名为 GhatGLM 的人工智能助手。你是基于智谱AI训练的语言模型 GLM-4 模型开发的,你的任务是针对用户的问题和要求提供适当的答复和支持。"
173
+ # content += "\n\n# 可用工具"
174
+ # for tool in tools:
175
+ # if tool["type"] == "function":
176
+ # function = tool["function"]
177
+ # content += f"\n\n## {function['name']}\n\n{json.dumps(function, ensure_ascii=False, indent=4)}"
178
+ # content += "\n在调用上述函数时,请使用 Json 格式表示调用的参数。"
179
+ # elif tool["type"] == "python":
180
+ # content += "\n\n## python\n\n当你向 `python` 发送包含 Python 代码的消息时,该代码将会在一个有状态的 Jupyter notebook 环境中执行。\n`python` 返回代码执行的输出,或在执行 60 秒后返回超时。\n`/mnt/data` 将会持久化存储你的文件。在此会话中,`python` 无法访问互联网。不要使用 `python` 进行任何网络请求或者在线 API 调用,这些在线内容的访问将不会成功。"
181
+ # elif tool["type"] == "simple_browser":
182
+ # content += "\n\n## simple_browser\n\n你可以使用 `simple_browser` 工具。该工具支持以下函数:\n`search(query: str, recency_days: int)`:使用搜索引擎进行查询并显示结果,可以使用 `recency_days` 参数控制搜索内容的时效性。\n`mclick(ids: list[int])`:获取一系列指定 id 的页面内容。每次调用时,须选择3-10个页面。选择多个角度的页面,同时尽可能选择可信任的信息来源。考虑到部分页面是无法加载的,你也可以多打开一些可能有用的页面而不用担心内容过多。\n`open_url(url: str)`:打开指定的 URL。\n\n使用 `【{引用 id}†{引用文本}】` 来引用内容。\n\n操作步骤:1. 使用 `search` 来获得信息列表; 2. 使用 `mclick` 来获取指定 ID 页面的内容; 3. 根据获得的内容进行回复。在回复中���当引用信息来源。\n 如果用户提供了 URL,也可以用 `open_url` 直接打开页面。\n如果初次搜索结果没有找到合适的信息,也可以再次使用 `search` 进行搜索。"
183
+ # elif tool["type"] == "cogview":
184
+ # content += "\n\n## cogview\n\n如果用户的请求中包含了对图像的描述,你可以使用 `cogview` 来生成图像并展示给用户。你需要向 `cogview` 发送图像描述,规则:\n- 发送给 `cogview` 的消息必须使用英语。用户的中文描述必须完全翻译为英语。\n- 应当尽可能详细地描述图像生成的需求,需求描述约 100 英文单词。\n- 保持用户原始描述的意图。不要虚构内容或者没见过的人物。\n- 如无特殊说明,所在地为中国,持有中国立场并遵循中国社会主义价值观。"
185
+ # else:
186
+ # raise NotImplementedError(f"Unknown tool type {tool['type']}")
187
+ # input = self.build_single_message("system", "", content, tokenize=tokenize)
188
+ # if tokenize:
189
+ # input_ids.extend(input)
190
+ # else:
191
+ # input_message += input
192
+ # if item["content"]:
193
+ # input = self.build_single_message(
194
+ # item["role"],
195
+ # item.get("metadata", ""),
196
+ # item["content"],
197
+ # tokenize=tokenize
198
+ # )
199
+ # if tokenize:
200
+ # input_ids.extend(input)
201
+ # else:
202
+ # input_message += input
203
+ # if add_generation_prompt:
204
+ # if tokenize:
205
+ # input_ids.extend([self.convert_tokens_to_ids("<|assistant|>")])
206
+ # else:
207
+ # input_message += "<|assistant|>"
208
+ # return input_ids if tokenize else input_message
209
+ #
210
+ # # Main logic to handle different conversation formats
211
+ # if isinstance(conversation, list) and all(isinstance(i, dict) for i in conversation):
212
+ # result = handle_single_conversation(conversation)
213
+ # elif isinstance(conversation, list) and all(isinstance(i, list) for i in conversation):
214
+ # result = [handle_single_conversation(c) for c in conversation]
215
+ # elif hasattr(conversation, "messages"):
216
+ # result = handle_single_conversation(conversation.messages)
217
+ # else:
218
+ # raise ValueError("Invalid conversation format")
219
+ #
220
+ # if tokenize:
221
+ # output = self.batch_encode_plus(
222
+ # [result] if isinstance(result[0], int) else result,
223
+ # padding=padding,
224
+ # truncation=truncation,
225
+ # max_length=max_length,
226
+ # return_tensors=return_tensors,
227
+ # is_split_into_words=True,
228
+ # add_special_tokens=False
229
+ # )
230
+ # if return_dict:
231
+ # return output
232
+ # else:
233
+ # return output["input_ids"]
234
+ # else:
235
+ # return result
236
 
237
  def build_inputs_with_special_tokens(
238
  self, token_ids_0: List[int], token_ids_1: Optional[List[int]] = None
tokenizer_config.json CHANGED
@@ -123,6 +123,7 @@
123
  "<|user|>", "<|assistant|>", "<|observation|>", "<|begin_of_image|>", "<|end_of_image|>",
124
  "<|begin_of_video|>", "<|end_of_video|>"],
125
  "clean_up_tokenization_spaces": false,
 
126
  "do_lower_case": false,
127
  "eos_token": "<|endoftext|>",
128
  "pad_token": "<|endoftext|>",
 
123
  "<|user|>", "<|assistant|>", "<|observation|>", "<|begin_of_image|>", "<|end_of_image|>",
124
  "<|begin_of_video|>", "<|end_of_video|>"],
125
  "clean_up_tokenization_spaces": false,
126
+ "chat_template": "[gMASK]<sop>{% for item in messages %}{% if item['tools'] is defined %}<|system|>\n你是一个名为 GLM-4 的人工智能助手。你是基于智谱AI训练的语言模型 GLM-4 模型开发的,你的任务是针对用户的问题和要求提供适当的答复和支持。\n\n# 可用工具{% set tools = item['tools'] %}{% for tool in tools %}{% if tool['type'] == 'function' %}\n\n## {{ tool['function']['name'] }}\n\n{{ tool['function'] | tojson(indent=4) }}\n在调用上述函数时,请使用 Json 格式表示调用的参数。{% elif tool['type'] == 'python' %}\n\n## python\n\n当你向 `python` 发送包含 Python 代码的消息时,该代码将会在一个有状态的 Jupyter notebook 环境中执行。\n`python` 返回代码执行的输出,或在执行 60 秒后返回超时。\n`/mnt/data` 将会持久化存储你的文件。在此会话中,`python` 无法访问互联网。不要使用 `python` 进行任何网络请求或者在线 API 调用,这些在线内容的访问将不会成功。{% elif tool['type'] == 'simple_browser' %}\n\n## simple_browser\n\n你可以使用 `simple_browser` 工具。该工具支持以下函数:\n`search(query: str, recency_days: int)`:使用搜索引擎进行查询并显示结果,可以使用 `recency_days` 参数控制搜索内容的时效性。\n`mclick(ids: list[int])`:获取一系列指定 id 的页面内容。每次调用时,须选择3-10个页面。选择多个角度的页面,同时尽可能选择可信任的信息来源。考虑到部分页面是无法加载的,你也可以多打开一些可能有用的页面而不用担心内容过多。\n`open_url(url: str)`:打开指定的 URL。\n\n使用 `【{引用 id}†{引用文本}】` 来引用内容。\n\n操作步骤:1. 使用 `search` 来获得信息列表; 2. 使用 `mclick` 来获取指定 ID 页面的内容; 3. 根据获得的内容进行回复。在回复中应当引用信息来源。\n 如果用户提供了 URL,也可以用 `open_url` 直接打开页面。\n如果初次搜索结果没有找到合适的信息,也可以再次使用 `search` 进行搜索。{% elif tool['type'] == 'cogview' %}\n\n## cogview\n\n如果用户的请求中包含了对图像的描述,你可以使用 `cogview` 来生成图像并展示给用户。你需要向 `cogview` 发送图像描述,规则:\n- 发送给 `cogview` 的消息必须使用英语。用户的中文描述必须完全翻译为英语。\n- 应当尽可能详细地描述图像生成的需求,需求描述约 100 英文单词。\n- 保持用户原始描述的意图。不要虚构内容或者没见过的人物。\n- 如无特殊说明,所在地为中国,持有中国立场并遵循中国社会主义价值观。{% endif %}{% endfor %}{% endif %}{% if item['content'] %}<|{{ item['role'] }}|>{{ item['metadata'] }}\n{{ item['content'] }}{% endif %}{% endfor %}{% if add_generation_prompt %}<|assistant|>{% endif %}",
127
  "do_lower_case": false,
128
  "eos_token": "<|endoftext|>",
129
  "pad_token": "<|endoftext|>",