xFasterTransformer
xFasterTransformer 是一个在 X86 平台上对大型语言模型 (LLM) 进行优化的解决方案,与 GPU 平台上的 FasterTransformer 类似。xFasterTransformer 能够在多个插槽和节点间以分布式模式运行,以支持更大模型的推理。此外,它提供了 C++ 和 Python 的 API,从高级接口到低级接口,便于采用和集成。
目录
模型概述
大型语言模型(LLMs)发展得非常快,并在许多 AI 场景中得到了更广泛的应用。xFasterTransformer 是一种使用主流和流行的 LLM 模型在 Xeon 上进行推理的优化解决方案。xFasterTransformer 充分利用 Xeon 平台的硬件能力,实现了 LLM 推理在单个插槽和多个插槽/多个节点上的高性能和高可扩展性。
xFasterTransformer 提供了一系列的 C++ 和 Python API,供终端用户将 xFasterTransformer 直接集成到他们自己的解决方案或服务中。还提供了多种示例代码来演示其使用方法。用户可以使用提供的基准测试代码和脚本来展示性能。还提供了流行 LLM 模型的网页演示。
模型支持矩阵
模型 | 框架 | 分布 | |
---|---|---|---|
PyTorch | C++ | ||
ChatGLM | ✔ | ✔ | ✔ |
ChatGLM2 | ✔ | ✔ | ✔ |
ChatGLM3 | ✔ | ✔ | ✔ |
GLM4 | ✔ | ✔ | ✔ |
Llama | ✔ | ✔ | ✔ |
Llama2 | ✔ | ✔ | ✔ |
Llama3 | ✔ | ✔ | ✔ |
Baichuan | ✔ | ✔ | ✔ |
Baichuan2 | ✔ | ✔ | ✔ |
QWen | ✔ | ✔ | ✔ |
QWen2 | ✔ | ✔ | ✔ |
SecLLM(YaRN-Llama) | ✔ | ✔ | ✔ |
Opt | ✔ | ✔ | ✔ |
Deepseek-coder | ✔ | ✔ | ✔ |
gemma | ✔ | ✔ | ✔ |
gemma-1.1 | ✔ | ✔ | ✔ |
codegemma | ✔ | ✔ | ✔ |
数据类型支持列表
- FP16
- BF16
- INT8
- W8A8
- INT4
- NF4
- BF16_FP16
- BF16_INT8
- BF16_W8A8
- BF16_INT4
- BF16_NF4
- W8A8_INT8
- W8A8_int4
- W8A8_NF4
文档
xFasterTransformer 文档和 Wiki 提供以下资源:
- xFasterTransformer 简介。
- C++ 和 PyTorch 的高级以及低级接口的全面 API 参考。
- xFasterTransformer 在 C++ 和 PyTorch 中的实际 API 使用示例。
安装
从 PyPI 安装
pip install xfastertransformer
使用 Docker
docker pull intel/xfastertransformer:latest
使用以下命令运行 docker(假设模型文件在 /data/
目录下):
docker run -it \
--name xfastertransformer \
--privileged \
--shm-size=16g \
-v /data/:/data/ \
-e "http_proxy=$http_proxy" \
-e "https_proxy=$https_proxy" \
intel/xfastertransformer:latest
注意!!!:如果在多节点模式下运行时发生 总线错误,请增大 --shm-size
。默认 docker 将共享内存大小限制为 64MB,而我们的实现使用了许多共享内存来实现更高的性能。
从源码构建
准备环境
手动准备
-
PyTorch v2.3(使用 PyTorch API 时需要,但使用 C++ API 时不需要。)
pip install torch --index-url https://download.pytorch.org/whl/cpu
-
对于 GPU,xFT 需要从 torch==2.3.0+cpu.cxx11.abi 获取 ABI=1,因为 DPC++ 需要 ABI=1。
安装依赖库
请安装 libnuma 包:
- CentOS: yum install libnuma-devel
- Ubuntu: apt-get install libnuma-dev
如何构建
- 使用 'CMake'
# 构建 xFasterTransformer git clone https://github.com/intel/xFasterTransformer.git xFasterTransformer cd xFasterTransformer git checkout <最新标签> # 请确保运行 python 示例时已安装 torch mkdir build && cd build cmake .. make -j
- 使用
python setup.py
# 构建 xFasterTransformer 库和 C++ 示例。 python setup.py build # 将 xFasterTransformer 安装到 pip 环境中。 # 注意:在安装前运行 `python setup.py build`! python setup.py install
模型准备
xFasterTransformer 支持与 Huggingface 不同的模型格式,但兼容 FasterTransformer 的格式。
-
首先下载 huggingface 格式的模型。
-
然后,使用 xfastertransformer 中的模型转换模块将模型转换为 xFasterTransformer 格式。如果未提供输出目录,转换后的模型将放置在
${HF_DATASET_DIR}-xft
中。python -c 'import xfastertransformer as xft; xft.LlamaConvert().convert("${HF_DATASET_DIR}","${OUTPUT_DIR}")'
注意:由于模型文件和
transformers
版本之间可能存在兼容性问题,请选择合适的transformers
版本。支持的模型转换列表:
- LlamaConvert
- YiConvert
- GemmaConvert
- ChatGLMConvert
- ChatGLM2Convert
- ChatGLM4Convert
- OPTConvert
- BaichuanConvert
- Baichuan2Convert
- QwenConvert
- Qwen2Convert
- DeepseekConvert
API 使用
有关更多详细信息,请参见 API 文档和 示例。
Python API(PyTorch)
首先,请安装依赖项。
- Python 依赖项
注意:由于模型文件和pip install -r requirements.txt
transformers
版本之间可能存在兼容性问题,请选择合适的transformers
版本。 - oneCCL(用于多节点)
安装 oneCCL 并设置环境。请参阅 准备环境。
xFasterTransformer 的 Python API 类似于 transformers,并且还支持 transformers 的流媒体功能以实现流式输出。示例中,使用 transformers 对输入提示进行编码生成标记 ID。
import xfastertransformer
from transformers import AutoTokenizer, TextStreamer
# 假设 huggingface 模型目录为 `/data/chatglm-6b-hf`,转换后的模型目录为 `/data/chatglm-6b-xft`。
MODEL_PATH="/data/chatglm-6b-xft"
TOKEN_PATH="/data/chatglm-6b-hf"
INPUT_PROMPT = "从前,有一个喜欢冒险的小女孩。"
tokenizer = AutoTokenizer.from_pretrained(TOKEN_PATH, use_fast=False, padding_side="left", trust_remote_code=True)
streamer = TextStreamer(tokenizer, skip_special_tokens=True, skip_prompt=False)
input_ids = tokenizer(INPUT_PROMPT, return_tensors="pt", padding=False).input_ids
model = xfastertransformer.AutoModel.from_pretrained(MODEL_PATH, dtype="bf16")
generated_ids = model.generate(input_ids, max_length=200, streamer=streamer)
C++ API
SentencePiece 可用于标记和去标记文本。
#include <vector>
#include <iostream>
#include "xfastertransformer.h"
// ChatGLM 的提示语 "从前,有一个喜欢冒险的小女孩。" 的标记 ID
std::vector<int> input(
{3393, 955, 104, 163, 6, 173, 9166, 104, 486, 2511, 172, 7599, 103, 127, 17163, 7, 130001, 130004});
// 假设转换后的模型目录为 `/data/chatglm-6b-xft`。
xft::AutoModel model("/data/chatglm-6b-xft", xft::DataType::bf16);
model.config(/*max length*/ 100, /*num beams*/ 1);
model.input(/*input token ids*/ input, /*batch size*/ 1);
while (!model.isDone()) {
std::vector<int> nextIds = model.generate();
}
std::vector<int> result = model.finalize();
for (auto id : result) {
std::cout << id << " ";
}
std::cout << std::endl;
运行方法
建议预加载 libiomp5.so
来获得更好的性能。
- [推荐] 如果已安装 xfastertransformer 的 Python 轮包,运行
export $(python -c 'import xfastertransformer as xft; print(xft.get_env())')
。 - 从源码成功构建 xFasterTransformer 后,
libiomp5.so
文件将位于3rdparty/mkl/lib
目录中。
单节点
FasterTransformer 将自动检查 MPI 环境,或者您可以使用 SINGLE_INSTANCE=1
环境变量强制禁用 MPI。
多节点
命令行
使用 MPI 以多节点模式运行,请首先安装 oneCCL。
-
- 如果从源码构建了 xfastertransformer,编译时会在 3rdparty 中安装 oneCCL。
source ./3rdparty/oneccl/build/_install/env/setvars.sh
- [推荐] 使用提供的脚本从源码构建。
cd 3rdparty sh prepare_oneccl.sh source ./oneccl/build/_install/env/setvars.sh
- 通过安装 Intel® oneAPI Base Toolkit 安装 oneCCL。(注意:建议使用 2023.x 及以下版本。) 并通过以下命令设置环境:
source /opt/intel/oneapi/setvars.sh
- 如果从源码构建了 xfastertransformer,编译时会在 3rdparty 中安装 oneCCL。
-
这里是一个本地示例。
# 或者手动导出 LD_PRELOAD=libiomp5.so export $(python -c 'import xfastertransformer as xft; print(xft.get_env())') OMP_NUM_THREADS=48 mpirun \ -n 1 numactl -N 0 -m 0 ${RUN_WORKLOAD} : \ -n 1 numactl -N 1 -m 1 ${RUN_WORKLOAD}
代码
更多详细信息,请参阅示例。
Python
model.rank
可以获取进程的排名,model.rank == 0
是主节点。
对于从节点,加载模型后,只需执行 model.generate()
。输入和生成配置将自动同步。
model = xfastertransformer.AutoModel.from_pretrained("/data/chatglm-6b-xft", dtype="bf16")
# 从节点
while True:
model.generate()
C++
model.getRank()
可以获取进程的排名,model.getRank() == 0
是主节点。
对于从节点,可以向 model.config()
和 model.input
输入任意值,因为主节点的值将被同步。
xft::AutoModel model("/data/chatglm-6b-xft", xft::DataType::bf16);
// 从节点
while (1) {
model.config();
std::vector<int> input_ids;
model.input(/*input token ids*/ input_ids, /*batch size*/ 1);
while (!model.isDone()) {
model.generate();
}
}
Web演示
在仓库中提供了基于Gradio的Web演示。目前支持ChatGLM、ChatGLM2和Llama2模型。
- 准备模型。
- 安装依赖项
注意:由于模型文件与pip install -r examples/web_demo/requirements.txt
transformers
版本之间可能存在兼容性问题,请选择合适的transformers
版本。 - 运行对应模型的脚本。Web服务器启动后,打开浏览器中的输出URL以使用演示。请指定模型和分词器目录路径以及数据类型。
transformer
的分词器用于文本编码和解码,因此${TOKEN_PATH}
表示huggingface模型目录。此演示还支持多秩模式。
# 推荐预加载`libiomp5.so`以获得更好的性能。
# 或者手动LD_PRELOAD=libiomp5.so,`libiomp5.so`文件将在构建xFasterTransformer后位于`3rdparty/mkl/lib`目录中。
export $(python -c 'import xfastertransformer as xft; print(xft.get_env())')
python examples/web_demo/ChatGLM.py \
--dtype=bf16 \
--token_path=${TOKEN_PATH} \
--model_path=${MODEL_PATH}
服务端
vLLM
创建了一个vLLM的分支以集成xFasterTransformer后端,保持与大多数官方vLLM功能的兼容性。详情请参考此链接。
安装
pip install vllm-xft
注意:请不要同时在环境中安装vllm-xft
和vllm
。虽然包名不同,但实际上它们会相互覆盖。
OpenAI兼容服务器
注意:需要预加载libiomp5.so!
# 通过以下命令预加载libiomp5.so或手动LD_PRELOAD=libiomp5.so
export $(python -c 'import xfastertransformer as xft; print(xft.get_env())')
python -m vllm.entrypoints.openai.api_server \
--model ${MODEL_PATH} \
--tokenizer ${TOKEN_PATH} \
--dtype bf16 \
--kv-cache-dtype fp16 \
--served-model-name xft \
--port 8000 \
--trust-remote-code
对于多秩模式,请使用python -m vllm.entrypoints.slave
作为从节点,并使从节点的参数与主节点对齐。
# 通过以下命令预加载libiomp5.so或手动LD_PRELOAD=libiomp5.so
export $(python -c 'import xfastertransformer as xft; print(xft.get_env())')
OMP_NUM_THREADS=48 mpirun \
-n 1 numactl --all -C 0-47 -m 0 \
python -m vllm.entrypoints.openai.api_server \
--model ${MODEL_PATH} \
--tokenizer ${TOKEN_PATH} \
--dtype bf16 \
--kv-cache-dtype fp16 \
--served-model-name xft \
--port 8000 \
--trust-remote-code \
: -n 1 numactl --all -C 48-95 -m 1 \
python -m vllm.entrypoints.slave \
--dtype bf16 \
--model ${MODEL_PATH} \
--kv-cache-dtype fp16
FastChat
xFasterTransformer是FastChat的官方推理后端。详情请参考FastChat中的xFasterTransformer和FastChat的服务。
MLServer
提供了MLServer服务示例,支持REST和gRPC接口和自适应批处理功能,可以动态地将推理请求分组。
基准测试
提供了基准测试脚本,可以快速获取模型推理性能。
- 准备模型。
- 安装依赖项,包括oneCCL和Python依赖项。
- 进入
benchmark
文件夹并运行run_benchmark.sh
。更多信息请参考Benchmark README。
注意:系统和CPU配置可能不同。为了获得最佳性能,请尝试根据测试环境修改OMP_NUM_THREADS、数据类型和内存节点数(使用numactl -H
检查内存节点)。
支持
- xFasterTransformer邮件:xft.maintainer@intel.com
- xFasterTransformer微信
接受的论文
- ICLR'2024关于有限/低资源设置下实际的机器学习:分布式大语言模型在CPU上的推理性能优化
- ICML'2024关于野外基础模型:大语言模型在CPU上的推理性能优化
- IEEE ICSESS 2024:大语言模型推理的一体化方法
如果xFT对您的研究有用,请引用:
@article{he2024distributed,
title={Distributed Inference Performance Optimization for LLMs on CPUs},
author={He, Pujiang and Zhou, Shan and Li, Changqing and Huang, Wenhuan and Yu, Weifei and Wang, Duyi and Meng, Chen and Gui, Sheng},
journal={arXiv preprint arXiv:2407.00029},
year={2024}
}
以及
@inproceedings{he2024inference,
title={Inference Performance Optimization for Large Language Models on CPUs},
author={He, Pujiang and Zhou, Shan and Huang, Wenhuan and Li, Changqing and Wang, Duyi and Guo, Bin and Meng, Chen and Gui, Sheng and Yu, Weifei and Xie, Yi},
booktitle={ICML 2024 Workshop on Foundation Models in the Wild}
}
常见问题解答
-
问:xFasterTransformer可以在Intel® Core™ CPU上运行吗?
答:不可以。xFasterTransformer需要支持AMX和AVX512指令集,而Intel® Core™ CPU不具备这些指令集。 -
问:xFasterTransformer可以在Windows系统上运行吗?
答:目前没有本地支持Windows,所有兼容性测试仅在Linux上进行,因此推荐使用Linux。 -
问:安装最新版本的oneCCL通过oneAPI后,为什么在多秩模式下运行程序会冻结或出错?
答:请尝试降级oneAPI到2023.x版本或以下,或使用提供的脚本从源代码安装oneCCL。 -
问:为什么使用两个CPU插槽运行程序的性能比使用单个CPU插槽低很多?
答:这样的运行方式会导致程序进行许多不必要的跨插槽通信,显著影响性能。如果需要跨插槽部署,请考虑在每个插槽上运行一个秩的多秩模式。 -
问:在单秩运行时性能正常,但使用MPI运行多个秩时性能却很慢且CPU利用率很低,为什么?
答:这是因为通过MPI启动的程序会读取OMP_NUM_THREADS=1
,无法正确从环境中获取适当的值。需要根据实际情况手动设置OMP_NUM_THREADS
的值。 -
问:转换已经支持的模型时仍然遇到错误,为什么?
答:尝试降级transformer
到适当版本,如requirements.txt
中指定的版本。因为不同版本的Transformer可能会更改某些变量的名称。