1.引言
通义千问团队推出Qwen系列的首个MoE模型,Qwen1.5-MoE-A2.7B。它仅拥有27亿个激活参数,但其性能却能与当前最先进的70亿参数模型,如Mistral 7B和Qwen1.5-7B相媲美。相较于包含65亿个Non-Embedding参数的Qwen1.5-7B,Qwen1.5-MoE-A2.7B只有20亿个Non-Embedding参数,约为原模型大小的三分之一。此外,相比Qwen1.5-7B,Qwen1.5-MoE-A2.7B的训练成本降低了75%,推理速度则提升了1.74倍。
1.1模型结构
Qwen1.5-MoE模型采用了特别设计的MoE架构。通常情况下,如Mixtral等方法所示,每个transformer block中的MoE层会配备8个expert,并采用top-2门控策略进行routing。这种配置还存在很大的优化空间。Qwen1.5-MoE的架构进行了多项改进:
- Finegrained experts
- 初始化
- 新的routing机制
DeepSeek-MoE和DBRX已经证明了finegrained experts的有效性。从FFN层过渡到MoE层时,一般只是简单地复制多次FFN来实现多个expert。而finegrained experts的目标是在不增加参数数量的前提下生成更多expert。为了实现这一点,Qwen1.5-MoE模型将单个FFN分割成几个部分,每个部分作为一个独立的expert。通义千问团队设计了具有总共64个expert的的MoE,对比其他配置,通义千问团队认为这个实现能达到效果和效率的最优。
模型初始化阶段至关重要。初步实验表明,从零开始训练MoE模型可能效率低下,且难以提升至预期的最优性能水平。因此,通义千问团队首先利用已有的Qwen-1.8B,将其改造为Qwen1.5-MoE-A2.7B。此外,在初始化阶段引入随机性可以显著加快收敛速度,并在整个预训练过程中带来更好的整体性能表现。
目前,一个明显的趋势是在MoE中实现共享expert与routing expert。从更宏观的角度看,这是一种广义的routing方法,因为在没有共享expert的情况下,实际上就退化为传统的MoE路由设置。对于Qwen1.5-MoE-A2.7B模型,通义千问团队在其中整合了4个总是被激活的共享expert和每次只激活其中4个的60个routing expert。这种方式非常灵活,同时在实验中表现最佳。
1.2性能
为了全面评估和展示Qwen1.5-MoE-A2.7B的能力和优势,对base模型和chat模型进行了评估。对于base模型,在MMLU、GSM8K和HumanEval评估了其语言理解、数学和代码能力。此外,为了评估其多语言能力,按照Qwen1.5的评测方法在数学、理解、考试和翻译等多个领域的多语言基准测试中进行了测试,并在"Multilingual"列中给出了综合得分。对于chat模型,没有使用传统的基准测试,而是使用MT-Bench进行了测试。
Model |
MMLU |
GSM8K |
HumanEval |
Multilingual |
MT-Bench |
Mistral-7B |
64.1 |
47.5 |
27.4 |
40.0 |
7.60 |
Gemma-7B |
64.6 |
50.9 |
32.3 |
|
|
Qwen1.5-7B |
61.0 |
62.5 |
36.0 |
45.2 |
7.60 |
DeepSeekMoE 16B |
45.0 |
18.8 |
26.8 |
|
6.93 |
Qwen1.5-MoE-A2.7B |
62.5 |
61.5 |
34.2 |
40.8 |
7.17 |
Qwen1.5-MoE-A2.7B在与最佳的7B模型相比取得了非常接近的性能。同时,也发现在chat模型方面仍有改进的空间。通义千问团队将继续研究如何更加有效地微调MoE模型。
1.3训练成本与推理效率
MoE模型的训练成本与dense模型存在显著差异。尽管MoE模型通常拥有更多的参数,但由于其稀疏性,训练开销可以显著降低。先对比各个模型的三个关键参数,分别是总参数数量、激活参数数量和Non-embedding参数:
Model |
Parameters |
(Activated) Parameters |
(Activated) Non-embedding parameters |
Mistral-7B |
7.2 |
7.2 |
7.0 |
Gemma-7B |
8.5 |
7.8 |
7.8 |
Qwen1.5-7B |
7.7 |
7.7 |
6.4 |
DeepSeekMoE 16B |
16.4 |
2.8 |
2.4 |
Qwen1.5-MoE-A2.7B |
14.3 |
2.7 |
2.0 |
不难看出,尽管Qwen1.5-MoE总参数量较大,但Non-embedding激活参数量远小于7B模型。在实践中,观察到使用Qwen1.5-MoE-A2.7B相比于Qwen1.5-7B,训练成本显著降低了75%。另外,由于Qwen1.5-MoE的初始化方法,不需要训练同样数量的token即可达到很好的模型效果,这也显著降低了训练成本。
如下是使用vLLM部署了Qwen1.5-7B和Qwen1.5-MoE-A2.7B模型,并使用单个NVIDIA A100-80G GPU进行性能测试。在实验设置中,输入token数设置为1000,输出token数设置为1000,通过吞吐量(每秒处理的请求数)和每秒token数(TPS)来衡量性能:
Model |
Throughput |
TPS |
Qwen2-7B-Chat |
1.15 |
2298.89 |
Qwen1.5-MoE-A2.7B-Chat |
2.01 |
4010.27 |
Qwen1.5-MoE-A2.7B与Qwen1.5-7B相比,速度提高了约1.74倍。这种加速主要归因于MoE在前向过程中仅激活了其总参数的一小部分,从而降低了计算需求。此外,共享expert也提升了模型的推理效率。因此,尽管MoE模型增加了内存需求,但它们在吞吐性能和推理速度方面都表现出明显的优势。
1.4Qwen1.5-MoE模型体验
英文常识&推理问答能力:
中文写作问答能力:
数学:在四则运算和中文应用题解题上都能正确解答
四则运算
应用题
环境配置与安装
- python 3.8及以上版本
- pytorch 1.12及以上版本,推荐2.0及以上版本
- 建议使用CUDA 11.4及以上
- 依赖最新的Transformers代码
1.5使用步骤
本文主要演示的模型为Qwen1.5-MoE对话模型,在魔搭免费算力PAI-DSW使用
模型链接和下载
Qwen1.5-MoE模型系列现已在ModelScope社区开源,包括:
Qwen1.5-MoE-A2.7B-Chat-GPTQ-Int4
社区支持直接下载模型的repo:
from modelscope import snapshot_download model_dir = snapshot_download("qwen/Qwen1.5-MoE-A2.7B-Chat")
Qwen1.5-MoE模型推理
Qwen1.5-MoE-A2.7B-Chat-GPTQ-Int4推理代码,Qwen1.5-MoE已合并到HuggingFace的transformers最新官方代码
from modelscope import AutoModelForCausalLM, AutoTokenizer device = "cuda" # the device to load the model onto model = AutoModelForCausalLM.from_pretrained( "qwen/Qwen1.5-MoE-A2.7B-Chat-GPTQ-Int4", torch_dtype="auto", device_map="auto" ) tokenizer = AutoTokenizer.from_pretrained("qwen/Qwen1.5-MoE-A2.7B-Chat-GPTQ-Int4") prompt = "Give me a short introduction to large language model." messages = [ {"role": "system", "content": "You are a helpful assistant."}, {"role": "user", "content": prompt} ] text = tokenizer.apply_chat_template( messages, tokenize=False, add_generation_prompt=True ) model_inputs = tokenizer([text], return_tensors="pt").to(device) generated_ids = model.generate( model_inputs.input_ids, max_new_tokens=512 ) generated_ids = [ output_ids[len(input_ids):] for input_ids, output_ids in zip(model_inputs.input_ids, generated_ids) ] response = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0] print(response)
资源消耗(10G):
Qwen1.5-MoE-A2.7B-Chat使用vLLM加速推理:
要使用vLLM加速模型推理,请从源代码安装vLLM:
git clone https://github.com/wenyujin333/vllm.git cd vllm git checkout add_qwen_moe pip install -e .
设置环境变量VLLM_USE_MODELSCOPE为True,从ModelScope下载模型:
export VLLM_USE_MODELSCOPE=True
下面这个示例说明如何使用vLLM构建一个与Qwen-MoE兼容的OpenAI-API接口:
python -m vllm.entrypoints.openai.api_server --model qwen/Qwen1.5-MoE-A2.7B-Chat
curl http://localhost:8000/v1/chat/completions \ -H "Content-Type: application/json" \ -d '{ "model": "qwen/Qwen1.5-MoE-A2.7B-Chat", "messages": [ {"role": "system", "content": "You are a helpful assistant."}, {"role": "user", "content": "Tell me something about large language models."} ] }'
Qwen1.5-MoE模型还将继续更新对第三方框架的支持,包括llama.cpp、MLX等。
Qwen1.5-MoE微调和微调后推理
我们使用SWIFT来对模型进行微调, swift是魔搭社区官方提供的LLM&AIGC模型微调推理框架.
我们使用blossom-math-zh数据集进行微调,任务是: 解数学题
环境准备:
git clone https://github.com/modelscope/swift.git cd swift pip install .[llm]
微调脚本: LoRA
# https://github.com/modelscope/swift/blob/main/examples/pytorch/llm/scripts/qwen1half-moe-a2_7b-chat/lora/sft.sh # Experimental environment: A100 # 42GB GPU memory PYTHONPATH=../../.. \ CUDA_VISIBLE_DEVICES=0 \ python llm_sft.py \ --model_type qwen1half-moe-a2_7b-chat \ --sft_type lora \ --tuner_backend swift \ --dtype AUTO \ --output_dir output \ --dataset dureader-robust-zh \ --train_dataset_sample 10000 \ --num_train_epochs 1 \ --max_length 1024 \ --check_dataset_strategy warning \ --lora_rank 8 \ --lora_alpha 32 \ --lora_dropout_p 0.05 \ --lora_target_modules ALL \ --gradient_checkpointing true \ --batch_size 1 \ --weight_decay 0.1 \ --learning_rate 1e-4 \ --gradient_accumulation_steps 16 \ --max_grad_norm 0.5 \ --warmup_ratio 0.03 \ --eval_steps 100 \ --save_steps 100 \ --save_total_limit 2 \ --logging_steps 10 \ --use_flash_attn true \ --self_cognition_sample 1000 \ --model_name 卡卡罗特 \ --model_author 陶白白 \
训练过程也支持本地数据集,需要指定如下参数:
--custom_train_dataset_path xxx.jsonl \ --custom_val_dataset_path yyy.jsonl \
微调后推理脚本:
(这里的ckpt_dir需要修改为训练生成的checkpoint文件夹)
# Experimental environment: A100 # 3GB GPU memory PYTHONPATH=../../.. \ CUDA_VISIBLE_DEVICES=0 \ python llm_infer.py \ --ckpt_dir "output/qwen1half-moe-a2_7b-chat/vx-xxx/checkpoint-xxx" \ --load_dataset_config true \ --use_flash_attn true \ --max_new_tokens 2048 \ --temperature 0.1 \ --top_p 0.7 \ --repetition_penalty 1. \ --do_sample true \ --merge_lora false \
微调的可视化结果
训练loss:
训练后生成样例:
[PROMPT]<|im_start|>system You are a helpful assistant.<|im_end|> <|im_start|>user 学校需新添28套课桌椅,共付款1820元,椅子每把17元,课桌每张多少元?<|im_end|> <|im_start|>assistant [OUTPUT]设课桌每张x元。 根据题意,椅子每把17元,课桌每张x元。 则椅子的总费用为17元/把 × 28把 = 476元。 课桌的总费用为x元/张 × 28张 = 28x元。 根据题意,课桌和椅子的总费用为1820元。 所以,28x + 476 = 1820。 解方程得:28x = 1820 - 476 = 1344。 x = 1344 / 28 = 48。 所以,课桌每张48元。 Answer: 48<|im_end|> [LABELS]假设课桌的价格为x元每张。 根据题意可得方程: 28(17+x) = 1820 化简得: 476 + 28x = 1820 移项得: 28x = 1820 - 476 化简得: 28x = 1344 将等式两边同时除以28,得: x = 1344 / 28 化简得: x = 48 所以,每张课桌的价格为48元。 Answer: 48 -------------------------------------------------- [PROMPT]<|im_start|>system You are a helpful assistant.<|im_end|> <|im_start|>user 甲数是18,乙数比甲数的2倍少5,乙数=.<|im_end|> <|im_start|>assistant [OUTPUT]设乙数为x,则根据题意可得: x = 2 * 18 - 5 x = 36 - 5 x = 31 所以乙数为31。 Answer: 31<|im_end|> [LABELS]首先,让我们用变量来表示甲数和乙数。 甲数 = 18 乙数 = 2 * 甲数 - 5 将甲数的值代入乙数的表达式中,我们得到: 乙数 = 2 * 18 - 5 = 36 - 5 = 31 所以,乙数=31。 Answer: 31
资源消耗
微调
点击直达体验创空间: