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,可以按以下方式安装: ``` com.alibaba dashscope-sdk-java the-latest-version ``` 使用 DashScope 最简单的方法是使用 messages,类似于 OpenAI API。示例如下: ``` import random from http import HTTPStatus from dashscope import Generation def call_with_messages(): messages = [{'role': 'system', 'content': 'You are a helpful assistant.'}, {'role': 'user', 'content': '如何做西红柿鸡蛋?'}] gen = Generation() response = gen.call( Generation.Models.qwen_turbo, messages=messages, seed=random.randint(1, 10000), # set the random seed, optional, default to 1234 if not set result_format='message', # set the result to be "message" format. ) return response if __name__ == '__main__': response = call_with_messages() if response.status_code == HTTPStatus.OK: print(response) else: print('Request id: %s, Status code: %s, error code: %s, error message: %s' % ( response.request_id, response.status_code, response.code, response.message )) ``` 更多用法,请访问官网了解更多详情。

## 量化 ### 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
分析在单个 A100-SXM4-80G GPU(除非提到 2xA100)上进行,使用 PyTorch 2.0.1、CUDA 11.8 和 Flash-Attention 2。(72B + vLLM 使用 PyTorch 2.1.0 和 Cuda 11.8。)推理速度是对编码和生成的 token 取平均值。 注意:上述提到的 Int4/Int8 模型的生成速度由 autogptq 库提供。当前使用 ``AutoModelForCausalLM.from_pretrained`` 加载的模型速度大约慢 20%。我们已将此问题报告给 HuggingFace 团队,如果有解决方案,我们会及时更新。 我们还测量了不同上下文和生成长度设置、Flash-Attention 版本下的推理速度和 GPU 内存使用情况。你可以在 Hugging Face 或 ModelScope 的相应模型卡片中找到结果。 ## 微调 ### 使用方法 现在我们提供官方训练脚本 `finetune.py`,供用户以简单的方式为下游应用微调预训练模型。此外,我们提供 shell 脚本让你无忧地启动微调。该脚本支持使用 [DeepSpeed](https://github.com/microsoft/DeepSpeed) 和 [FSDP](https://engineering.fb.com/2021/07/15/open-source/fsdp/) 进行训练。我们提供的 shell 脚本使用 DeepSpeed(注意:这可能与最新版本的 pydantic 冲突,你应该确保 `pydantic<2.0`)和 Peft。你可以通过以下方式安装它们: ``` pip install "peft<0.8.0" deepspeed ``` 要准备你的训练数据,你需要将所有样本放入一个列表并将其保存到 json 文件中。每个样本是一个字典,由一个 id 和一个对话列表组成。下面是一个包含 1 个样本的简单示例列表: ``` [ { "id": "identity_0", "conversations": [ { "from": "user", "value": "你好" }, { "from": "assistant", "value": "我是一个语言模型,我叫通义千问。" } ] } ] ``` 数据准备好后,你可以使用提供的 shell 脚本运行微调。记得指定数据文件的路径 `$DATA`。 微调脚本允许你执行: - 全参数微调 - LoRA - Q-LoRA 全参数微调需要在整个训练过程中更新所有参数。要启动你的训练,运行以下脚本: ``` # 分布式训练。我们不提供单 GPU 训练脚本,因为 GPU 显存不足会导致训练崩溃。 bash finetune/finetune_ds.sh ``` 记得在 shell 脚本中指定正确的模型名称或路径、数据路径以及输出目录。另一件需要注意的是,我们在此脚本中使用 DeepSpeed ZeRO 3。如果你想进行更改,只需删除参数 `--deepspeed` 或根据你的要求在 DeepSpeed 配置 json 文件中进行更改。此外,此脚本支持混合精度训练,因此你可以使用 `--bf16 True` 或 `--fp16 True`。当你使用 fp16 进行混合精度训练时,记得使用 DeepSpeed。根据经验,如果你的机器支持 bf16,我们建议你使用 bf16 以使你的训练与我们的预训练和对齐保持一致,因此我们默认使用它。 类似地,要运行 LoRA,使用另一个脚本如下所示。在开始之前,请确保你已安装 `peft`。此外,你需要指定模型、数据和输出的路径。我们建议你为预训练模型使用绝对路径。这是因为 LoRA 仅保存适配器,并且适配器配置 json 文件中的绝对路径用于查找要加载的预训练模型。此外,此脚本同时支持 bf16 和 fp16。 ``` # 单 GPU 训练 bash finetune/finetune_lora_single_gpu.sh # 分布式训练 bash finetune/finetune_lora_ds.sh ``` 与全参数微调相比,LoRA([论文](https://arxiv.org/abs/2106.09685))仅更新适配器层的参数,但保持原始大语言模型层冻结。这大大减少了内存成本,从而减少了计算成本。 请注意,如果你使用 LoRA 微调基础语言模型(例如 Qwen-7B),而不是聊天模型(例如 Qwen-7B-Chat),脚本会自动将 embedding 层和 output 层切换为可训练参数。这是因为基础语言模型不了解 ChatML 格式带来的特殊 token。因此,这些层需要更新,以便模型理解和预测这些 token。换句话说,如果你的训练在 LoRA 中引入了特殊 token,你应该通过在代码中设置 `modules_to_save` 来将这些层设置为可训练参数。此外,如果我们有这些参数可训练,则不能使用 ZeRO 3,这就是我们在脚本中默认使用 ZeRO 2 的原因。如果你没有新的可训练参数,可以通过更改 DeepSpeed 配置文件切换到 ZeRO 3。此外,我们发现 LoRA 在有无这些可训练参数时的内存占用存在显著差距。因此,如果你在内存方面遇到困难,我们建议你 LoRA 微调聊天模型。查看下面的分析以获取更多信息。 如果你仍然受困于内存不足,可以考虑 Q-LoRA([论文](https://arxiv.org/abs/2305.14314)),它使用量化的大语言模型和分页注意力等技术来允许更少的内存成本。 注意:要运行单 GPU Q-LoRA 训练,你可能需要通过 `pip` 或 `conda` 安装 `mpi4py`。 要运行 Q-LoRA,直接运行以下脚本: ``` # 单 GPU 训练 bash finetune/finetune_qlora_single_gpu.sh # 分布式训练 bash finetune/finetune_qlora_ds.sh ``` 对于 Q-LoRA,我们建议你加载我们提供的量化模型,例如 Qwen-7B-Chat-Int4。你**不应**使用 bf16 模型。与全参数微调和 LoRA 不同,Q-LoRA 仅支持 fp16。对于单 GPU 训练,由于我们观察到 torch amp 导致的错误,我们必须使用 DeepSpeed 进行混合精度训练。此外,对于 Q-LoRA,LoRA 中特殊 token 的问题仍然存在。但是,由于我们仅为聊天模型提供 Int4 模型,这意味着语言模型已经学习了 ChatML 格式的特殊 token,你无需担心这些层。注意 Int4 模型的层不应该是可训练的,因此如果你在训练中引入特殊 token,Q-LoRA 可能无法工作。 与全参数微调不同,LoRA 和 Q-LoRA 的训练仅保存适配器参数。假设你的训练从 Qwen-7B 开始,你可以如下所示加载微调后的模型进行推理: ``` from peft import AutoPeftModelForCausalLM model = AutoPeftModelForCausalLM.from_pretrained( path_to_adapter, # path to the output directory device_map="auto", trust_remote_code=True ).eval() ``` 如果你想合并适配器并将微调后的模型保存为独立模型(你只能对 LoRA 执行此操作,并且你无法合并 Q-LoRA 中的参数),你可以运行以下代码: ``` from peft import AutoPeftModelForCausalLM model = AutoPeftModelForCausalLM.from_pretrained( path_to_adapter, # path to the output directory device_map="auto", trust_remote_code=True ).eval() merged_model = model.merge_and_unload() # max_shard_size 和安全序列化不是必需的。 # 它们分别用于分片检查点和将模型保存为 safetensors merged_model.save_pretrained(new_model_directory, max_shard_size="2048MB", safe_serialization=True) ``` `new_model_directory` 目录将包含合并后的模型权重和模块文件。请注意,保存的文件中可能缺少 `*.cu` 和 `*.cpp` 文件。如果你希望使用 KV cache 功能,请手动复制它们。此外,tokenizer 文件在此步骤中未保存在新目录中。你可以复制 tokenizer 文件或使用以下代码 ``` from transformers import AutoTokenizer tokenizer = AutoTokenizer.from_pretrained( path_to_adapter, # path to the output directory trust_remote_code=True ) tokenizer.save_pretrained(new_model_directory) ``` 注意:对于多 GPU 训练,你需要根据你的机器为分布式训练指定适当的超参数。此外,我们建议你使用参数 `--model_max_length` 指定你的最大序列长度,基于你对数据、内存占用和训练速度的考虑。 ### 量化微调后的模型 本节适用于全参数/LoRA 微调后的模型。(注意:你不需要量化 Q-LoRA 微调后的模型,因为它已经是量化的。) 如果你使用 LoRA,请按照上述说明在量化前合并你的模型。 我们建议使用 [auto_gptq](https://github.com/PanQiWei/AutoGPTQ) 来量化微调后的模型。 ``` pip install auto-gptq optimum ``` 注意:目前 AutoGPTQ 有一个 [issue](https://github.com/PanQiWei/AutoGPTQ/issues/370) 中提到的 bug。这里有一个 [变通 PR](https://github.com/PanQiWei/AutoGPTQ/pull/495),你可以拉取此分支并从源代码安装。 首先,准备校准数据。你可以重用微调数据,或使用遵循相同格式的其他数据。 其次,运行以下脚本: ``` python run_gptq.py \ --model_name_or_path $YOUR_LORA_MODEL_PATH \ --data_path $DATA \ --out_path $OUTPUT_PATH \ --bits 4 # 4 for int4; 8 for int8 ``` 此步骤需要 GPU,并且根据你的数据大小和模型大小可能需要几个小时。 然后,将所有 `*.py`、`*.cu`、`*.cpp` 文件和 `generation_config.json` 复制到输出路径。我们建议你通过从相应的官方量化模型复制文件来覆盖 `config.json` (例如,如果你正在微调 `Qwen-7B-Chat` 并使用 `--bits 4`,你可以从 [Qwen-7B-Chat-Int4](https://huggingface.co/Qwen/Qwen-7B-Chat-Int4/blob/main/config.json) 找到 `config.json`)。 你还应该将 ``gptq.safetensors`` 重命名为 ``model.safetensors``。 最后,通过与加载官方量化模型相同的方法测试模型。例如, ``` from transformers import AutoModelForCausalLM, AutoTokenizer from transformers.generation import GenerationConfig tokenizer = AutoTokenizer.from_pretrained("/path/to/your/model", trust_remote_code=True) model = AutoModelForCausalLM.from_pretrained( "/path/to/your/model", device_map="auto", trust_remote_code=True ).eval() response, history = model.chat(tokenizer, "你好", history=None) print(response) ``` ### 多节点微调 我们提供的脚本支持多节点微调。你可以参考 [脚本](./finetune/finetune_lora_ds.sh) 中的注释来正确设置相应的参数并在每个节点上启动脚本。有关多节点分布式训练的更多信息,请参阅 [torchrun](https://pytorch.org/docs/stable/elastic/run.html)。 注意:DeepSpeed ZeRO 3 需要比 ZeRO 2 高得多的节点间通信速率,这在多节点微调的情况下会显著降低训练速度。因此,我们不建议在多节点微调脚本中使用 DeepSpeed ZeRO 3 配置。 ### 内存和速度分析 我们分析了单 GPU 训练设置下 LoRA(LoRA (emb) 指训练 embedding 和 output 层,而 LoRA 没有可训练的 embedding 和 output 层)和 Q-LoRA 的 GPU 内存和训练速度。在此测试中,我们在单个 A100-SXM4-80G GPU 上进行实验,我们使用 CUDA 11.8 和 Pytorch 2.0。启用了 Flash attention 2。我们统一使用 batch size 为 1 和梯度累积为 8。我们分析了不同长度输入的内存 (GB) 和速度,即 256、512、1024、2048、4096 和 8192。我们还报告了在 2 个 A100 GPU 上使用 Qwen-7B全参数微调的统计数据。由于 GPU 内存的限制,我们仅报告 256、512 和 1024 个 token 的统计数据。 对于 Qwen-7B,我们还测试了多节点微调的性能。我们使用两台服务器进行实验,每台包含两个 A100-SXM4-80G GPU,其余配置与其他 Qwen-7B 实验相同。多节点微调的结果在表中标记为 LoRA (multinode)。 对于 Qwen-72B,我们以两种方式进行实验:1) 在 4 个 A100-SXM4-80G GPU 上使用 Lora fintuning + DeepSpeed ZeRO 3 和 2) 在单个 A100-SXM4-80G GPU 上使用 QLora (int4) fine-tuning。请注意,在没有 Deepspeed ZeRO 3 的情况下,在 4 个 A100-SXM4-80G GPU 上使用 LoRA (emb) fine-tuning 和 LoRA fine-tuning 均会出现 OOM(你可以将 `--deepspeed finetune/ds_config_zero3.json` 传递给 [`finetune/finetune_lora_ds.sh`](finetune/finetune_lora_ds.sh) 以启用 DeepSpeed ZeRO 3)。 统计数据如下:
模型大小方法#节点每节点 GPU 数序列长度
2565121024204840968192
1.8BLoRA 11 6.7G / 1.0s/it7.4G / 1.0s/it8.4G / 1.1s/it11.0G / 1.7s/it16.2G / 3.3s/it21.8G / 6.8s/it
LoRA (emb) 11 13.7G / 1.0s/it14.0G / 1.0s/it14.0G / 1.1s/it15.1G / 1.8s/it19.7G / 3.4s/it27.7G / 7.0s/it
Q-LoRA 11 5.8G / 1.4s/it6.0G / 1.4s/it6.6G / 1.4s/it7.8G / 2.0s/it10.2G / 3.4s/it15.8G / 6.5s/it
Full-parameter 11 43.5G / 2.1s/it43.5G / 2.2s/it43.5G / 2.2s/it43.5G / 2.3s/it47.1G / 2.8s/it48.3G / 5.6s/it
7B LoRA 11 20.1G / 1.2s/it20.4G / 1.5s/it21.5G / 2.8s/it23.8G / 5.2s/it29.7G / 10.1s/it36.6G / 21.3s/it
LoRA (emb) 11 33.7G / 1.4s/it34.1G / 1.6s/it35.2G / 2.9s/it35.1G / 5.3s/it39.2G / 10.3s/it48.5G / 21.7s/it
Q-LoRA 11 11.5G / 3.0s/it11.5G / 3.0s/it12.3G / 3.5s/it13.9G / 7.0s/it16.9G / 11.6s/it23.5G / 22.3s/it
Full-parameter 12 139.2G / 4.0s/it148.0G / 4.0s/it162.0G / 4.5s/it---
LoRA (multinode) 22 74.7G / 2.09s/it77.6G / 3.16s/it84.9G / 5.17s/it95.1G / 9.25s/it121.1G / 18.1s/it155.5G / 37.4s/it
14B LoRA 11 34.6G / 1.6s/it35.1G / 2.4s/it35.3G / 4.4s/it37.4G / 8.4s/it42.5G / 17.0s/it55.2G / 36.0s/it
LoRA (emb) 11 51.2 / 1.7s/it51.1G / 2.6s/it51.5G / 4.6s/it54.1G / 8.6s/it56.8G / 17.2s/it67.7G / 36.3s/it
Q-LoRA 11 18.7G / 5.3s/it18.4G / 6.3s/it18.9G / 8.2s/it19.9G / 11.8s/it23.0G / 20.1s/it27.9G / 38.3s/it
72B LoRA + Deepspeed Zero3 14 215.4G / 17.6s/it217.7G / 20.5s/it222.6G / 29.4s/it228.8G / 45.7s/it249.0G / 83.4s/it289.2G / 161.5s/it
Q-LoRA 11 61.4G / 27.4s/it61.4G / 31.5s/it62.9G / 41.4s/it64.1G / 59.5s/it68.0G / 97.7s/it75.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 可以实现**角色扮演**、**语言风格迁移**、**任务设置**和**行为设置**。 ![](https://static.pigsec.cn/wp-content/uploads/repos/2026/03/ff30422952003113.png) ![](https://static.pigsec.cn/wp-content/uploads/repos/2026/03/d01617354b003120.png) 有关更多信息,请参阅[示例文档](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-498.0%0.95323.9%
GPT-3.574.5%0.80780.6%
Qwen-1_8B-Chat85.0%0.83927.6%
Qwen-7B-Chat95.5%0.90011.6%
Qwen-14B-Chat96.9%0.9175.6%
Qwen-72B-Chat98.2%0.9271.1%
为了评估 Qwen 使用 Python Code Interpreter 执行数学问题解决、数据可视化以及其他通用任务(如文件处理和网页抓取)的能力,我们创建并开源了一个专门用于评估这些能力的基准。你可以在此[链接](https://github.com/QwenLM/Qwen-Agent/tree/main/benchmark)找到该基准。 我们观察到 Qwen 在生成代码时的代码可执行性和结果准确性方面表现良好:
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 在长上下文场景中可以达到出色的性能。结果如下所示:

模型序列长度
10242048409681921638432768
Qwen-7B (原版)4.233.7839.35469.812645.09-
+ dynamic_ntk4.233.783.593.665.71-
+ dynamic_ntk + logn4.233.783.583.564.62-
+ dynamic_ntk + logn + window_attn4.233.783.583.494.32-
Qwen-1.8B5.004.484.133.8917.42433.85
+ dynamic_ntk + logn + window_attn5.004.484.143.933.823.83
Qwen-7B4.233.813.523.317.27181.49
+ dynamic_ntk + logn + window_attn4.233.813.523.333.223.17
Qwen-14B-3.4622.79334.653168.35-
+ dynamic_ntk + logn + window_attn-3.463.293.183.42-
Qwen-72B---2.832.732.72
此外,为了验证 Qwen-72B-Chat 在长文本理解上的能力,我们在 [L-Eval](https://arxiv.org/abs/2307.11088)(封闭式任务)上对其进行了测试。结果如下: | Model | Input Length | Average | Coursera | GSM | QuALITY | TOEFL | CodeU | SFcition | |:------------------|:------------:|:---------:|:----------:|:----------:|:----------:|:----------:|:----------:|:----------:| | ChatGPT-3.5-16k | 16K | 60.73 | **63.51** | **84.00** | 61.38 | 78.43 | **12.22** | 64.84 | | **Qwen-72B-Chat** | 32K | **62.30** | 58.13 | 76.00 | **77.22** | **86.24** | 6.66 | **69.53** | 我们进行了“大海捞针”实验(想法来自 [@Greg Kamradt](https://twitter.com/GregKamradt/status/1727018183608193393))以测试模型是否可以在不同长度的输入中的不同位置检索信息,结果如下: ![](https://static.pigsec.cn/wp-content/uploads/repos/2026/03/8453ea7298003124.png) 上述结果表明,Qwen-72B-Chat 可以准确地检索放置在 32k 输入长度内各种位置的信息,证明了其出色的长文本理解能力。 ## Tokenizer 我们基于 tiktoken 的 tokenizer 与其他 tokenizer 不同,例如 sentencepiece tokenizer。你需要注意特殊 token,尤其是在微调时。有关 tokenizer 及其在微调中相关用途的更多详细信息,请参阅[文档](tokenization_note.md)。

## 复现 为了让你在基准数据集上复现模型性能,我们提供了脚本供你复现结果。查看 [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} } ```
## 许可协议 在 提供的源代码根据可在根目录中找到的 [Apache 2.0 许可证](./LICENSE) 授权。 研究人员和开发者可以自由使用 Qwen 和 Qwen-Chat 的代码和模型权重。对于商业用途,请查看随附每个模型的许可协议。 - Qwen-72B、Qwen-14B 和 Qwen-7B 根据可在相应 HuggingFace 和 ModelScope 存储库中找到的
标签:AI, AIGC, Apex, DLL 劫持, Hugging Face, Int4, Int8, LLM, ModelScope, NLP, NLP库, PyTorch, Qwen, Transformer, Unmanaged PE, 中文大模型, 人工智能, 凭据扫描, 分布式搜索, 大语言模型, 对话系统, 开源模型, 机器学习, 模型量化, 深度学习, 生成式AI, 用户模式Hook绕过, 系统调用监控, 索引, 自动化代码审查, 逆向工具, 通义千问, 阿里云, 预训练技术, 预训练模型