当前位置: 首页 > news >正文

在NPU平台上,如何尝试跑通Ktransformers + DeepSeek R1?

1、Ktransformers介绍

KTransformers是一个灵活的、以Python为中心的框架,其核心是可扩展性。通过用一行代码实现和注入一个优化的模块,用户可以访问与Transformers兼容的接口、兼容OpenAI和Ollama的RESTful API,甚至是一个简化的类似ChatGPT的Web UI。
在这里插入图片描述

仓库地址:https://github.com/kvcache-ai/ktransformers
考虑到vLLM已经是大规模部署优化的优秀框架,KTransformers特别关注受有限资源限制的本地部署。我们特别关注异构计算机会,例如量化模型的GPU/CPU卸载。例如,我们分别为CPU和GPU支持高效的Llamafile和Marlin内核.

2、环境准备

硬件环境:

Kunpeng-920 + 800IA2

软件版本:

torch-2.4.0
torch_npu-2.4.0.post2-cp311
CANN:version=24.1.0
Python版本:python=3.11

DeepSeek-R1-GGUF:
Int8版本:https://modelscope.cn/models/unsloth/DeepSeek-R1-GGUF/files/ DeepSeek-R1-Q8_0
BF16版本:https://modelscope.cn/models/unsloth/DeepSeek-R1-GGUF/files/ 8bit版本:https://modelscope.cn/models/unsloth/DeepSeek-R1-GGUF/files/ DeepSeek-R1-Q8_0

3、编译 & 运行

根据官网提供的Installation Guide(https://kvcache-ai.github.io/ktransformers/en/install.html)文件,按照步骤进行编译安装。
需要注意点如下:

  1. 建议创建一个独立的conda环境,因为GLIBC的问题,可能需要升级安装libstdcxx-ng库文件
  2. torch,torchvision,torchaudio,这几个软件的版本与torch_npu的版本保持一致,否则会报错不兼容的问题。

3.1 编译

Step 1、下载源码:

git clone https://github.com/kvcache-ai/ktransformers.git
cd ktransformers
git submodule init
git submodule update

Step 2、执行编译安装脚本

bash install.sh

直接执行脚本,会到很多的问题。这里做一个需要修改内容的大概介绍,全量修改详见附件中提供ktransformers.patch文件。

1、 KTransformersOps
由于KTransformersOps提供的是cuda的相关的反量化算子,npu上肯定用不到,而且当前不会用AscendC进行源码编写替代,因此用到KTransformersOps的地方,需要屏蔽掉其调用。

2、cpufeature问题
cpufeature是x86上的一个wheel包,用来获取cpu相关的信息,arm上不存在这个包,需要通过其它的接口进行规避使用。

3、 cuda相关
KTransformers整个框架基于cuda来构建,与cuda的耦合度很高。Cuda相关的组件需要跳过或者规避,如setup.py中:
在这里插入图片描述

内容解释:
CMakeExtension部分的内容:通过CUDAExtension来编译安装ktransformers/ktransformers_ext下的一些手写算子(反量化算子),还有一些pybind11的编译(python提供反量化接口,最终执行是.cu中的手写算子)。

还有一些marlin gpu相关的代码需要修改,如:
/ktransformers/ktransformers/operators/linear.py

from torch import Tensor, nn
# import KTransformersOps 
from ktransformers.util.custom_gguf import GGUFLoader
from ktransformers.util.utils import InferenceState
# from ktransformers.ktransformers_ext.operators.custom_marlin.quantize.utils.marlin_utils import (
#     MarlinWorkspace,
#     marlin_quantize,
#     GPTQ_MARLIN_MIN_THREAD_N,
#     GPTQ_MARLIN_MAX_PARALLEL,
# )
from ktransformers.operators.base_operator import BaseInjectedModule

还有,在KTransformersLinear类中,用到一些在cuda文件中定义的变量,如GPTQ_MARLIN_MIN_THREAD_N,这些只需要在用到的地方重新定义即可,如
/ktransformers/ktransformers/operators/linear.py

LINEAR_MAP = {"KLinearMarlin": KLinearMarlin,"KLinearTorch": KLinearTorch,"KLinearCPUInfer": KLinearCPUInfer
}GPTQ_MARLIN_MIN_THREAD_N = 64class KTransformersLinear(BaseInjectedModule, KLinearBase):

4、 量化相关
在ktransformers/ktransformers/util/custom_gguf.py文件中,定义了大量反量化相关的操作接口,这些接口调用的就是KTransformersOps中定义的手写反量化算子。因此,如果需要完成同样的接口功能,一方面可以通过AscendC进行适配;另一个方面,可以先不用反量化的功能(也就是不开始量化的功能)。接口修改,可以先规避掉:

5、 get_package_version
这个是获取cuda版本的接口,在npu上需要魔改。对外发布的时候,需要改成与npu相关的版本信息。

3.2 运行

由于DeepSeek R1的gguf权重文件大小,当前以DeepSeek-V2模型作为基础,先打通npu侧的流程。当前基于torch_npu的单算子的模式进行打通。
1、添加torch_npu
在ktransformers/ktransformers/models/modeling_deepseek.py中添加如下修改:

from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELossimport torch_npu 
from torch_npu.contrib import transfer_to_npufrom transformers.activations import ACT2FN
from transformers.cache_utils import Cache, DynamicCache, StaticCache

2、关闭use_cuda_graph
修改local_chat.py中的local_chat接口,关闭use_cuda_graph

def local_chat(model_path: str | None = None,optimize_rule_path: str = None,gguf_path: str | None = None,max_new_tokens: int = 300,cpu_infer: int = Config().cpu_infer,use_cuda_graph: bool = False,prompt_file : str | None = None,mode: str = "normal",force_think: bool = False,
):

2、 执行local_chat命令:

python -m ktransformers.local_chat --model_path ../DeepSeek-V2-Lite-Chat --gguf_path ../DeepSeek-V2-Lite-Chat-GGUF

model_path:在Hugging Face上在deepseek-ai/DeepSeek-V2-Lite-Chat的模型文件夹,因为使用gguf量化后的权重文件,这里的model-00001-of-000004.safetensors ~ model-00003-of-000004.safetensors可以不用下载,其它的tokenizer.json、config.json等文件均需要;
gguf_path:这个下载的gguf权重文件夹,就算只有一个gguf文件,也需要用文件夹的形式。

当前算子执行到如下位置会报错:

在这里插入图片描述

由于接下来调试调优的工作与其它同学相重合,就暂且不继续攻关,以配合的方式继续关注相关工作。

4 重要问题FAQ

问题1:GLIBCXX报错
在这里插入图片描述
参见:
libstdc++.so.6: version `GLIBCXX_3.4.30‘ not found 解决方案_libstdc++6 3.4.30-CSDN博客
解决办法:
conda install -c conda-forge libstdcxx-ng

问题2:flash_attn
在这里插入图片描述
flash_attn就是实现 FlashAttention and FlashAttention-2 的仓库。
在这里插入图片描述

这个仓库只实现了CUDA toolkit or ROCm toolkit的版本,针对npu并没有实现。因此需要替换为npu或者pytorch实现的相关的flash_attention相关计算的接口。
如果是cuda环境,直接:pip install flash_attn

问题3:block_q8_0_x4未定义
在这里插入图片描述
这个问题本质上是arm-neo版本指令实现问题,不同的arm机器上,对该指令的支持情况并
不一致。本次通过修改llama.cpp/ggml-common.h中的内容即可解决:

解决办法:
/home/disk_sdd/zjun/ktransformers/third_party/llama.cpp/ggml-common.h文件中,添加如下定义:

//xlong
typedef struct {
ggml_half d[8];
int8_t qs[4*QK8_1];
} block_q8_1_x4;//static_assert(sizeof(block_q8_1_x4) == 4*sizeof(block_q8_1),"Size of block_q8_1_x4 is not equal to 4 times the size of block_q8_1");
// printf("sizeof(block_q8_1) = %zu\n", sizeof(block_q8_1));
// printf("sizeof(block_q8_1_x4) = %zu\n", sizeof(block_q8_1_x4));
typedef struct {
ggml_half d[4];
int8_t qs[4*QK8_0];
} block_q8_0_x4;

修改的截图如下:
在这里插入图片描述

问题4:getauxval未声明
在这里插入图片描述

AT_HWCAP、getauxval、HWCAP_FPHP中是在auxv.h中定义的,因此需要在编译llamafile时包含此文件。

解决办法:
打开third_party/llamafile/sgemm.cpp中的#include <sys/auxv.h>,
原本是注释的:// #include <sys/auxv.h>
在这里插入图片描述

问题5:vmul_16
在这里插入图片描述

Vmul_16是在glibc中定义的一个函数,这里报错,说明调用函数的时候,给的函数入参的类型不匹配。但是,通过详细的入参比较,并没有发现参数类型不一致的情况。由于该函数主要也就是做2个数的乘法,如下:

33057 __extension__ extern __inline float16x4_t
33058 __attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
33059 vmul_f16 (float16x4_t __a, float16x4_t __b)
33060 {
33061   return __a * __b;
33062 }
33063

因此,在使用到的地方,直接通过乘法解决。
解决办法:

在这里插入图片描述

http://www.lryc.cn/news/575001.html

相关文章:

  • 基于LangChat搭建RAG与Function Call结合的聊天机器人方案
  • 前端使用rtsp视频流接入海康威视摄像头
  • QT 学习笔记摘要(三)
  • HCIA-IP路由基础
  • C++ 多线程深度解析:掌握并行编程的艺术与实践
  • 基于CMS的黄道吉日万年历源码(自适应)
  • 商务年度总结汇报PPT模版分享
  • 板凳-------Mysql cookbook学习 (十--10)
  • LeetCode 3258.统计满足K约束的子字符串数量1
  • HTML表单元素
  • 线性结构之链表
  • 深度学习实战112-基于大模型Qwen+RAG+推荐算法的作业互评管理系统设计与实现
  • 机器学习01
  • SpringBoot高校党务系统
  • SpringBoot项目快速开发框架JeecgBoot——数据访问!
  • ros (二) 使用消息传递点云+rviz显示
  • Happy-LLM-Task06 :3.1 Encoder-only PLM
  • C++设计模式(GOF-23)——04 C++装饰器模式(Decorator)(一个类同时继承和组合另一个类)解决类爆炸问题、模板装饰器
  • python3文件操作
  • Node.js特训专栏-实战进阶:8. Express RESTful API设计规范与实现
  • python的智慧养老院管理系统
  • klayout db::edge 里的 crossed_by_point 的坑点
  • mbedtls ssl handshake error,res:-0x2700
  • 从零开始的云计算生活——第二十三天,稍作休息,Tomcat
  • Excel数据转SQL语句(增删改查)
  • 阿里云Web应用防火墙3.0使用CNAME接入传统负载均衡CLB
  • DDNS-GO 使用教程:快速搭建属于自己的动态域名解析服务(Windows 版)
  • 大语言模型的通用局限性与全球技术演进
  • React Native【实战范例】账号管理(含转换分组列表数据的封装,分组折叠的实现,账号的增删改查,表单校验等)
  • 【版本控制教程】如何使用Unreal Engine 5 + UE源代码控制(Perforce P4)