QwenLM/Qwen
GitHub: QwenLM/Qwen
阿里云通义千问官方大模型仓库,提供从1.8B到72B参数的高性能基座与对话模型,支持长文本、工具调用及高效微调部署。
Stars: 20572 | Forks: 1728
中文  |  English  |  日本語 |  Français |  Español
🤗 Hugging Face   |   🤖 ModelScope   |    📑 论文    |   🖥️ Demo
WeChat (微信)   |   Discord   |   API
| | Qwen-Chat | Qwen-Chat (Int4) | Qwen-Chat (Int8) | Qwen | |-----|:------------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------------------------------------------------------:|:---------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------:| | 1.8B | 🤖 🤗 | 🤖 🤗 | 🤖 🤗 | 🤖 🤗 | | 7B | 🤖 🤗 | 🤖 🤗 | 🤖 🤗 | 🤖 🤗 | | 14B | 🤖 🤗 | 🤖 🤗 | 🤖 🤗 | 🤖 🤗 | | 72B | 🤖 🤗 | 🤖 🤗 | 🤖 🤗 | 🤖 🤗 | 我们开源了 **Qwen** 系列,目前包括 **Qwen**,即基础语言模型,包括 **Qwen-1.8B**、**Qwen-7B**、**Qwen-14B** 和 **Qwen-72B**,以及 **Qwen-Chat**,即聊天模型,包括 **Qwen-1.8B-Chat**、**Qwen-7B-Chat**、**Qwen-14B-Chat** 和 **Qwen-72B-Chat**。链接在上表中。点击它们并查看模型卡片。此外,我们还发布了 **[技术报告](https://arxiv.org/abs/2309.16609)**。请点击论文链接查看! 简而言之,我们拥有强大的基础语言模型,它们在高达 3 万亿 token 的多语言数据上进行了稳定的预训练,覆盖了广泛的领域、语言(以中文和英文为主)等。它们能够在基准数据集上取得具有竞争力的表现。此外,我们还有基于 SFT 和 RLHF(尚未发布)与人类偏好对齐的聊天模型,这些模型能够聊天、创作内容、提取信息、总结、翻译、编写代码、解决数学问题等,并且能够使用工具、扮演智能体,甚至扮演代码解释器等。 | Model | Release Date | Max Length | System Prompt Enhancement | # of Pretrained Tokens | Minimum GPU Memory Usage of Finetuning (Q-Lora) | Minimum GPU Usage of Generating 2048 Tokens (Int4) | Tool Usage | |:----------|:------------:|:----------:|:-------------------------:|:----------------------:|:-----------------------------------------------:|:--------------------------------------------------:|:----------:| | Qwen-1.8B | 23.11.30 | 32K | ✅ | 2.2T | 5.8GB | 2.9GB | ✅ | | Qwen-7B | 23.08.03 | 32K | ❎ | 2.4T | 11.5GB | 8.2GB | ✅ | | Qwen-14B | 23.09.25 | 8K | ❎ | 3.0T | 18.7GB | 13.0GB | ✅ | | Qwen-72B | 23.11.30 | 32K | ✅ | 3.0T | 61.4GB | 48.9GB | ✅ | 在这个 repo 中,你可以了解: * Qwen 的快速入门,并享受简单的推理。 * 关于量化模型的详细信息,包括 GPTQ 和 KV cache 量化。 * 推理性能的统计数据,包括速度和内存。 * 微调教程,包括全参数微调、LoRA 和 Q-LoRA。 * 部署说明,以 vLLM 和 FastChat 为例。 * 构建 demo 的说明,包括 WebUI、CLI demo 等。 * DashScope API 服务介绍,以及为你的模型构建 OpenAI 风格 API 的说明。 * 关于 Qwen 用于工具使用、智能体和代码解释器的信息 * 长文本理解评估的统计数据 * 许可协议 * ... 此外,如果你遇到问题,请先转向 [FAQ](FAQ.md) 寻求帮助。仍然感到困难?随时向我们提交 issues(最好用英文,这样更多人可以理解你)!如果你想帮助我们,请毫不犹豫地发送 pull request!我们总是对 PR 感到兴奋! 想和我们聊天或者约个咖啡时间?欢迎加入我们的 Discord 或 WeChat!
## 新闻与更新 * 2023.11.30 🔥 我们发布了 **Qwen-72B** 和 **Qwen-72B-Chat**,它们在 3T token 上训练并支持 32k 上下文,同时发布的还有 **Qwen-1.8B** 和 **Qwen-1.8B-Chat**,均在 ModelScope 和 Hugging Face 上可用。我们还加强了 Qwen-72B-Chat 和 Qwen-1.8B-Chat 的 System Prompt 能力,见[示例文档](examples/system_prompt.md)。此外,支持在 **Ascend 910** 和 **Hygon DCU** 上进行推理。查看 `ascend-support` 和 `dcu-support` 了解更多详情。 * 2023.10.17 我们发布了 Int8 量化模型 **Qwen-7B-Chat-Int8** 和 **Qwen-14B-Chat-Int8**。 * 2023.9.25 🔥 我们在 ModelScope 和 Hugging Face 上发布了 **Qwen-14B** 和 **Qwen-14B-Chat**,以及 [qwen.cpp](https://github.com/QwenLM/qwen.cpp) 和 [Qwen-Agent](https://github.com/QwenLM/Qwen-Agent)。**Qwen-7B** 和 **Qwen-7B-Chat** 的代码和检查点也已更新。**请拉取最新版本!** - 与 **Qwen-7B**(原版)相比,**Qwen-7B** 使用了更多的训练 token,从 2.2T token 增加到 2.4T token,同时上下文长度从 2048 扩展到 8192。**Qwen-7B** 的中文知识和编程能力得到了进一步提升。 * 2023.9.12 我们现在支持在 Qwen-7B 模型上进行微调,包括全参数微调、LoRA 和 Q-LoRA。 * 2023.8.21 我们发布了 Qwen-7B-Chat 的 Int4 量化模型,**Qwen-7B-Chat-Int4**,它需要较低的内存成本,但实现了更快的推理速度。此外,在基准评估中没有显著的性能下降。 * 2023.8.3 我们在 ModelScope 和 Hugging Face 上同时发布了 **Qwen-7B** 和 **Qwen-7B-Chat**。我们还提供了一份技术备忘录,其中包含有关模型的更多详细信息,包括训练细节和模型性能。
## 性能 Qwen 模型在一系列基准数据集上优于类似模型大小的基线模型,例如 MMLU、C-Eval、GSM8K、MATH、HumanEval、MBPP、BBH 等,这些数据集评估了模型在自然语言理解、数学问题解决、编码等方面的能力。Qwen-72B 在所有任务上都取得了比 LLaMA2-70B 更好的性能,并且在 10 项任务中有 7 项优于 GPT-3.5。
| Model | MMLU | C-Eval | GSM8K | MATH | HumanEval | MBPP | BBH | CMMLU |
|:------------------|:--------:|:--------:|:--------:|:--------:|:---------:|:--------:|:--------:|:--------:|
| | 5-shot | 5-shot | 8-shot | 4-shot | 0-shot | 3-shot | 3-shot | 5-shot |
| LLaMA2-7B | 46.8 | 32.5 | 16.7 | 3.3 | 12.8 | 20.8 | 38.2 | 31.8 |
| LLaMA2-13B | 55.0 | 41.4 | 29.6 | 5.0 | 18.9 | 30.3 | 45.6 | 38.4 |
| LLaMA2-34B | 62.6 | - | 42.2 | 6.2 | 22.6 | 33.0 | 44.1 | - |
| ChatGLM2-6B | 47.9 | 51.7 | 32.4 | 6.5 | - | - | 33.7 | - |
| InternLM-7B | 51.0 | 53.4 | 31.2 | 6.3 | 10.4 | 14.0 | 37.0 | 51.8 |
| InternLM-20B | 62.1 | 58.8 | 52.6 | 7.9 | 25.6 | 35.6 | 52.5 | 59.0 |
| Baichuan2-7B | 54.7 | 56.3 | 24.6 | 5.6 | 18.3 | 24.2 | 41.6 | 57.1 |
| Baichuan2-13B | 59.5 | 59.0 | 52.8 | 10.1 | 17.1 | 30.2 | 49.0 | 62.0 |
| Yi-34B | 76.3 | 81.8 | 67.9 | 15.9 | 26.2 | 38.2 | 66.4 | 82.6 |
| XVERSE-65B | 70.8 | 68.6 | 60.3 | - | 26.3 | - | - | - |
| **Qwen-1.8B** | 45.3 | 56.1 | 32.3 | 2.3 | 15.2 | 14.2 | 22.3 | 52.1 |
| **Qwen-7B** | 58.2 | 63.5 | 51.7 | 11.6 | 29.9 | 31.6 | 45.0 | 62.2 |
| **Qwen-14B** | 66.3 | 72.1 | 61.3 | 24.8 | 32.3 | 40.8 | 53.4 | 71.0 |
| **Qwen-72B** | **77.4** | **83.3** | **78.9** | **35.2** | **35.4** | **52.2** | **67.7** | **83.6** |
对于所有比较模型,我们报告了其官方报告结果与 [OpenCompass](https://opencompass.org.cn/leaderboard-llm) 之间的最佳分数。
有关更多实验结果(更多基准数据集上的详细模型性能)和细节,请点击[此处](https://qianwen-res.oss-cn-beijing.aliyuncs.com/QWEN_TECHNICAL_REPORT.pdf)参考我们的技术报告。
## 要求
* python 3.8 及以上版本
* pytorch 1.12 及以上版本,推荐 2.0 及以上版本
* transformers 4.32 及以上版本
* 推荐 CUDA 11.4 及以上版本(适用于 GPU 用户、flash-attention 用户等)
## 快速入门
下面,我们提供简单的示例来展示如何使用 🤖 ModelScope 和 🤗 Transformers 运行 Qwen-Chat。
你可以使用我们预构建的 docker 镜像来跳过大部分环境设置步骤,有关更多详细信息,请参阅[“使用预构建 Docker 镜像”](#-docker)部分。
如果不使用 docker,请确保你已经设置好环境并安装了必要的包。确保你满足上述要求,然后安装依赖库。
```
pip install -r requirements.txt
```
如果你的设备支持 fp16 或 bf16,我们建议安装 [flash-attention](https://github.com/Dao-AILab/flash-attention)(**我们现在支持 flash attention 2。**)以提高效率并降低内存使用。(**flash-attention 是可选的,不安装它项目也能正常运行**)
```
git clone https://github.com/Dao-AILab/flash-attention
cd flash-attention && pip install .
# 以下是可选的。安装它们可能会很慢。
# pip install csrc/layer_norm
# 如果 flash-attn 的版本高于 2.1.1,则不需要以下步骤。
# pip install csrc/rotary
```
现在你可以开始使用 ModelScope 或 Transformers。
### 🤗 Transformers
要使用 Qwen-Chat 进行推理,你只需要输入几行代码,如下所示。记得传入正确的模型名称或路径,例如 "Qwen/Qwen-7B-Chat" 和 "Qwen/Qwen-14B-Chat"。但是,**请确保你使用的是最新代码。**
```
from transformers import AutoModelForCausalLM, AutoTokenizer
from transformers.generation import GenerationConfig
# 模型名称:"Qwen/Qwen-7B-Chat", "Qwen/Qwen-14B-Chat"
tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen-7B-Chat", trust_remote_code=True)
# 使用 bf16
# model = AutoModelForCausalLM.from_pretrained("Qwen/Qwen-7B-Chat", device_map="auto", trust_remote_code=True, bf16=True).eval()
# 使用 fp16
# model = AutoModelForCausalLM.from_pretrained("Qwen/Qwen-7B-Chat", device_map="auto", trust_remote_code=True, fp16=True).eval()
# 仅使用 CPU
# model = AutoModelForCausalLM.from_pretrained("Qwen/Qwen-7B-Chat", device_map="cpu", trust_remote_code=True).eval()
# 使用 auto 模式,根据设备自动选择精度。
model = AutoModelForCausalLM.from_pretrained(
"Qwen/Qwen-7B-Chat",
device_map="auto",
trust_remote_code=True
).eval()
# 指定生成的超参数。但如果你使用 transformers>=4.32.0,则不需要这样做。
# model.generation_config = GenerationConfig.from_pretrained("Qwen/Qwen-7B-Chat", trust_remote_code=True)
# 第一轮对话
response, history = model.chat(tokenizer, "你好", history=None)
print(response)
# 你好!很高兴为你提供帮助。
# 第二轮对话
response, history = model.chat(tokenizer, "给我讲一个年轻人奋斗创业最终取得成功的故事。", history=history)
print(response)
# 这是一个关于一个年轻人奋斗创业最终取得成功的故事。
# 故事的主人公叫李明,他来自一个普通的家庭,父母都是普通的工人。从小,李明就立下了一个目标:要成为一名成功的企业家。
# 为了实现这个目标,李明勤奋学习,考上了大学。在大学期间,他积极参加各种创业比赛,获得了不少奖项。他还利用课余时间去实习,积累了宝贵的经验。
# 毕业后,李明决定开始自己的创业之路。他开始寻找投资机会,但多次都被拒绝了。然而,他并没有放弃。他继续努力,不断改进自己的创业计划,并寻找新的投资机会。
# 最终,李明成功地获得了一笔投资,开始了自己的创业之路。他成立了一家科技公司,专注于开发新型软件。在他的领导下,公司迅速发展起来,成为了一家成功的科技企业。
# 李明的成功并不是偶然的。他勤奋、坚韧、勇于冒险,不断学习和改进自己。他的成功也证明了,只要努力奋斗,任何人都有可能取得成功。
# 第三轮对话
response, history = model.chat(tokenizer, "给这个故事起一个标题", history=history)
print(response)
# 《奋斗创业:一个年轻人的成功之路》
```
运行 Qwen,即基础语言模型,也很简单。
运行 Qwen
```
from transformers import AutoModelForCausalLM, AutoTokenizer
from transformers.generation import GenerationConfig
# 模型名称:"Qwen/Qwen-7B", "Qwen/Qwen-14B"
tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen-7B", trust_remote_code=True)
# 使用 bf16
# model = AutoModelForCausalLM.from_pretrained("Qwen/Qwen-7B", device_map="auto", trust_remote_code=True, bf16=True).eval()
# 使用 fp16
# model = AutoModelForCausalLM.from_pretrained("Qwen/Qwen-7B", device_map="auto", trust_remote_code=True, fp16=True).eval()
# 仅使用 CPU
# model = AutoModelForCausalLM.from_pretrained("Qwen/Qwen-7B", device_map="cpu", trust_remote_code=True).eval()
# 使用 auto 模式,根据设备自动选择精度。
model = AutoModelForCausalLM.from_pretrained(
"Qwen/Qwen-7B",
device_map="auto",
trust_remote_code=True
).eval()
# 指定生成的超参数。但如果你使用 transformers>=4.32.0,则不需要这样做。
# model.generation_config = GenerationConfig.from_pretrained("Qwen/Qwen-7B", trust_remote_code=True)
inputs = tokenizer('蒙古国的首都是乌兰巴托(Ulaanbaatar)\n冰岛的首都是雷克雅未克(Reykjavik)\n埃塞俄比亚的首都是', return_tensors='pt')
inputs = inputs.to(model.device)
pred = model.generate(**inputs)
print(tokenizer.decode(pred.cpu()[0], skip_special_tokens=True))
# 蒙古国的首都是乌兰巴托(Ulaanbaatar)\n冰岛的首都是雷克雅未克(Reykjavik)\n埃塞俄比亚的首都是亚的斯亚贝巴(Addis Ababa)...
```
如果在尝试从 HuggingFace 下载模型检查点和代码时遇到网络问题,一种替代方法是先从 ModelScope 获取检查点,然后按如下所述从本地目录加载它:
``` from modelscope import snapshot_download from transformers import AutoModelForCausalLM, AutoTokenizer # 下载模型检查点到本地目录 model_dir # model_dir = snapshot_download('qwen/Qwen-7B') # model_dir = snapshot_download('qwen/Qwen-7B-Chat') # model_dir = snapshot_download('qwen/Qwen-14B') model_dir = snapshot_download('qwen/Qwen-14B-Chat') # 加载本地检查点 # trust_remote_code 仍然设置为 True,因为我们仍然从本地目录而不是 transformers 加载代码 tokenizer = AutoTokenizer.from_pretrained(model_dir, trust_remote_code=True) model = AutoModelForCausalLM.from_pretrained( model_dir, device_map="auto", trust_remote_code=True ).eval() ``` ### 🤖 ModelScope ModelScope 是一个开源的模型即服务平台,为 AI 开发者提供灵活且经济高效的模型服务。同样,你可以如下所示使用 ModelScope 运行模型: ``` from modelscope import AutoModelForCausalLM, AutoTokenizer from modelscope import GenerationConfig # 模型名称:"qwen/Qwen-7B-Chat", "qwen/Qwen-14B-Chat" tokenizer = AutoTokenizer.from_pretrained("qwen/Qwen-7B-Chat", trust_remote_code=True) model = AutoModelForCausalLM.from_pretrained("qwen/Qwen-7B-Chat", device_map="auto", trust_remote_code=True, fp16=True).eval() model.generation_config = GenerationConfig.from_pretrained("Qwen/Qwen-7B-Chat", trust_remote_code=True) # 可指定不同的生成长度、top_p等相关超参 response, history = model.chat(tokenizer, "你好", history=None) print(response) response, history = model.chat(tokenizer, "浙江的省会在哪里?", history=history) print(response) response, history = model.chat(tokenizer, "它有什么好玩的景点", history=history) print(response) ``` ### 批量推理 Qwen 支持批量推理。启用 flash attention 后,使用批量推理可以带来 40% 的加速。示例代码如下所示: ``` import torch from transformers import AutoModelForCausalLM, AutoTokenizer from transformers import GenerationConfig from qwen_generation_utils import make_context, decode_tokens, get_stop_words_ids # 为了自动生成 attention masks,必须为 pad_token 和 eos_token 分配不同的 # token_ids,并在 generation_config 中设置 pad_token_id。 tokenizer = AutoTokenizer.from_pretrained( './', pad_token='<|extra_0|>', eos_token='<|endoftext|>', padding_side='left', trust_remote_code=True ) model = AutoModelForCausalLM.from_pretrained( './', pad_token_id=tokenizer.pad_token_id, device_map="auto", trust_remote_code=True ).eval() model.generation_config = GenerationConfig.from_pretrained('./', pad_token_id=tokenizer.pad_token_id) all_raw_text = ["我想听你说爱我。", "今天我想吃点啥,甜甜的,推荐下", "我马上迟到了,怎么做才能不迟到"] batch_raw_text = [] for q in all_raw_text: raw_text, _ = make_context( tokenizer, q, system="You are a helpful assistant.", max_window_size=model.generation_config.max_window_size, chat_format=model.generation_config.chat_format, ) batch_raw_text.append(raw_text) batch_input_ids = tokenizer(batch_raw_text, padding='longest') batch_input_ids = torch.LongTensor(batch_input_ids['input_ids']).to(model.device) batch_out_ids = model.generate( batch_input_ids, return_dict_in_generate=False, generation_config=model.generation_config ) padding_lens = [batch_input_ids[i].eq(tokenizer.pad_token_id).sum().item() for i in range(batch_input_ids.size(0))] batch_response = [ decode_tokens( batch_out_ids[i][padding_lens[i]:], tokenizer, raw_text_len=len(batch_raw_text[i]), context_length=(batch_input_ids[i].size(0)-padding_lens[i]), chat_format="chatml", verbose=False, errors='replace' ) for i in range(len(all_raw_text)) ] print(batch_response) response, _ = model.chat(tokenizer, "我想听你说爱我。", history=None) print(response) response, _ = model.chat(tokenizer, "今天我想吃点啥,甜甜的,推荐下", history=None) print(response) response, _ = model.chat(tokenizer, "我马上迟到了,怎么做才能不迟到", history=None) print(response) ``` ### CPU 要在 CPU 上部署我们的模型,我们强烈建议你使用 [qwen.cpp](https://github.com/QwenLM/qwen.cpp),这是 Qwen 和 tiktoken 的纯 C++ 实现。查看该 repo 了解更多详情! 此外,直接在 CPU 上运行模型也很简单,只需要你指定设备: ``` model = AutoModelForCausalLM.from_pretrained("Qwen/Qwen-7B-Chat", device_map="cpu", trust_remote_code=True).eval() ``` 然而,你可能会遇到极低的推理效率。 ### 多 GPU 如果你遇到 GPU 内存不足的问题,并且希望在多于 1 个 GPU 上运行模型,你可以直接使用默认的加载方法,该方法现在由 Transformers 支持。基于 `utils.py` 的先前方法已被弃用。 然而,虽然这种方法很简单,但原生 pipeline parallelism 的效率较低。我们建议你使用 vLLM 配合 FastChat,请阅读部署部分。 ### x86 平台 在 Core™/Xeon® 可扩展处理器上部署或使用 Arc™ GPU 时,推荐使用 [OpenVINO™ Toolkit](https://docs.openvino.ai/2023.3/gen_ai_guide.html)。你可以安装并运行这个[示例 notebook](https://github.com/openvinotoolkit/openvino_notebooks/tree/main/notebooks/254-llm-chatbot)。对于相关问题,欢迎你在 [OpenVINO repo](https://github.com/openvinotoolkit/openvino_notebooks/issues) 提交 issue。 ### DashScope 通过 API 使用 Qwen 的最简单方法是通过阿里云的 DashScope API 服务。我们对其用法进行了介绍。此外,我们提供了一个脚本供你在自己的服务器上部署 OpenAI 风格的 API。 DashScope 是阿里云提供的大语言模型 API 服务,目前支持 Qwen。请注意,DashScope 背后的模型是内部版本,暂时不提供详细信息。服务包括 `qwen-turbo` 和 `qwen-plus`,前者运行速度更快,后者性能更好。更多信息,请访问[此处](https://dashscope.aliyun.com)的文档。 请前往官网 [链接](https://help.aliyun.com/zh/dashscope/developer-reference/activate-dashscope-and-create-an-api-key?spm=a2c4g.11186623.0.0.6c2774fahtfXdn) 创建 DashScope 账户并获取 API key (AK)。我们建议使用环境变量设置 AK: ``` export DASHSCOPE_API_KEY="YOUR_DASHSCOPE_API_KEY" ``` 然后请安装包并点击[此处](https://help.aliyun.com/zh/dashscope/developer-reference/install-dashscope-sdk)查看文档。如果你使用 Python,可以使用 pip 安装 DashScope: ``` pip install dashscope ``` 如果你使用 JAVA SDK,可以按以下方式安装: ```## 量化 ### GPTQ 我们提供了基于 [AutoGPTQ](https://github.com/PanQiWei/AutoGPTQ) 的解决方案,并发布了 Int4 和 Int8 量化模型,这些模型在模型效果上几乎无损,但在内存成本和推理速度上都有所提升。 这里我们演示如何使用我们提供的量化模型进行推理。在开始之前,请确保你满足 auto-gptq 的要求(例如,torch 2.0 及以上版本,transformers 4.32.0 及以上版本等)并安装必要的包: ``` pip install auto-gptq optimum ``` 如果你在安装 `auto-gptq` 时遇到问题,我们建议你查看官方 [repo](https://github.com/PanQiWei/AutoGPTQ) 以找到 wheel。 然后你可以轻松加载量化模型并像往常一样运行推理: ``` # 模型名称:"Qwen/Qwen-7B-Chat-Int4", "Qwen/Qwen-14B-Chat-Int4" model = AutoModelForCausalLM.from_pretrained( "Qwen/Qwen-7B-Chat-Int4", device_map="auto", trust_remote_code=True ).eval() response, history = model.chat(tokenizer, "Hi", history=None) ``` 我们在基准测试中展示了 BF16、Int8 和 Int4 模型的模型性能,发现量化模型没有出现显著的性能下降。结果如下所示: | Quantization | MMLU | CEval (val) | GSM8K | Humaneval | |----------------------|:----:|:-----------:|:-----:|:---------:| | Qwen-1.8B-Chat (BF16)| 43.3 | 55.6 | 33.7 | 26.2 | | Qwen-1.8B-Chat (Int8)| 43.1 | 55.8 | 33.0 | 27.4 | | Qwen-1.8B-Chat (Int4)| 42.9 | 52.8 | 31.2 | 25.0 | | Qwen-7B-Chat (BF16) | 55.8 | 59.7 | 50.3 | 37.2 | | Qwen-7B-Chat (Int8) | 55.4 | 59.4 | 48.3 | 34.8 | | Qwen-7B-Chat (Int4) | 55.1 | 59.2 | 49.7 | 29.9 | | Qwen-14B-Chat (BF16) | 64.6 | 69.8 | 60.1 | 43.9 | | Qwen-14B-Chat (Int8) | 63.6 | 68.6 | 60.0 | 48.2 | | Qwen-14B-Chat (Int4) | 63.3 | 69.0 | 59.8 | 45.7 | | Qwen-72B-Chat (BF16) | 74.4 | 80.1 | 76.4 | 64.6 | | Qwen-72B-Chat (Int8) | 73.5 | 80.1 | 73.5 | 62.2 | | Qwen-72B-Chat (Int4) | 73.4 | 80.1 | 75.3 | 61.6 | ### KV cache 量化 注意力 KV cache 可以被量化并压缩存储,以获得更高的采样吞吐量。`config.json` 中的参数 `use_cache_quantization` 和 `use_cache_kernel` 用于启用 KV cache 量化。具体使用方法如下: ``` model = AutoModelForCausalLM.from_pretrained( "Qwen/Qwen-7B-Chat", device_map="auto", trust_remote_code=True, use_cache_quantization=True, use_cache_kernel=True, use_flash_attn=False ) ``` 注意:目前,KV cache 量化和 flash attention 不能同时使用。 如果你同时启用 KV cache 量化和 flash attention(`use_flash_attn=True`,`use_cache_quantization=True`,`use_cache_kernel=True`),`use_flash_attn` 默认被禁用(`use_flash_attn=false`)。 我们已经验证,使用量化的 Int8-KV-Cache 模型在下游评估中不会出现显著的性能下降。下面,我们重点关注分析其在不同条件下的内存占用。 分析在单个 A100-SXM4-80G GPU 上运行,使用 PyTorch 2.0.1 和 CUDA 11.4。 我们默认使用 BF16 模型生成 1024 个 token,“OOM”表示内存不足错误。 启用 KV cache 量化后,模型可以使用更大的 batch size (bs) 进行推理。 | USE KV Cache | bs=1 | bs=4 | bs=16 | bs=32 | bs=64 | bs=100 | |--------------|:------:|:------:|:------:|:------:|:------:|:------:| | No | 16.3GB | 24.1GB | 31.7GB | 48.7GB | OOM | OOM | | Yes | 15.5GB | 17.2GB | 22.3GB | 30.2GB | 48.2GB | 72.4GB | 启用 KV cache 量化后,在推理阶段生成更长序列(`sl`,序列长度,生成的 token 数量)时,模型可以节省更多内存。 | USE KV Cache | sl=512 | sl=1024 | sl=2048 | sl=4096 | sl=8192 | |--------------|:------:|:-------:|:-------:|:-------:|:-------:| | No | 15.2GB | 16.3GB | 17.6GB | 19.5GB | 23.2GB | | Yes | 15GB | 15.5GB | 15.8GB | 16.6GB | 17.6GB | 启用 KV cache 量化的模型会将 `layer_past` 的格式从 float 转换为 int8,同时量化的 `layer-past` 也会存储量化参数。 具体步骤如下: 1. 量化 key/value ``` qv,scale,zero_point=quantize_cache_v(v) ``` 2. 存入 layer_past 以下是量化后的 `layer_past` 格式: ``` layer_past=((q_key,key_scale,key_zero_point), (q_value,value_scale,value_zero_point)) ``` 原始的 `layer_past` 格式如下所示: ``` layer_past=(key,value) ``` 如果你想使用量化后的 attention KV,可以使用反量化操作将 Int8 key/value 转换回 float 格式,如下所示: ``` v=dequantize_cache_torch(qv,scale,zero_point) ```
## 推理性能 本节提供了不同精度模型的速度和内存统计数据。速度和内存分析使用[此脚本](https://qianwen-res.oss-cn-beijing.aliyuncs.com/profile.py)进行。 我们测量了 BF16、Int8 和 Int4 模型在生成 2048 个 token 时的平均推理速度和 GPU 内存使用情况。
| 模型大小 | 量化 | 速度 | GPU 显存占用 |
| 1.8B | BF16 | 54.09 | 4.23GB |
| Int8 | 55.56 | 3.48GB | |
| Int4 | 71.07 | 2.91GB | |
| 7B | BF16 | 40.93 | 16.99GB |
| Int8 | 37.47 | 11.20GB | |
| Int4 | 50.09 | 8.21GB | |
| 14B | BF16 | 32.22 | 30.15GB |
| Int8 | 29.28 | 18.81GB | |
| Int4 | 38.72 | 13.01GB | |
| 72B | BF16 | 8.48 | 144.69GB (2xA100) |
| Int8 | 9.05 | 81.27GB (2xA100) | |
| Int4 | 11.32 | 48.86GB | |
| 72B + vLLM | BF16 | 17.60 | 2xA100 |
| 模型大小 | 方法 | #节点 | 每节点 GPU 数 | 序列长度 | |||||
|---|---|---|---|---|---|---|---|---|---|
| 256 | 512 | 1024 | 2048 | 4096 | 8192 | ||||
| 1.8B | LoRA | 1 | 1 | 6.7G / 1.0s/it | 7.4G / 1.0s/it | 8.4G / 1.1s/it | 11.0G / 1.7s/it | 16.2G / 3.3s/it | 21.8G / 6.8s/it |
| LoRA (emb) | 1 | 1 | 13.7G / 1.0s/it | 14.0G / 1.0s/it | 14.0G / 1.1s/it | 15.1G / 1.8s/it | 19.7G / 3.4s/it | 27.7G / 7.0s/it | |
| Q-LoRA | 1 | 1 | 5.8G / 1.4s/it | 6.0G / 1.4s/it | 6.6G / 1.4s/it | 7.8G / 2.0s/it | 10.2G / 3.4s/it | 15.8G / 6.5s/it | |
| Full-parameter | 1 | 1 | 43.5G / 2.1s/it | 43.5G / 2.2s/it | 43.5G / 2.2s/it | 43.5G / 2.3s/it | 47.1G / 2.8s/it | 48.3G / 5.6s/it | |
| 7B | LoRA | 1 | 1 | 20.1G / 1.2s/it | 20.4G / 1.5s/it | 21.5G / 2.8s/it | 23.8G / 5.2s/it | 29.7G / 10.1s/it | 36.6G / 21.3s/it |
| LoRA (emb) | 1 | 1 | 33.7G / 1.4s/it | 34.1G / 1.6s/it | 35.2G / 2.9s/it | 35.1G / 5.3s/it | 39.2G / 10.3s/it | 48.5G / 21.7s/it | |
| Q-LoRA | 1 | 1 | 11.5G / 3.0s/it | 11.5G / 3.0s/it | 12.3G / 3.5s/it | 13.9G / 7.0s/it | 16.9G / 11.6s/it | 23.5G / 22.3s/it | |
| Full-parameter | 1 | 2 | 139.2G / 4.0s/it | 148.0G / 4.0s/it | 162.0G / 4.5s/it | - | - | - | |
| LoRA (multinode) | 2 | 2 | 74.7G / 2.09s/it | 77.6G / 3.16s/it | 84.9G / 5.17s/it | 95.1G / 9.25s/it | 121.1G / 18.1s/it | 155.5G / 37.4s/it | |
| 14B | LoRA | 1 | 1 | 34.6G / 1.6s/it | 35.1G / 2.4s/it | 35.3G / 4.4s/it | 37.4G / 8.4s/it | 42.5G / 17.0s/it | 55.2G / 36.0s/it |
| LoRA (emb) | 1 | 1 | 51.2 / 1.7s/it | 51.1G / 2.6s/it | 51.5G / 4.6s/it | 54.1G / 8.6s/it | 56.8G / 17.2s/it | 67.7G / 36.3s/it | |
| Q-LoRA | 1 | 1 | 18.7G / 5.3s/it | 18.4G / 6.3s/it | 18.9G / 8.2s/it | 19.9G / 11.8s/it | 23.0G / 20.1s/it | 27.9G / 38.3s/it | |
| 72B | LoRA + Deepspeed Zero3 | 1 | 4 | 215.4G / 17.6s/it | 217.7G / 20.5s/it | 222.6G / 29.4s/it | 228.8G / 45.7s/it | 249.0G / 83.4s/it | 289.2G / 161.5s/it |
| Q-LoRA | 1 | 1 | 61.4G / 27.4s/it | 61.4G / 31.5s/it | 62.9G / 41.4s/it | 64.1G / 59.5s/it | 68.0G / 97.7s/it | 75.6G / 179.8s/it | |
## 部署 ### vLLM 对于部署和快速推理,我们建议使用 vLLM。 如果你使用 **CUDA 12.1 和 PyTorch 2.1**,你可以直接使用以下命令安装 vLLM。 ``` pip install vllm ``` 否则,请参考官方 vLLM [安装说明](https://docs.vllm.ai/en/latest/getting_started/installation.html)。 #### vLLM + Transformer-like Wrapper 你可以下载 [wrapper codes](examples/vllm_wrapper.py) 并执行以下命令进行多轮对话交互。(注意:目前仅支持 ``model.chat()`` 方法。) ``` from vllm_wrapper import vLLMWrapper model = vLLMWrapper('Qwen/Qwen-7B-Chat', tensor_parallel_size=1) # model = vLLMWrapper('Qwen/Qwen-7B-Chat-Int4', tensor_parallel_size=1, dtype="float16") response, history = model.chat(query="你好", history=None) print(response) response, history = model.chat(query="给我讲一个年轻人奋斗创业最终取得成功的故事。", history=history) print(response) response, history = model.chat(query="给这个故事起一个标题", history=history) print(response) ``` #### vLLM + Web Demo / OpenAI-like API 你可以使用 FastChat 启动 web demo 或 OpenAI API 服务器。首先,安装 FastChat: ``` pip install "fschat[model_worker,webui]" ``` 要使用 vLLM 和 FastChat 运行 Qwen,你需要通过以下方式启动 controller: ``` python -m fastchat.serve.controller ``` 然后你可以启动 model worker,这意味着加载你的模型进行推理。对于单 GPU 推理,你可以直接运行: ``` python -m fastchat.serve.vllm_worker --model-path $model_path --trust-remote-code --dtype bfloat16 # python -m fastchat.serve.vllm_worker --model-path $model_path --trust-remote-code --dtype float16 # run int4 model ``` 然而,如果你希望在多个 GPU 上运行模型以获得更快的推理速度或更大的内存,你可以使用 vLLM 支持的张量并行。假设你在 4 个 GPU 上运行模型,命令如下所示: ``` python -m fastchat.serve.vllm_worker --model-path $model_path --trust-remote-code --tensor-parallel-size 4 --dtype bfloat16 # python -m fastchat.serve.vllm_worker --model-path $model_path --trust-remote-code --tensor-parallel-size 4 --dtype float16 # run int4 model ``` 启动你的 model worker 后,你可以启动一个: * Web UI Demo ``` python -m fastchat.serve.gradio_web_server ``` * OpenAI API ``` python -m fastchat.serve.openai_api_server --host localhost --port 8000 ``` 然而,如果你发现使用 vLLM 和 FastChat 很困难,你可以尝试我们提供的最简单的方法来部署 web demo、CLI demo 和 API。 ### Web UI 我们提供代码供用户构建 web UI demo(感谢 @wysaid)。在开始之前,请确保你安装了以下包: ``` pip install -r requirements_web_demo.txt ``` 然后运行下面的命令并点击生成的链接: ``` python web_demo.py ```
### CLI Demo 我们在 `cli_demo.py` 中提供了一个 CLI demo 示例,它支持生成的流式输出。用户可以通过输入提示与 Qwen-7B-Chat 交互,模型在流式模式下返回模型输出。运行下面的命令: ``` python cli_demo.py ```
### API
我们提供基于 OpenAI API 部署本地 API 的方法(感谢 @hanpenggit)。在开始之前,安装所需的包:
```
pip install fastapi uvicorn "openai<1.0" pydantic sse_starlette
```
然后运行命令部署你的 API:
```
python openai_api.py
```
你可以你的参数,例如 `-c` 用于检查点名称或路径,`--cpu-only` 用于 CPU 部署等。如果你在启动 API 部署时遇到问题,将包更新到最新版本可能会解决问题。
使用 API 也很简单。见下面的示例:
```
import openai
openai.api_base = "http://localhost:8000/v1"
openai.api_key = "none"
# 创建一个激活流式响应的请求
for chunk in openai.ChatCompletion.create(
model="Qwen",
messages=[
{"role": "user", "content": "你好"}
],
stream=True
# Specifying stop words in streaming output format is not yet supported and is under development.
):
if hasattr(chunk.choices[0].delta, "content"):
print(chunk.choices[0].delta.content, end="", flush=True)
# 创建一个未激活流式响应的请求
response = openai.ChatCompletion.create(
model="Qwen",
messages=[
{"role": "user", "content": "你好"}
],
stream=False,
stop=[] # You can add custom stop words here, e.g., stop=["Observation:"] for ReAct prompting.
)
print(response.choices[0].message.content)
```
也支持 **Function calling**(但目前仅当 `stream=False` 时)。请参阅此处的[示例用法](examples/function_call_examples.py)。
## 🐳 Docker
为了简化部署过程,我们提供了预构建环境的 docker 镜像:[qwenllm/qwen](https://hub.docker.com/r/qwenllm/qwen)。你只需要安装驱动程序并下载模型文件即可启动 demo、部署 OpenAI API 和微调模型。
### 准备工作
1. 根据要使用的镜像安装正确版本的 Nvidia 驱动程序:
- `qwenllm/qwen:cu117` (**推荐**): `>= 515.48.07`
- `qwenllm/qwen:cu114` (w/o flash-attention): `>= 470.82.01`
- `qwenllm/qwen:cu121`: `>= 530.30.02`
- `qwenllm/qwen:latest`: 同 `qwenllm/qwen:cu117`
2. 安装并配置 [docker](https://docs.docker.com/engine/install/) 和 [nvidia-container-toolkit](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html):
```
# 配置 docker
sudo systemctl start docker
# 测试 docker 是否正确安装
sudo docker run hello-world
# 配置 nvidia-container-toolkit
sudo nvidia-ctk runtime configure --runtime=docker
sudo systemctl restart docker
# 测试 nvidia-container-toolkit 是否正确安装
sudo docker run --rm --runtime=nvidia --gpus all ubuntu nvidia-smi
```
3. 将模型检查点和代码下载到你的环境中(见[此处](#DownloadModel))。
### 部署
这里我们以 Qwen-7B-Chat 为例。在启动 web demo 或 API 之前,你可以按如下所示设置配置:
```
IMAGE_NAME=qwenllm/qwen:cu117
PORT=8901
CHECKPOINT_PATH=/path/to/Qwen-7B-Chat # Path to downloaded model checkpoints and codes
```
以下脚本可以帮助你构建:
* OpenAI API
```
bash docker/docker_openai_api.sh -i ${IMAGE_NAME} -c ${CHECKPOINT_PATH} --port ${PORT}
```
* Web UI
```
bash docker/docker_web_demo.sh -i ${IMAGE_NAME} -c ${CHECKPOINT_PATH} --port ${PORT}
```
* CLI Demo
```
bash docker/docker_cli_demo.sh -i ${IMAGE_NAME} -c ${CHECKPOINT_PATH}
```
上面的命令将自动下载所需的镜像并在后台启动 Web UI demo(服务将自动重启)。你可以在主机上打开 `http://localhost:${PORT}` 以使用 demo。
如果你看到以下输出,则说明 demo 已成功启动:
```
Successfully started web demo. Open '...' to try!
Run `docker logs ...` to check demo status.
Run `docker rm -f ...` to stop and remove the demo.
```
如果你想检查 demo 的状态,可以使用 `docker logs qwen` 来显示输出。
你可以使用 `docker rm -f qwen` 来停止服务并移除容器。
### 微调
使用预构建 Docker 镜像进行微调的方法与[上一章](#Finetuning)基本相同(我们已经在镜像中安装了依赖项):
以下是单 GPU LoRA 的示例:
```
IMAGE_NAME=qwenllm/qwen:cu117
CHECKPOINT_PATH=/path/to/Qwen-7B # Path to downloaded model checkpoints and codes
#CHECKPOINT_PATH=/path/to/Qwen-7B-Chat-Int4 # Path to downloaded model checkpoints and codes (Q-LoRA)
DATA_PATH=/path/to/data/root # Prepare finetune data at ${DATA_PATH}/example.json
OUTPUT_PATH=/path/to/output/checkpoint # Path to finetune outputs
# 默认使用所有主机设备
DEVICE=all
# 如果你需要指定 GPU 进行训练,请按如下方式设置 device(注意:内部引号不能省略)
#DEVICE='"device=0,1,2,3"'
mkdir -p ${OUTPUT_PATH}
# 单 GPU LoRA 微调
docker run --gpus ${DEVICE} --rm --name qwen \
--mount type=bind,source=${CHECKPOINT_PATH},target=/data/shared/Qwen/Qwen-7B \
--mount type=bind,source=${DATA_PATH},target=/data/shared/Qwen/data \
--mount type=bind,source=${OUTPUT_PATH},target=/data/shared/Qwen/output_qwen \
--shm-size=2gb \
-it ${IMAGE_NAME} \
bash finetune/finetune_lora_single_gpu.sh -m /data/shared/Qwen/Qwen-7B/ -d /data/shared/Qwen/data/example.json
```
例如,要更改为单 GPU Q-LoRA,你只需要修改 `docker run` 中的 bash 命令:
```
bash finetune/finetune_qlora_single_gpu.sh -m /data/shared/Qwen/Qwen-7B-Chat-Int4/ -d /data/shared/Qwen/data/example.json
```
## 🔥 System Prompt
Qwen-1.8-Chat 和 Qwen-72B-Chat 已经在具有多轮复杂交互的各种 system prompt 上进行了充分训练,因此它们可以遵循各种 system prompt 并实现上下文中的模型定制,进一步提高 Qwen-chat 的可扩展性。
借助 System Prompt,Qwen-Chat 可以实现**角色扮演**、**语言风格迁移**、**任务设置**和**行为设置**。


有关更多信息,请参阅[示例文档](examples/system_prompt.md)。
## 工具使用
Qwen-Chat 已针对工具使用和 function calling 能力进行了优化。用户可以开发智能体、LangChain 应用程序,甚至使用 Python Code Interpreter 增强 Qwen。
我们提供了关于如何基于 ReAct Prompting 原则实现工具调用的文档,请参阅 [ReAct 示例](examples/react_prompt.md)。基于此原则,我们在 [openai_api.py](openai_api.py) 中提供了对 function calling 的支持。
我们已经在我们开源的中文评估基准上测试了模型的工具调用能力,发现 Qwen-Chat 始终表现良好:
| 中文工具使用基准 (版本 20231206) | |||
|---|---|---|---|
| 模型 | 工具选择 (Acc.↑) | 工具输入 (Rouge-L↑) | 误报率↓ |
| GPT-4 | 98.0% | 0.953 | 23.9% |
| GPT-3.5 | 74.5% | 0.807 | 80.6% |
| Qwen-1_8B-Chat | 85.0% | 0.839 | 27.6% |
| Qwen-7B-Chat | 95.5% | 0.900 | 11.6% |
| Qwen-14B-Chat | 96.9% | 0.917 | 5.6% |
| Qwen-72B-Chat | 98.2% | 0.927 | 1.1% |
| Code Interpreter 基准 (版本 20231206) | ||||
|---|---|---|---|---|
| 模型 | 代码执行结果准确率 (%) | 代码可执行率 (%) | ||
| 数学↑ | 可视化-困难↑ | 可视化-简单↑ | 通用↑ | |
| GPT-4 | 82.8 | 66.7 | 60.8 | 82.8 |
| GPT-3.5 | 47.3 | 33.3 | 55.7 | 74.1 |
| LLaMA2-13B-Chat | 8.3 | 1.2 | 15.2 | 48.3 |
| CodeLLaMA-13B-Instruct | 28.2 | 15.5 | 21.5 | 74.1 |
| InternLM-20B-Chat | 34.6 | 10.7 | 25.1 | 65.5 |
| ChatGLM3-6B | 54.2 | 4.8 | 15.2 | 67.1 |
| Qwen-1.8B-Chat | 25.6 | 21.4 | 22.8 | 65.5 |
| Qwen-7B-Chat | 41.9 | 23.8 | 38.0 | 67.2 |
| Qwen-14B-Chat | 58.4 | 31.0 | 45.6 | 65.5 |
| Qwen-72B-Chat | 72.7 | 41.7 | 43.0 | 82.8 |
## 长文本理解
为了扩展上下文长度并突破训练序列长度的瓶颈,我们引入了多种技术,包括 NTK-aware interpolation、window attention 和 LogN attention scaling,将 Qwen-14B 的上下文长度从 2K 扩展到 8K token 以上,并将 Qwen-1.8B/7B 从 8K 扩展到 32K token。
对于 Qwen-72B,我们使用更大的旋转基数将 RoPE 适配到更长的上下文。Qwen-72B 支持最大 32K token 的上下文长度。
我们在 arXiv 数据集上使用 PPL 评估进行了语言建模实验,发现 Qwen 在长上下文场景中可以达到出色的性能。结果如下所示:
| 模型 | 序列长度 | |||||
|---|---|---|---|---|---|---|
| 1024 | 2048 | 4096 | 8192 | 16384 | 32768 | |
| Qwen-7B (原版) | 4.23 | 3.78 | 39.35 | 469.81 | 2645.09 | - |
| + dynamic_ntk | 4.23 | 3.78 | 3.59 | 3.66 | 5.71 | - |
| + dynamic_ntk + logn | 4.23 | 3.78 | 3.58 | 3.56 | 4.62 | - |
| + dynamic_ntk + logn + window_attn | 4.23 | 3.78 | 3.58 | 3.49 | 4.32 | - |
| Qwen-1.8B | 5.00 | 4.48 | 4.13 | 3.89 | 17.42 | 433.85 |
| + dynamic_ntk + logn + window_attn | 5.00 | 4.48 | 4.14 | 3.93 | 3.82 | 3.83 |
| Qwen-7B | 4.23 | 3.81 | 3.52 | 3.31 | 7.27 | 181.49 |
| + dynamic_ntk + logn + window_attn | 4.23 | 3.81 | 3.52 | 3.33 | 3.22 | 3.17 |
| Qwen-14B | - | 3.46 | 22.79 | 334.65 | 3168.35 | - |
| + dynamic_ntk + logn + window_attn | - | 3.46 | 3.29 | 3.18 | 3.42 | - |
| Qwen-72B | - | - | - | 2.83 | 2.73 | 2.72 |
## 复现 为了让你在基准数据集上复现模型性能,我们提供了脚本供你复现结果。查看 [eval/EVALUATION.md](eval/EVALUATION.md) 了解更多信息。请注意,复现可能与我们要报告的结果略有不同。
## FAQ 如果你遇到问题,请在启动新 issue 之前先参考 [FAQ](FAQ.md) 和 issue 以搜索解决方案。
## 引用 如果你觉得我们的工作有帮助,请随意引用我们。 ``` @article{qwen, title={Qwen Technical Report}, author={Jinze Bai and Shuai Bai and Yunfei Chu and Zeyu Cui and Kai Dang and Xiaodong Deng and Yang Fan and Wenbin Ge and Yu Han and Fei Huang and Binyuan Hui and Luo Ji and Mei Li and Junyang Lin and Runji Lin and Dayiheng Liu and Gao Liu and Chengqiang Lu and Keming Lu and Jianxin Ma and Rui Men and Xingzhang Ren and Xuancheng Ren and Chuanqi Tan and Sinan Tan and Jianhong Tu and Peng Wang and Shijie Wang and Wei Wang and Shengguang Wu and Benfeng Xu and Jin Xu and An Yang and Hao Yang and Jian Yang and Shusheng Yang and Yang Yao and Bowen Yu and Hongyi Yuan and Zheng Yuan and Jianwei Zhang and Xingxuan Zhang and Yichang Zhang and Zhenru Zhang and Chang Zhou and Jingren Zhou and Xiaohuan Zhou and Tianhang Zhu}, journal={arXiv preprint arXiv:2309.16609}, year={2023} } ```
## 许可协议 在