Update README.md
Browse files
README.md
CHANGED
@@ -1,12 +1,12 @@
|
|
1 |
<div align="center">
|
2 |
<h1>
|
3 |
-
|
4 |
</h1>
|
5 |
</div>
|
6 |
|
7 |
|
8 |
<p align="center">
|
9 |
-
|
10 |
</p>
|
11 |
|
12 |
# 目录
|
@@ -19,60 +19,44 @@
|
|
19 |
|
20 |
# 模型介绍
|
21 |
|
22 |
-
**
|
23 |
|
24 |
### 训练策略
|
25 |
-
|
26 |
|
27 |
-
-
|
28 |
-
|
29 |
-
|
30 |
-
#### 基础模型训练
|
31 |
-
|
32 |
-
- TeleChat2.5 采用了多阶段课程学习策略,在训练过程中逐步提升理科和编程类高密度知识数据的比例。每个训练阶段都使用比前一阶段质量更高、难度更大的数据,以实现持续的模型优化。
|
33 |
-
|
34 |
-
- 在最终训练阶段,为了平衡模型在各个维度的能力表现,我们选取了不同训练阶段效果较优的多个模型,并基于各模型的综合表现进行参数加权融合,其中权重分配与模型性能呈正相关。
|
35 |
-
|
36 |
-
#### 后训练阶段
|
37 |
-
我们采用分阶段优化的模型训练策略:
|
38 |
-
|
39 |
-
- 融合优化阶段:整合复杂推理与通用问答能力,针对语言理解、数理逻辑等薄弱任务进行解构重组。通过重构任务框架并融合多维度解题思路,生成优化后的通用答案集。此阶段答案长度会适度增加,并基于优化数据实施微调训练。
|
40 |
-
|
41 |
-
- 能力强化阶段:针对数理逻辑与编程类任务,通过注入结构化解题思路,结合基于规则的强化学习奖励机制,显著提升模型对复杂任务的理解与处理能力。
|
42 |
-
|
43 |
-
- 泛化提升阶段:面向安全合规、指令响应、函数调用、数学推理、代码生成等十余种任务类型进行系统性强化学习增强,全面提升模型的通用任务处理能力。
|
44 |
|
45 |
### 模型下载
|
46 |
-
| 模型版本
|
47 |
-
|
48 |
-
|
|
49 |
-
|
|
50 |
|
51 |
# 效果评测
|
52 |
-
| 模型
|
53 |
-
|
54 |
-
|
|
55 |
-
|
|
56 |
-
|
|
57 |
-
|
|
58 |
-
|
|
59 |
-
|
|
60 |
-
| TeleChat2.5-35B | 85 | 7.73 | 78.28 |
|
61 |
-
| TeleChat2.5-115B | 87 | 7.93 | 83.39 |
|
62 |
|
63 |
|
64 |
# 模型推理
|
65 |
|
66 |
-
|
|
|
67 |
|
68 |
|
69 |
```python
|
70 |
import torch
|
71 |
from transformers import AutoModelForCausalLM, AutoTokenizer, GenerationConfig
|
72 |
|
73 |
-
tokenizer = AutoTokenizer.from_pretrained("
|
74 |
model = AutoModelForCausalLM.from_pretrained(
|
75 |
-
"
|
76 |
trust_remote_code=True,
|
77 |
torch_dtype=torch.bfloat16,
|
78 |
device_map="auto"
|
@@ -80,8 +64,8 @@ model = AutoModelForCausalLM.from_pretrained(
|
|
80 |
prompt = "生抽和酱油的区别是什么?"
|
81 |
messages = [{"role": "user", "content": prompt}]
|
82 |
text = tokenizer.apply_chat_template(messages,
|
83 |
-
|
84 |
-
|
85 |
)
|
86 |
model_inputs = tokenizer([text], return_tensors="pt").to(model.device)
|
87 |
generated_ids = model.generate(
|
@@ -93,15 +77,91 @@ generated_ids = [
|
|
93 |
response = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]
|
94 |
print(response)
|
95 |
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
96 |
|
97 |
#### ModelScope
|
98 |
-
|
99 |
```python
|
100 |
import os
|
101 |
import torch
|
102 |
from modelscope import AutoModelForCausalLM, AutoTokenizer, GenerationConfig
|
103 |
-
tokenizer = AutoTokenizer.from_pretrained('
|
104 |
-
model = AutoModelForCausalLM.from_pretrained('
|
105 |
torch_dtype=torch.bfloat16)
|
106 |
prompt = "生抽与老抽的区别?"
|
107 |
messages = [{"role": "user", "content": prompt}]
|
@@ -117,18 +177,17 @@ response = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]
|
|
117 |
print(response)
|
118 |
```
|
119 |
|
120 |
-
|
121 |
### vLLM 推理
|
122 |
|
123 |
-
|
124 |
##### 离线推理
|
125 |
```python
|
126 |
from transformers import AutoTokenizer
|
127 |
from vllm import LLM, SamplingParams
|
128 |
|
129 |
-
tokenizer = AutoTokenizer.from_pretrained("
|
130 |
-
sampling_params = SamplingParams(temperature=0.
|
131 |
-
llm = LLM(model="
|
132 |
|
133 |
prompt = "生抽和酱油的区别是什么?"
|
134 |
messages = [{"role": "user", "content": prompt}]
|
@@ -148,12 +207,13 @@ for output in outputs:
|
|
148 |
##### OpenAI 兼容的 API 服务
|
149 |
您可以借助 vLLM,构建一个与 OpenAI API 兼容的 API 服务。请按照以下所示运行命令:
|
150 |
```
|
151 |
-
vllm serve
|
152 |
--trust-remote-code \
|
153 |
--dtype bfloat16 \
|
154 |
--disable-custom-all-reduce
|
155 |
```
|
156 |
-
|
|
|
157 |
```python
|
158 |
from openai import OpenAI
|
159 |
openai_api_key = "EMPTY"
|
@@ -161,14 +221,14 @@ openai_api_base = "http://localhost:8000/v1"
|
|
161 |
|
162 |
client = OpenAI(api_key=openai_api_key, base_url=openai_api_base)
|
163 |
chat_response = client.chat.completions.create(
|
164 |
-
model="
|
165 |
messages=[
|
166 |
{"role": "user", "content": "生抽和酱油的区别是什么?"},
|
167 |
],
|
168 |
-
temperature=0.
|
169 |
max_tokens=8192,
|
170 |
extra_body={
|
171 |
-
"repetition_penalty": 1.
|
172 |
"skip_special_tokens": False,
|
173 |
"spaces_between_special_tokens": False,
|
174 |
},
|
@@ -176,23 +236,36 @@ chat_response = client.chat.completions.create(
|
|
176 |
print("Chat response:", chat_response)
|
177 |
```
|
178 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
179 |
# 国产化适配
|
180 |
|
181 |
-
|
182 |
-
1. <a href="https://modelers.cn/models/MindSpore-Lab/
|
183 |
-
2. <a href="https://modelers.cn/models/MindSpore-Lab/
|
|
|
184 |
|
185 |
# 声明、引用
|
186 |
|
187 |
### 声明
|
188 |
|
189 |
-
我们在此声明,不要使用
|
190 |
|
191 |
-
我们已经尽我们所能,来确保模型训练过程中使用的数据的合规性。然而,尽管我们已经做出了巨大的努力,但由于模型和数据的复杂性,仍有可能存在一些无法预见的问题。因此,如果由于使用
|
192 |
|
193 |
### 引用
|
194 |
|
195 |
-
如需引用我们的工作,请使用如下 reference
|
196 |
|
197 |
```
|
198 |
@misc{wang2024telechat,
|
|
|
1 |
<div align="center">
|
2 |
<h1>
|
3 |
+
T1
|
4 |
</h1>
|
5 |
</div>
|
6 |
|
7 |
|
8 |
<p align="center">
|
9 |
+
🦉 <a href="https://github.com/Tele-AI/T1" target="_blank">github</a> • 🤗 <a href="https://huggingface.co/Tele-AI" target="_blank">Hugging Face</a> • 🤖 <a href="https://modelscope.cn/organization/TeleAI" target="_blank">ModelScope</a> • 🐾 <a href="https://gitee.com/Tele-AI/T1" target="_blank">gitee</a> • 💬 <a href="https://github.com/Tele-AI/Telechat/blob/master/images/wechat.jpg" target="_blank">WeChat</a>
|
10 |
</p>
|
11 |
|
12 |
# 目录
|
|
|
19 |
|
20 |
# 模型介绍
|
21 |
|
22 |
+
**T1** 模型是 **TeleChat** 系列专注于复杂推理的模型,由中国电信人工智能研究院基于国产算力研发训练。该系列模型借助先进的思维推理和批判纠错能力,在下游复杂任务中有很好的表现。本次我们开源了 **T1-35B** 和 **T1-115B** 两款不同尺寸的模型,与同尺寸模型相比都具有较好的效果表现。
|
23 |
|
24 |
### 训练策略
|
25 |
+
采用课程学习贯穿全流程的后训练方案,循序渐进提升模型效果。
|
26 |
|
27 |
+
- 微调阶段:将多任务数据集进行难度划分(根据模型推理正误比率判断),首先使用中低难度冷启动微调,然后使用RFT方式筛选中高难度数据进行持续微调进行效果提升;
|
28 |
+
- 强化学习阶段:首先对数理逻辑、代码能力进行提升,采用难度渐进式课程学习方案进行能力强化;然后,基于指令遵循、安全、幻觉、Function Call等10多种混合通用任务进行持续强化,全面提升模型效果;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
29 |
|
30 |
### 模型下载
|
31 |
+
| 模型版本 | 下载链接 |
|
32 |
+
|---------|-----------------------------------------------------------|
|
33 |
+
| T1-35B | [modelscope](https://modelscope.cn/models/TeleAI/T1-35B) |
|
34 |
+
| T1-115B | [modelscope](https://modelscope.cn/models/TeleAI/T1-115B) |
|
35 |
|
36 |
# 效果评测
|
37 |
+
| 模型 | MATH-500 | AlignBench | BFCL(avg v1&v2) |
|
38 |
+
|------------------------------|----------|------------|-----------------|
|
39 |
+
| OpenAI o1-mini | 90 | 7.91 | - |
|
40 |
+
| DeepSeek-R1-Distill-Qwen-32B | 94.3 | 7.42 | 76.14 |
|
41 |
+
| QWQ-32B | 96 | 7.97 | 83.1 |
|
42 |
+
| Qwen3-32B(长推理) | 93 | 8.27 | 86.82 |
|
43 |
+
| **T1-35B** | 90 | 7.93 | 80.11 |
|
44 |
+
| **T1-115B** | 94 | 8.22 | 83.39 |
|
|
|
|
|
45 |
|
46 |
|
47 |
# 模型推理
|
48 |
|
49 |
+
### Transformers
|
50 |
+
T1 系列模型支持使用 `transformers` 库进行推理,示例如下:
|
51 |
|
52 |
|
53 |
```python
|
54 |
import torch
|
55 |
from transformers import AutoModelForCausalLM, AutoTokenizer, GenerationConfig
|
56 |
|
57 |
+
tokenizer = AutoTokenizer.from_pretrained("T1/T1-35B", trust_remote_code=True)
|
58 |
model = AutoModelForCausalLM.from_pretrained(
|
59 |
+
"T1/T1-35B",
|
60 |
trust_remote_code=True,
|
61 |
torch_dtype=torch.bfloat16,
|
62 |
device_map="auto"
|
|
|
64 |
prompt = "生抽和酱油的区别是什么?"
|
65 |
messages = [{"role": "user", "content": prompt}]
|
66 |
text = tokenizer.apply_chat_template(messages,
|
67 |
+
tokenize=False,
|
68 |
+
add_generation_prompt=True
|
69 |
)
|
70 |
model_inputs = tokenizer([text], return_tensors="pt").to(model.device)
|
71 |
generated_ids = model.generate(
|
|
|
77 |
response = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]
|
78 |
print(response)
|
79 |
```
|
80 |
+
<details>
|
81 |
+
<summary>推理结果</summary>
|
82 |
+
|
83 |
+
```markdown
|
84 |
+
|
85 |
+
嗯,用户问生抽和酱油的区别,这看起来是一个关于调味品的问题。首先,我需要确定用户的基本需求。可能他们在做饭时不确定该用哪种,或者想了解它们的用途。接下来,我得回忆一下生抽和酱油的定义和特点。
|
86 |
+
|
87 |
+
生抽通常是指以大豆和面粉为原料,经过发酵制成的液体调味品,颜色较浅,味道偏咸鲜。而酱油一般指的是老抽,颜色深,味道更浓郁,常用于上色。不过,可能用户对“酱油”的理解有偏差,因为有些地方可能把酱油泛指所有酱油类调味品,包括生抽和老抽。
|
88 |
+
|
89 |
+
然后,我需要考虑用户的背景。可能是家庭烹饪者,尤其是新手,对调料不太熟悉。他们可能想知道在炒菜或凉拌时该用哪种,或者如何正确使用以达到最佳效果。此外,用户可能没有明确区分生抽、老抽和其他类型的酱油,比如味极鲜、蒸鱼豉油等。
|
90 |
+
|
91 |
+
接下来,要分析用户可能的深层需求。除了基本的区别,他们可能还关心使用场景、健康因素(比如盐分含量)或者如何替代使用。例如,生抽适合凉拌和炒菜,而老抽适合红烧和卤味。如果用户有健康顾虑,可能需要提到低盐产品。
|
92 |
+
|
93 |
+
还要考虑常见的误区。比如,有些人可能认为酱油就是生抽,或者混淆了生抽和老抽的功能。需要明确指出两者的不同用途,避免用户在烹饪时出错。
|
94 |
+
|
95 |
+
另外,用户可能对“酱油”这个词的广义理解有误,认为所有酱油都是同一种东西。这时候需要解释清楚,酱油是一个大类,包含多种类型,而生抽是其中的一种,主要用于提鲜,老抽用于上色。
|
96 |
+
|
97 |
+
最后,总结回答时要结构清晰,分点说明区别,包括原料、颜色、味道、用途和健康提示。确保语言通俗易懂,避免专业术语过多,让用户容易理解。同时,提醒用户根据烹饪需求选择合适的调料,可能还需要举例说明常见菜品中使用的情况,帮助用户更好地应用知识。
|
98 |
+
</think>
|
99 |
+
|
100 |
+
生抽和酱油都是常用的调味品,但它们在原料、制作工艺、风味和用法上有明显区别。以下是详细的区分:
|
101 |
+
|
102 |
+
---
|
103 |
+
|
104 |
+
### **1. 原料与工艺**
|
105 |
+
- **生抽**
|
106 |
+
- **原料**:以大豆(黄豆或黑豆)、小麦粉为主,辅以盐、水、曲种(米曲霉)。
|
107 |
+
- **工艺**:通过发酵(固态或液态)制成,颜色较浅,呈红褐色或琥珀色,味道偏咸鲜,含较多氨基酸。
|
108 |
+
|
109 |
+
- **酱油**(传统广式老酱油或老抽)
|
110 |
+
- **原料**:同样以大豆、小麦为基础,但可能添加焦糖色、糖类或其他增色成分。
|
111 |
+
- **��艺**:发酵后需长时间晾晒或烘烤,颜色更深(深褐色),咸味较重,鲜味略逊于生抽。
|
112 |
+
|
113 |
+
---
|
114 |
+
|
115 |
+
### **2. 风味差异**
|
116 |
+
- **生抽**:鲜味突出,咸中带甜,适合直接调味。
|
117 |
+
- **酱油**:咸味浓郁,部分产品带有焦糖香气,常用于上色或提味。
|
118 |
+
|
119 |
+
---
|
120 |
+
|
121 |
+
### **3. 用途区别**
|
122 |
+
- **生抽**:
|
123 |
+
- 凉拌菜(如拌黄瓜、海带)增鲜提味。
|
124 |
+
- 炒菜(如小炒肉、青菜)代替盐,保持食材原味。
|
125 |
+
- 蘸料(如白切鸡、刺身)提鲜。
|
126 |
+
|
127 |
+
- **酱油**:
|
128 |
+
- 红烧、炖煮(如红烧肉、卤味)上色和增香。
|
129 |
+
- 腌制或蘸食(如蘸饺子、拌面)增加咸香。
|
130 |
+
|
131 |
+
---
|
132 |
+
|
133 |
+
### **4. 健康注意事项**
|
134 |
+
- **盐分**:两者含盐量较高,生抽钠含量约为15%(每百毫升),酱油约18%,需注意控制用量。
|
135 |
+
- **添加剂**:部分生抽含谷氨酸钠(味精),增加鲜味;酱油可能添加焦糖色素或防腐剂,选择时可参考配料表。
|
136 |
+
|
137 |
+
---
|
138 |
+
|
139 |
+
### **常见误区澄清**
|
140 |
+
- **“酱油=老抽”**:传统广式酱油(如豉油)与老抽(北方称法)类似,但部分地区将“酱油”泛指点缀所有酱油类(包括生抽、老抽、味极鲜等)。购买时需看清包装标注。
|
141 |
+
- **替代使用**:生抽不可完全替代酱油,因上色能力不足;老抽咸味过重,不宜直接用于凉拌。
|
142 |
+
|
143 |
+
---
|
144 |
+
|
145 |
+
### **总结**
|
146 |
+
| **对比项** | **生抽** | **酱油(老抽)** |
|
147 |
+
|--------------|-------------------------|--------------------------|
|
148 |
+
| **颜色** | 淡红褐色 | 深褐色 |
|
149 |
+
| **鲜味** | 突出 | 较弱 |
|
150 |
+
| **咸味** | 中等 | 较浓 |
|
151 |
+
| **主要用途** | 凉拌、炒菜、蘸料 | 上色、炖煮、腌制 |
|
152 |
+
|
153 |
+
根据烹饪需求选择:追求鲜味用生抽,需要上色或浓郁咸香用酱油。
|
154 |
+
```
|
155 |
+
</details>
|
156 |
|
157 |
#### ModelScope
|
158 |
+
T1 系列模型支持使用 ModelScope 推理,示例如下:
|
159 |
```python
|
160 |
import os
|
161 |
import torch
|
162 |
from modelscope import AutoModelForCausalLM, AutoTokenizer, GenerationConfig
|
163 |
+
tokenizer = AutoTokenizer.from_pretrained('T1/T1-35BB', trust_remote_code=True)
|
164 |
+
model = AutoModelForCausalLM.from_pretrained('T1/T1-35B', trust_remote_code=True, device_map="auto",
|
165 |
torch_dtype=torch.bfloat16)
|
166 |
prompt = "生抽与老抽的区别?"
|
167 |
messages = [{"role": "user", "content": prompt}]
|
|
|
177 |
print(response)
|
178 |
```
|
179 |
|
|
|
180 |
### vLLM 推理
|
181 |
|
182 |
+
T1 支持使用 [vLLM](https://github.com/vllm-project/vllm) 进行部署与推理加速,示例如下:
|
183 |
##### 离线推理
|
184 |
```python
|
185 |
from transformers import AutoTokenizer
|
186 |
from vllm import LLM, SamplingParams
|
187 |
|
188 |
+
tokenizer = AutoTokenizer.from_pretrained("T1/T1-35B", trust_remote_code=True)
|
189 |
+
sampling_params = SamplingParams(temperature=0.6, repetition_penalty=1.05, max_tokens=8192)
|
190 |
+
llm = LLM(model="T1/T1-35B", trust_remote_code=True, tensor_parallel_size=4, dtype="bfloat16")
|
191 |
|
192 |
prompt = "生抽和酱油的区别是什么?"
|
193 |
messages = [{"role": "user", "content": prompt}]
|
|
|
207 |
##### OpenAI 兼容的 API 服务
|
208 |
您可以借助 vLLM,构建一个与 OpenAI API 兼容的 API 服务。请按照以下所示运行命令:
|
209 |
```
|
210 |
+
vllm serve T1/T1-35B \
|
211 |
--trust-remote-code \
|
212 |
--dtype bfloat16 \
|
213 |
--disable-custom-all-reduce
|
214 |
```
|
215 |
+
|
216 |
+
然后,您可以与 T1 进行对话:
|
217 |
```python
|
218 |
from openai import OpenAI
|
219 |
openai_api_key = "EMPTY"
|
|
|
221 |
|
222 |
client = OpenAI(api_key=openai_api_key, base_url=openai_api_base)
|
223 |
chat_response = client.chat.completions.create(
|
224 |
+
model="T1/T1-35B",
|
225 |
messages=[
|
226 |
{"role": "user", "content": "生抽和酱油的区别是什么?"},
|
227 |
],
|
228 |
+
temperature=0.6,
|
229 |
max_tokens=8192,
|
230 |
extra_body={
|
231 |
+
"repetition_penalty": 1.05,
|
232 |
"skip_special_tokens": False,
|
233 |
"spaces_between_special_tokens": False,
|
234 |
},
|
|
|
236 |
print("Chat response:", chat_response)
|
237 |
```
|
238 |
|
239 |
+
|
240 |
+
#### 推理注意事项
|
241 |
+
|
242 |
+
1. T1 系列模型在 chat template 中加入了一些适配复杂推理模型的特性:
|
243 |
+
- T1 系列模型在 chat template 中加入了`<think>\n`符号以确保推理时能够生成 reason 过程。如果借助 `transformers` 库推理,并采用`apply_chat_template`方法,且 `add_generation_prompt` 设为`True`,则将会在推理时自动拼接`<think>\n`符号;如果使用 vLLM 库推理,也会自动在推理起始拼接`<think>\n`符号。此时输出结果会缺少开头的`<think>\n`符号。
|
244 |
+
- T1 系列模型在进行多轮推理时不应传入之前轮次回答中的`<think>..</think>`过程,在chat template 中已经实现了对多轮历史信息的自动处理。
|
245 |
+
|
246 |
+
2. T1 系列模型推理参数选择
|
247 |
+
- 在推理数学、代码任务时,建议使用`repetition_penalty=1.0, temperature=0.6, top_p=0.95`的推理设置。
|
248 |
+
- 在推理通用任务时,建议使用`repetition_penalty=1.05, temperature=0.6, top_p=0.95`的推理设置,可以有效减少重复生成现象。
|
249 |
+
|
250 |
+
|
251 |
# 国产化适配
|
252 |
|
253 |
+
T1系列模型均进行了**国产化算力适配**,具体信息可见
|
254 |
+
1. <a href="https://modelers.cn/models/MindSpore-Lab/T1-35B" target="_blank">MindSpore-Lab/T1-35B</a>
|
255 |
+
2. <a href="https://modelers.cn/models/MindSpore-Lab/T1-115B" target="_blank">MindSpore-Lab/T1-115B</a>
|
256 |
+
|
257 |
|
258 |
# 声明、引用
|
259 |
|
260 |
### 声明
|
261 |
|
262 |
+
我们在此声明,不要使用 T1 系列模型及其衍生模型进行任何危害国家社会安全或违法的活动。同时,我们也要求使用者不要将 T1 系列模型用于没有安全审查和备案的互联网服务。我们希望所有使用者遵守上述原则,确保科技发展在合法合规的环境下进行。
|
263 |
|
264 |
+
我们已经尽我们所能,来确保模型训练过程中使用的数据的合规性。然而,尽管我们已经做出了巨大的努力,但由于模型和数据的复杂性,仍有可能存在一些无法预见的问题。因此,如果由于使用 T1 系列开源模型而导致的任何问题,包括但不限于数据安全问题、公共舆论风险,或模型被误导、滥用、传播或不当利用所带来的任何风险和问题,我们将不承担任何责任。
|
265 |
|
266 |
### 引用
|
267 |
|
268 |
+
如需引用我们的工作,请使用如下 reference:
|
269 |
|
270 |
```
|
271 |
@misc{wang2024telechat,
|