Commit 9d64d96c authored by zhangwq5's avatar zhangwq5
Browse files

online

parent b9a3367a
...@@ -54,12 +54,13 @@ pip install transformers==4.51.1 ...@@ -54,12 +54,13 @@ pip install transformers==4.51.1
## 训练 ## 训练
暂无 暂无
## 推理 ## 推理
### vllm推理Qwen3-30B-A3B
### vllm离线推理Qwen3-30B-A3B
```bash ```bash
## Qwen3-30B-A3B 在 BF16 精度下,其模型权重本身大约是 61 GB,至少需要双卡部署推理 ## Qwen3-30B-A3B 在 BF16 精度下,其模型权重本身大约是 61 GB,至少需要双卡部署推理
export HIP_VISIBLE_DEVICES=6,7 export HIP_VISIBLE_DEVICES=6,7
## 模型地址参数 ## 模型地址参数
python ./infer/infer_vllm.py --model /your_path/Qwen3-30B-A3B --tensor-parallel-size 2 python ./infer/offline/infer_vllm.py --model /your_path/Qwen3-30B-A3B --tensor-parallel-size 2
``` ```
## result ## result
...@@ -94,19 +95,21 @@ Logprobs per generated token: ...@@ -94,19 +95,21 @@ Logprobs per generated token:
### 精度 ### 精度
``` ```
# 分别在DCU和GPU上运行infer_vllm.py,得到各自的精度数据,并将精度数据复制粘贴到acc.py中运行 # 分别在DCU和GPU上运行infer_vllm.py,得到各自的精度数据,并将精度数据复制粘贴到acc.py中运行
python ./infer/acc.py python ./infer/offline/acc.py
``` ```
结果 结果
``` ```
Qwen3-30B-A3B精度:0.002905419914469576 Qwen3-30B-A3B在DCU(K100_AI)与GPU(A800)离线推理的平均绝对误差值:0.002905419914469576
``` ```
DCU(K100_AI)与GPU(A800)离线推理Qwen3-30B-A3B精度一致,推理框架:vllm
### vllm推理Qwen3-30B-A3B-Instruct-2507 ### vllm离线推理Qwen3-30B-A3B-Instruct-2507
```bash ```bash
## Qwen3-30B-A3B-Instruct-2507 至少需要双卡部署推理 ## Qwen3-30B-A3B-Instruct-2507 至少需要双卡部署推理
export HIP_VISIBLE_DEVICES=6,7 export HIP_VISIBLE_DEVICES=6,7
## 模型地址参数 ## 模型地址参数
python ./infer/infer_vllm.py --model /your_path/Qwen3-30B-A3B-Instruct-2507 --tensor-parallel-size 2 python ./infer/offline/infer_vllm.py --model /your_path/Qwen3-30B-A3B-Instruct-2507 --tensor-parallel-size 2
``` ```
## result ## result
...@@ -141,16 +144,76 @@ Logprobs per generated token: ...@@ -141,16 +144,76 @@ Logprobs per generated token:
### 精度 ### 精度
``` ```
# 分别在DCU和GPU上运行infer_vllm.py,得到各自的精度数据,并将精度数据复制粘贴到acc.py中运行 # 分别在DCU和GPU上运行infer_vllm.py,得到各自的精度数据,并将精度数据复制粘贴到acc.py中运行
python ./infer/acc.py python ./infer/offline/acc.py
``` ```
结果 结果
``` ```
Qwen3-30B-A3B-Instruct-2507精度:0.006542379854522551 Qwen3-30B-A3B-Instruct-2507在DCU(K100_AI)与GPU(A800)离线推理的平均绝对误差值:0.006542379854522551
```
DCU(K100_AI)与GPU(A800)离线推理Qwen3-30B-A3B-Instruct-2507精度一致,推理框架:vllm
### vllm在线推理Qwen3-30B-A3B
```bash
## Qwen3-30B-A3B 至少需要双卡部署
export HIP_VISIBLE_DEVICES=6,7
## 启动服务
vllm serve /your_path/Qwen3-30B-A3B --enable-reasoning --reasoning-parser deepseek_r1 --tensor-parallel-size 2 --max-logprobs 10
## 修改./infer/online/client.py, MODEL_NAME请改成/your_path/Qwen3-30B-A3B,并运行client.py, 代码内部共设置十个提示词
python client.py
``` ```
## result
```
欢迎使用 Qwen3-30B-A3B 聊天客户端!
已连接到 vLLM 服务,使用模型: /home/zwq/model/Qwen3-30B-A3B
--------------------------------------------------
--- 问题 1: '介绍一下北京.' ---
完整回答 (包含思考): '\n\n北京是中国的首都,也是世界著名古都和国际化大都市,拥有深厚的历史文化底蕴与现代化的城市风貌。以下从多个角度为您简要介绍:\n\n---\n\n### **1. 历史与文化**\n- **古都底蕴**:北京已有3000多年建城史,曾是元、明、清三朝的都城,是中华文明的重要发源地之一。故宫、天坛、颐和园、长城等世界文化遗产,见证了中国古代建筑与文化的辉煌。\n- **胡同与四合院**:老北京的典型民居形式,如南锣鼓巷、烟袋斜街等胡同区,保留了传统市井文化。\n- **文化地标**:国家博物馆、中国美术馆、首都博物馆等机构汇聚了丰富的文物与艺术资源。\n\n---\n\n### **2. 政治与经济中心**\n- **政治核心**:中南海(中共中央和国务院所在地)、人民大会堂(全国人大和政协会议场所)等是国家政治决策的核心区域。\n- **经济枢纽**:作为中国四大直辖市之一,北京是科技创新、金融、教育和文化中心,拥有中关村科技园区、金融街等重要经济区域。\n\n---\n\n### **3. 现代都市风貌**\n- **地标建筑**:央视大楼、国贸三期、北京大兴国际机场等现代化建筑展现了城市活力。\n- **交通网络**:地铁系统发达(中国最长的地铁线路之一),拥有首都国际机场和大兴国际机场,是全国航空枢纽。\n- **绿色空间**:奥林匹克公园、景山公园、北海公园等为城市增添生态气息。\n\n---\n\n### **4. 美食与生活**\n- **特色美食**:北京烤鸭(全聚德)、炸酱面、豆汁儿、卤煮火烧等传统小吃,以及各种京味儿餐馆。\n- **市井文化**:王府井、西单等商圈汇聚购物与餐饮,而胡同里的老茶馆、相声表演则体现市井生活。\n\n---\n\n### **5. 旅游与四季风光**\n- **经典景点**:故宫(紫禁城)、长城(八达岭/慕田峪)、颐和园、天坛、圆明园等。\n- **四季特色**:\n - **春**:玉渊潭樱花、植物园桃花。\n - **夏**:北海荷花、香山红叶(秋)。\n - **秋**:香山红叶、京郊红叶谷。\n - **冬**:北海冰场、滑雪场。\n\n---\n\n### **6. 教育与科技**\n- **高校云集**:清华大学、北京大学、中国人民大学等顶尖学府,是中国高等教育的高地。\n- **科技创新**:中关村是中国科技创新的“硅谷”,聚集了大量互联网、人工智能企业。\n\n---\n\n### **7. 体育与国际活动**\n- **奥运之城**:2008年夏季奥运会和2022年冬季奥运会的举办地,拥有鸟巢、水立方等标志性场馆。\n- **国际赛事**:承办过亚运会、世界田径锦标赛等大型国际赛事。\n\n---\n\n北京是一座将历史与现代、传统与创新完美融合的城市,既有厚重的文化积淀,又充满活力与未来感。无论是探索古迹、感受文化,还是体验现代都市生活,北京都能带来独特的魅力。'
【主要回答】: '\n\n北京是中国的首都,也是世界著名古都和国际化大都市,拥有深厚的历史文化底蕴与现代化的城市风貌。以下从多个角度为您简要介绍:\n\n---\n\n### **1. 历史与文化**\n- **古都底蕴**:北京已有3000多年建城史,曾是元、明、清三朝的都城,是中华文明的重要发源地之一。故宫、天坛、颐和园、长城等世界文化遗产,见证了中国古代建筑与文化的辉煌。\n- **胡同与四合院**:老北京的典型民居形式,如南锣鼓巷、烟袋斜街等胡同区,保留了传统市井文化。\n- **文化地标**:国家博物馆、中国美术馆、首都博物馆等机构汇聚了丰富的文物与艺术资源。\n\n---\n\n### **2. 政治与经济中心**\n- **政治核心**:中南海(中共中央和国务院所在地)、人民大会堂(全国人大和政协会议场所)等是国家政治决策的核心区域。\n- **经济枢纽**:作为中国四大直辖市之一,北京是科技创新、金融、教育和文化中心,拥有中关村科技园区、金融街等重要经济区域。\n\n---\n\n### **3. 现代都市风貌**\n- **地标建筑**:央视大楼、国贸三期、北京大兴国际机场等现代化建筑展现了城市活力。\n- **交通网络**:地铁系统发达(中国最长的地铁线路之一),拥有首都国际机场和大兴国际机场,是全国航空枢纽。\n- **绿色空间**:奥林匹克公园、景山公园、北海公园等为城市增添生态气息。\n\n---\n\n### **4. 美食与生活**\n- **特色美食**:北京烤鸭(全聚德)、炸酱面、豆汁儿、卤煮火烧等传统小吃,以及各种京味儿餐馆。\n- **市井文化**:王府井、西单等商圈汇聚购物与餐饮,而胡同里的老茶馆、相声表演则体现市井生活。\n\n---\n\n### **5. 旅游与四季风光**\n- **经典景点**:故宫(紫禁城)、长城(八达岭/慕田峪)、颐和园、天坛、圆明园等。\n- **四季特色**:\n - **春**:玉渊潭樱花、植物园桃花。\n - **夏**:北海荷花、香山红叶(秋)。\n - **秋**:香山红叶、京郊红叶谷。\n - **冬**:北海冰场、滑雪场。\n\n---\n\n### **6. 教育与科技**\n- **高校云集**:清华大学、北京大学、中国人民大学等顶尖学府,是中国高等教育的高地。\n- **科技创新**:中关村是中国科技创新的“硅谷”,聚集了大量互联网、人工智能企业。\n\n---\n\n### **7. 体育与国际活动**\n- **奥运之城**:2008年夏季奥运会和2022年冬季奥运会的举办地,拥有鸟巢、水立方等标志性场馆。\n- **国际赛事**:承办过亚运会、世界田径锦标赛等大型国际赛事。\n\n---\n\n北京是一座将历史与现代、传统与创新完美融合的城市,既有厚重的文化积淀,又充满活力与未来感。无论是探索古迹、感受文化,还是体验现代都市生活,北京都能带来独特的魅力。'
答案部分前10个Token的Rank 1 Logprobs:
Step 0: 0.0000
Step 1: -0.0000
Step 2: -0.0711
Step 3: -0.0000
Step 4: -0.1086
Step 5: -0.0150
Step 6: -0.0067
Step 7: -0.0000
Step 8: -0.0298
Step 9: -0.0091
--------------------------------------------------
......
......
所有测试结果已保存到文件: ./Qwen3-30B-A3B_logprobs_K100AI_fp16.json
```
### 精度
```bash
## 分别在DCU和GPU上启动vllm服务,并对应运行client.py,得到各自的精度数据后,运行online文件夹下的acc.py
python ./infer/online/acc.py --file1 /your_path/Qwen3-30B-A3B_logprobs_A800_fp16.json --file2 /your_path/Qwen3-30B-A3B_logprobs_K100AI_fp16.json
```
结果
```
提示词:介绍一下北京.,平均绝对误差:0.002455742455325094
提示词:写一首关于春天的五言绝句.,平均绝对误差:0.0007630783482369452
提示词:请解释一下黑洞的形成原理.,平均绝对误差:0.005167613880542632
提示词:推荐三部值得一看的科幻电影,并简述理由.,平均绝对误差:0.0030238355811320616
提示词:如何有效提高编程能力?,平均绝对误差:0.014263489465471934
提示词:给我讲一个关于人工智能的笑话.,平均绝对误差:0.003418742059113811
提示词:你认为未来教育会发展成什么样?,平均绝对误差:0.0246062334959511
提示词:如何制作一道美味的麻婆豆腐?,平均绝对误差:0.005538759729023468
提示词:量子计算的原理是什么?它有哪些潜在应用?,平均绝对误差:0.012481686085721578
提示词:请用英语介绍一下中国长城.,平均绝对误差:0.001114922351905534
总体平均绝对误差:7.283410e-03
```
DCU(K100_AI)与GPU(A800)在线推理Qwen3-30B-A3B精度一致,推理框架:vllm
DCU与GPU精度一致,推理框架:vllm。
## 应用场景 ## 应用场景
### 算法类别 ### 算法类别
`对话` `对话`
...@@ -161,6 +224,7 @@ DCU与GPU精度一致,推理框架:vllm。 ...@@ -161,6 +224,7 @@ DCU与GPU精度一致,推理框架:vllm。
- [Qwen/Qwen3-30B-A3B-Instruct-2507](https://huggingface.co/Qwen/Qwen3-30B-A3B-Instruct-2507) - [Qwen/Qwen3-30B-A3B-Instruct-2507](https://huggingface.co/Qwen/Qwen3-30B-A3B-Instruct-2507)
## 源码仓库及问题反馈 ## 源码仓库及问题反馈
- https://developer.sourcefind.cn/codes/modelzoo/granite-speech_pytorch - https://developer.sourcefind.cn/codes/modelzoo/qwen3-30b-a3b_vllm
## 参考资料 ## 参考资料
- https://github.com/ibm-granite/granite-speech-models - https://huggingface.co/Qwen/Qwen3-30B-A3B
\ No newline at end of file - https://huggingface.co/Qwen/Qwen3-30B-A3B-Instruct-2507
...@@ -113,7 +113,6 @@ def main(args: dict): ...@@ -113,7 +113,6 @@ def main(args: dict):
first_10_logprobs_to_save.append(logprob_value) first_10_logprobs_to_save.append(logprob_value)
output_filename = './Qwen3-30B-A3B_logprobs_K100AI_fp16.json' output_filename = './Qwen3-30B-A3B_logprobs_K100AI_fp16.json'
with open(output_filename, 'w') as f: with open(output_filename, 'w') as f:
json.dump(first_10_logprobs_to_save, f, indent=2) json.dump(first_10_logprobs_to_save, f, indent=2)
......
This diff is collapsed.
This diff is collapsed.
import json
import numpy as np
import argparse
def load_json_file(file_path):
"""读取 JSON 文件并返回内容"""
try:
with open(file_path, 'r', encoding='utf-8') as f:
return json.load(f)
except FileNotFoundError:
print(f"错误:文件 {file_path} 不存在")
exit(1)
except json.JSONDecodeError:
print(f"错误:文件 {file_path} 不是有效的 JSON 格式")
exit(1)
def calculate_mae(file1_path, file2_path):
"""计算两个 JSON 文件中 logprobs 的平均绝对误差"""
data1 = load_json_file(file1_path)
data2 = load_json_file(file2_path)
if len(data1) != len(data2):
print("错误:两个 JSON 文件的字典数量不同")
exit(1)
mae_per_token = np.zeros(10)
num_entries = len(data1)
overall_error = 0
for i in range(num_entries):
prompt = data1[i]["input"]
logprobs1 = data1[i]["logprobs_of_rank1_for_the_first_10_tokens"]
logprobs2 = data2[i]["logprobs_of_rank1_for_the_first_10_tokens"]
if len(logprobs1) != 10 or len(logprobs2) != 10:
print(f"错误:第 {i+1} 个字典的 logprobs 数组长度不为 10")
exit(1)
current_mae = np.mean(np.abs(np.array(logprobs1) - np.array(logprobs2)))
print(f"提示词:{prompt},平均绝对误差:{current_mae}")
overall_error +=current_mae
overall_mae = overall_error/num_entries
print(f"\n总体平均绝对误差:{overall_mae:.6e}")
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="计算两个 JSON 文件中 logprobs 的平均绝对误差")
parser.add_argument("--file1", help="第一个 JSON 文件的路径")
parser.add_argument("--file2", help="第二个 JSON 文件的路径")
args = parser.parse_args()
# 调用计算函数
calculate_mae(args.file1, args.file2)
\ No newline at end of file
import requests
import json
import re
API_BASE_URL = "http://localhost:8000/v1"
# MODEL_NAME = "/home/zwq/model/Qwen3-30B-A3B"
MODEL_NAME = "/home/zwq/model/Qwen3-30B-A3B-Instruct-2507"
class Qwen3ChatClient:
def __init__(self, api_base_url=API_BASE_URL, model_name=MODEL_NAME):
self.api_base_url = api_base_url
self.model_name = model_name
self.history = []
def _parse_response(self, text):
"""
解析模型响应,分离思考内容和最终内容。
"""
thinking_content = ""
main_content = text
# re.DOTALL 确保 '.' 匹配包括换行符在内的所有字符
# 这个正则表达式尝试捕获 <think> 和 </think> 之间的内容,以及其后的所有内容
match = re.search(r'<think>(.*?)</think>(.*)', text, re.DOTALL)
if match:
thinking_content = match.group(1).strip()
main_content = match.group(2).strip()
# 如果没有 <think> 标签,则 thinking_content 保持为空,main_content 为原始文本
return thinking_content, main_content
def generate_response(self, user_input, enable_thinking=True, conversation_history=None):
"""
向Qwen3模型发送请求并获取响应。
:param user_input: 用户输入的消息。
:param enable_thinking: 是否启用思考模式。True为思考模式(默认),False为非思考模式。
:param conversation_history: 可选的对话历史列表,格式为 [{"role": "...", "content": "..."}]
:return: (full_assistant_content, list_of_rank1_logprobs)
full_assistant_content 是模型的完整原始回答,包含思考内容
"""
if conversation_history is None:
conversation_history = [{"role": "system", "content": "You are a helpful assistant."}]
# 将用户输入添加到当前会话历史
current_messages = conversation_history + [{"role": "user", "content": user_input}]
headers = {
"Content-Type": "application/json"
}
# 采样参数,固定用于确定性或近似确定性测试
temperature, top_p, top_k = 0.0, 1.0, 1
payload = {
"model": self.model_name,
"messages": current_messages,
"temperature": temperature,
"top_p": top_p,
"top_k": top_k,
"max_tokens": 8192,
"stream": False,
"logprobs": True,
"extra_body": {
"enable_reasoning": enable_thinking
}
}
try:
response = requests.post(f"{self.api_base_url}/chat/completions", headers=headers, json=payload)
response.raise_for_status() # 检查HTTP错误
response_data = response.json()
if not response_data.get("choices"):
print("错误: 响应中未找到 choices。")
return "", []
full_assistant_content = response_data["choices"][0]["message"]["content"]
# --- 提取 Logprobs ---
list_of_rank1_logprobs = []
logprobs_data = response_data["choices"][0].get("logprobs", {}).get("content", [])
for token_logprob_info in logprobs_data:
# 在vLLM的OpenAI API兼容响应中,顶层"logprob"字段就是Rank 1的Logprob
list_of_rank1_logprobs.append(token_logprob_info.get("logprob"))
return full_assistant_content, list_of_rank1_logprobs
except requests.exceptions.HTTPError as e:
print(f"HTTP请求失败: {e}")
print(f"响应内容: {e.response.text}")
return "", []
except requests.exceptions.RequestException as e:
print(f"请求失败: {e}")
return "", []
except json.JSONDecodeError as e:
print(f"JSON解析失败: {e} - 响应文本: {response.text[:200]}...")
return "", []
except Exception as e:
print(f"发生未知错误: {e}")
return "", []
# --- 示例用法 (已修改) ---
if __name__ == "__main__":
chatbot = Qwen3ChatClient()
print("欢迎使用 Qwen3-30B-A3B 聊天客户端!")
print(f"已连接到 vLLM 服务,使用模型: {MODEL_NAME}")
print("--------------------------------------------------")
# 硬编码的 10 个随机问题
test_questions = [
"介绍一下北京.",
"写一首关于春天的五言绝句.",
"请解释一下黑洞的形成原理.",
"推荐三部值得一看的科幻电影,并简述理由.",
"如何有效提高编程能力?",
"给我讲一个关于人工智能的笑话.",
"你认为未来教育会发展成什么样?",
"如何制作一道美味的麻婆豆腐?",
"量子计算的原理是什么?它有哪些潜在应用?",
"请用英语介绍一下中国长城.",
]
results_to_save = []
for i, question in enumerate(test_questions):
print(f"\n--- 问题 {i+1}: {question!r} ---")
full_content, rank1_logprobs = chatbot.generate_response(question, enable_thinking=True)
thinking_part, main_answer = chatbot._parse_response(full_content)
print(f"完整回答 (包含思考): {full_content!r}")
if thinking_part:
print(f"【思考过程】: {thinking_part!r}")
print(f"【主要回答】: {main_answer!r}")
thinking_end_tag = '</think>'
logprobs_after_thinking = []
if thinking_end_tag in full_content and rank1_logprobs:
end_char_idx = full_content.find(thinking_end_tag) + len(thinking_end_tag)
current_decoded_length = 0
for j, logprob_val in enumerate(rank1_logprobs):
raw_logprobs_data = response_data["choices"][0].get("logprobs", {}).get("content", [])
if j < len(raw_logprobs_data):
token_text_from_api = raw_logprobs_data[j].get("token", "")
current_decoded_length += len(token_text_from_api)
if current_decoded_length > end_char_idx:
logprobs_after_thinking = rank1_logprobs[j:]
break
if not logprobs_after_thinking and thinking_end_tag in full_content:
print("Warning: Could not accurately find logprobs after </think> tag. Using all logprobs.")
logprobs_after_thinking = rank1_logprobs
elif not thinking_end_tag in full_content:
logprobs_after_thinking = rank1_logprobs
else:
logprobs_after_thinking = rank1_logprobs
print("\n答案部分前10个Token的Rank 1 Logprobs:")
for k, logprob_val in enumerate(logprobs_after_thinking[:10]):
print(f" Step {k}: {logprob_val:.4f}")
results_to_save.append({
"input": question,
"output": main_answer,
"logprobs_of_rank1_for_the_first_10_tokens": logprobs_after_thinking[:10]
})
print("--------------------------------------------------")
output_filename_client_all_results = './Qwen3-30B-A3B-Instruct-2507_logprobs_K100AI_fp16.json'
with open(output_filename_client_all_results, 'w', encoding='utf-8') as f:
json.dump(results_to_save, f, indent=4, ensure_ascii=False)
print(f"\n所有测试结果已保存到文件: {output_filename_client_all_results}")
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment