fix: update README since we support 32k context length (#12)
English | 中文
DashInfer采用C++ Runtime编写,提供C++和Python语言接口。DashInfer具有生产级别的高性能表现,适用于多种CPU架构,包括x86和ARMv9。DashInfer支持连续批处理(Continuous Batching)和多NUMA推理(NUMA-Aware),能够充分利用服务器级CPU的算力,为推理14B及以下的LLM模型提供更多的硬件选择。
DashInfer Demo on ModelScope
Demo信息:
InstantQuant是一种weight-only量化技术。
在Yitian710 CPU(ARMv9)上,DashInfer支持weight-only量化。
要进行weight-only量化,需要修改模型配置文件的do_dynamic_quantize_convert和quantization_config字段,参数的详细说明参考文档。
do_dynamic_quantize_convert
quantization_config
weight-only量化,会在GroupSize的范围内求取weight的最大、最小值,并将weight数值映射到uint8的值域范围,计算公式如下:
推理过程中,量化的weight会被恢复成bfloat16进行矩阵乘法计算。
模型加载与序列化:此过程负责读取模型权重、配置模型转换参数及量化参数,并根据这些信息对模型进行序列化,并生成DashInfer格式(.dimodel、.ditensors)的模型。此功能仅提供Python接口,并依赖于PyTorch和transformers库来访问权重。不同模型对PyTorch和transformers的版本要求可能有所不同,DashInfer本身并没有特殊的版本要求。
模型推理:此步骤负责执行模型推理,使用DashInfer推理序列化后的模型,不依赖PyTorch等组件。DashInfer采用DLPack格式的tensor来实现与外部框架(如PyTorch)的交互。DLPack格式的tensor,可以通过手动创建或由深度学习框架的tensor转换函数产生。对于C++接口,由于已经将几乎所有依赖静态编译,仅对openmp运行时库以及C++系统库的有依赖。我们进行了链接符号处理,以确保只有DashInfer的API接口符号可见,避免与客户系统中已有的公共库(如protobuf等)发生版本冲突。
说明: .dimodel、.ditensors是由DashInfer内核定义的一种特殊的模型格式。 使用Python接口时,可以将步骤1和2的代码放在一起。由于缺少C++层面加载Huggingface模型的功能,C++接口只能进行DashInfer格式的模型推理,因此在使用C++接口前,必须先用Python接口先对模型进行序列化。
说明:
在模型推理阶段,可以通过StartRequest传入请求输入token和生成参数发起推理请求,当请求成功后,DashInfer engine会返回一个输出队列ResultQueue和控制句柄RequestHandle。
StartRequest
ResultQueue
RequestHandle
ResultQueue用来获取输出token以及生成的状态,推理引擎会异步地把生成的token放到该队列中,可以阻塞(ResultQueue.Get())或非阻塞(ResultQueue.GetNoWait())地获取队列中的token。
ResultQueue.Get()
ResultQueue.GetNoWait()
RequestHandle是用来管理请求的句柄,DashInfer engine根据传入的RequestHandle实现对指定request的同步(Sync)、停止(Stop)和释放(Release)操作。其中SyncRequest操作,会在生成结束(生成的token数达到上限,或产生结束符)后返回,用来模拟同步接口的行为。
engine
SyncRequest
在单NUMA的模式下,DashInfer Runtime采用多线程和线程池的结构做调度。
由于部分Linux内核无法在线程级别控制CPU亲和性,在多NUMA的CPU上采用单进程推理可能会出现跨NUMA访问内存访问,从而导致性能下降。为了能够精确地控制程序的CPU亲和性,DashInfer的多NUMA方案采用了多进程的client-server架构,实现tensor parallel的模型推理。在每个NUMA节点上,都有一个独立的进程运行DashInfer server,每个server负责一部分的tensor parallel推理,进程间使用OpenMPI进行协同(例如allreduce操作)。DashInfer client通过gRPC与server交互,提供唯一的对外接口,避免在调用DashInfer接口时,需要对多进程进行管理。
在API使用上,多NUMA和单NUMA的推理需要引用不同的头文件、.so库(或调用不同的python接口)。除了引用阶段外,其余接口一致,无需修改代码。具体可以参考examples中的示例。
注意:C++的liballspark_framework.so(单NUMA推理时调用)和liballspark_client.so(多NUMA推理时调用)是互斥的,不能同时链接两个库。
详细的性能测试结果请参考文档。
该性能测试结果可用<path_to_dashinfer>/examples/python/1_performance中的脚本复现。
<path_to_dashinfer>/examples/python/1_performance
测试模型:Qwen/Qwen-7B-Chat
<path_to_dashinfer>/examples/python/2_evaluation
在<path_to_dashinfer>/examples下提供了C++、python接口的调用示例,请参考<path_to_dashinfer>/documents/CN目录下的文档运行示例。
<path_to_dashinfer>/examples
<path_to_dashinfer>/documents/CN
本小节列出了DashInfer不同阶段的第三方依赖。
注:这些依赖包通过conan管理,在编译DashInfer时自动下载。
DashInfer源代码采用Apache 2.0协议授权,您可在该仓库根目录找到协议全文。
©Copyright 2023 CCF 开源发展委员会 Powered by Trustie& IntelliDE 京ICP备13000930号
English | 中文
简介
DashInfer采用C++ Runtime编写,提供C++和Python语言接口。DashInfer具有生产级别的高性能表现,适用于多种CPU架构,包括x86和ARMv9。DashInfer支持连续批处理(Continuous Batching)和多NUMA推理(NUMA-Aware),能够充分利用服务器级CPU的算力,为推理14B及以下的LLM模型提供更多的硬件选择。
DashInfer的主要特征
DashInfer Demo
DashInfer Demo on ModelScope
Demo信息:
文档
硬件支持和数据类型
硬件支持
数据类型
InstantQuant
InstantQuant是一种weight-only量化技术。
在Yitian710 CPU(ARMv9)上,DashInfer支持weight-only量化。
要进行weight-only量化,需要修改模型配置文件的
do_dynamic_quantize_convert
和quantization_config
字段,参数的详细说明参考文档。weight-only量化,会在GroupSize的范围内求取weight的最大、最小值,并将weight数值映射到uint8的值域范围,计算公式如下:
scale=255−0xfp32max−xfp32minzeropoint=0−scalexfp32minxu8=xfp32/scale+zeropoint推理过程中,量化的weight会被恢复成bfloat16进行矩阵乘法计算。
模型支持
Qwen/Qwen-7B-Chat,
Qwen/Qwen-14B-Chat, etc.
qwen/Qwen-7B-Chat,
qwen/Qwen-14B-Chat, etc.
Qwen/Qwen1.5-1.8B-Chat,
Qwen/Qwen1.5-4B-Chat,
Qwen/Qwen1.5-7B-Chat,
Qwen/Qwen1.5-14B-Chat, etc.
qwen/Qwen1.5-1.8B-Chat,
qwen/Qwen1.5-4B-Chat,
qwen/Qwen1.5-7B-Chat,
qwen/Qwen1.5-14B-Chat, etc.
THUDM/chatglm2-6b-32k
ZhipuAI/chatglm2-6b-32k
THUDM/chatglm3-6b-32k
ZhipuAI/chatglm3-6b-32k
meta-llama/Llama-2-13b-chat-hf
modelscope/Llama-2-13b-chat-ms
软件框架
推理流程
模型加载与序列化:此过程负责读取模型权重、配置模型转换参数及量化参数,并根据这些信息对模型进行序列化,并生成DashInfer格式(.dimodel、.ditensors)的模型。此功能仅提供Python接口,并依赖于PyTorch和transformers库来访问权重。不同模型对PyTorch和transformers的版本要求可能有所不同,DashInfer本身并没有特殊的版本要求。
模型推理:此步骤负责执行模型推理,使用DashInfer推理序列化后的模型,不依赖PyTorch等组件。DashInfer采用DLPack格式的tensor来实现与外部框架(如PyTorch)的交互。DLPack格式的tensor,可以通过手动创建或由深度学习框架的tensor转换函数产生。对于C++接口,由于已经将几乎所有依赖静态编译,仅对openmp运行时库以及C++系统库的有依赖。我们进行了链接符号处理,以确保只有DashInfer的API接口符号可见,避免与客户系统中已有的公共库(如protobuf等)发生版本冲突。
单NUMA架构图
在模型推理阶段,可以通过
StartRequest
传入请求输入token和生成参数发起推理请求,当请求成功后,DashInfer engine会返回一个输出队列ResultQueue
和控制句柄RequestHandle
。ResultQueue
用来获取输出token以及生成的状态,推理引擎会异步地把生成的token放到该队列中,可以阻塞(ResultQueue.Get()
)或非阻塞(ResultQueue.GetNoWait()
)地获取队列中的token。RequestHandle
是用来管理请求的句柄,DashInferengine
根据传入的RequestHandle
实现对指定request的同步(Sync)、停止(Stop)和释放(Release)操作。其中SyncRequest
操作,会在生成结束(生成的token数达到上限,或产生结束符)后返回,用来模拟同步接口的行为。在单NUMA的模式下,DashInfer Runtime采用多线程和线程池的结构做调度。
多NUMA架构图
由于部分Linux内核无法在线程级别控制CPU亲和性,在多NUMA的CPU上采用单进程推理可能会出现跨NUMA访问内存访问,从而导致性能下降。为了能够精确地控制程序的CPU亲和性,DashInfer的多NUMA方案采用了多进程的client-server架构,实现tensor parallel的模型推理。在每个NUMA节点上,都有一个独立的进程运行DashInfer server,每个server负责一部分的tensor parallel推理,进程间使用OpenMPI进行协同(例如allreduce操作)。DashInfer client通过gRPC与server交互,提供唯一的对外接口,避免在调用DashInfer接口时,需要对多进程进行管理。
在API使用上,多NUMA和单NUMA的推理需要引用不同的头文件、.so库(或调用不同的python接口)。除了引用阶段外,其余接口一致,无需修改代码。具体可以参考examples中的示例。
性能测试
详细的性能测试结果请参考文档。
该性能测试结果可用
<path_to_dashinfer>/examples/python/1_performance
中的脚本复现。精度测试
测试模型:Qwen/Qwen-7B-Chat
<path_to_dashinfer>/examples/python/2_evaluation
中的脚本复现。示例代码
在
<path_to_dashinfer>/examples
下提供了C++、python接口的调用示例,请参考<path_to_dashinfer>/documents/CN
目录下的文档运行示例。依赖库
本小节列出了DashInfer不同阶段的第三方依赖。
代码编译阶段
模型转换阶段
模型推理阶段
未来规划
License
DashInfer源代码采用Apache 2.0协议授权,您可在该仓库根目录找到协议全文。