OpenHarmony开发者论坛

标题: 拆·应用丨第6期:基于Vulkan的端侧AI运算 [打印本页]

作者: 开源鸿蒙知行录    时间: 2026-1-22 14:19
标题: 拆·应用丨第6期:基于Vulkan的端侧AI运算
[md]> 【拆·应用】是为开源鸿蒙应用开发者打造的技术分享平台,是汇聚开发者的技术洞见与实践经验、提供开发心得与创新成果的展示窗口。诚邀您踊跃发声,期待您的真知灼见与技术火花!
> **引言**
> 本期内容由AI Model SIG提供,介绍了在开源鸿蒙中,利用图形接口Vulkan的计算着色器能力,在端侧部署大模型的的整体思路和实践分享。

开源鸿蒙是由开放原子开源基金会孵化及运营的开源项目,目标是面向全场景、全连接、全智能时代,搭建一个智能终端设备操作系统的框架和平台,促进万物互联产业的繁荣发展。在人工智能时代下,与其它成熟的操作系统相比,开源鸿蒙部署AI LLM模型的能力欠缺。为了补齐开源鸿蒙在端侧部署大模型的能力,笔者将分享如何在端侧打通大模型部署的整体思路和实践。

# 软硬件选型

在硬件上选取国产CPU飞腾D2000,显卡选用AMD GPU。目前能够在 `OpenHarmony5.0.0 Release`上点亮AMD GPU,包括RX 550、RX 580和RX 7900 XTX。
其次是推理框架的选择,笔者选取了 `llama.cpp`这个开源的[推理框架](github.com/ggml-org/llama.cpp)。目前很火的 `ollama`,其也是选用了 `llama.cpp`作为推理后端。`llama.cpp`是一个专注于在边缘设备、个人PC上进行llm部署的高性能推理框架。其相比于vllm等主流llm推理框架来说,有以下明显的优点:

- 纯 C++/C 实现,在 `Windows`、`mac`、`Linux`等多种系统下编译都非常简单。
- 丰富的后端支持:如图所示,支持 `x86`、`arm`、`Nvidia_GPU`、`AMD_GPU`、`Vulkan`甚至 `华为昇腾NPU_CANN`。
- 支持CPU AVX指令集进行矢量计算加速、CPU多核并行计算、CPU+GPU混合计算
- 支持低精度量化:1.5bit、2 bit、3 bit、4 bit、5 bit、6 bit和 8 bit整数量化,可加快推理速度并减少内存使用。

<div align="center"><img src="https://forums-obs.openharmony.cn/forum/202601/22/142413ic8esmg8egvcgmim.png" alt="表格"></div>
<div align="center">llama.cpp支持的后端及其硬件</div>

在上图中,`llama.cpp`支持 `Vulkan`后端。笔者通过查阅相关资料和阅读 `llama.cpp`关于 `Vulkan`的相关代码,发现其是利用图形接口 `Vulkan`的计算着色器(Compute Shader)的能力来运行大模型的。计算着色器(Compute Shader) 是GPU上用于通用计算(GPGPU) 的特殊程序,与传统图形渲染管线解耦,可直接操作GPU并行处理非图形任务(如AI推理、物理模拟、数据处理)等。下表是计算着色器的特点:

![2.jpg](https://forums-obs.openharmony.c ... jxjewjhbocwjmqx.jpg "2.jpg")

综合多因素的考量,在软硬件上最终选用 `飞腾D2000` + `AMD GPU` + `OpenHarmony 5.0.0 Release`的组合,利用图形接口 `Vulkan`的计算着色器能力,在终端设备上高效运行大模型。

# 在开源鸿蒙部署大模型的难点

在第一部分提到将利用图形接口Vulkan的计算着色器的能力,在端侧高效运行大模型。在开源鸿蒙社区有个 `Vulkan`的[demo样例](https://gitee.com/openharmony/ap ... re/Native/NdkVulkan "demo样例的仓库地址"),通过笔者的实践,目前在 `HarmonyOS`能跑通该样例,但是在开源鸿蒙上尚不能跑通该样例。通过阅读该例子的文档说明,如下图,发现核心原因是缺少AMD GPU的 `Vulkan`用户态驱动库 `libvulkan_radeon.so`以及 `Vulkan`的sdk。因此核心难点是要能将 `Vulkan`的计算着色器在开源鸿蒙上正常跑起来。

<div align="center"><img src="https://forums-obs.openharmony.cn/forum/202601/22/142438y6xx1sfaezyk6e0a.jpg" alt="图片描述"></div>
<div align="center">NdkVulkan例子</div>

# 整体思路

为了能够利用图形接口 `Vulkan`的计算着色器的能力跑大模型。笔者总结了以下四个的关键步骤:

1. 在开源鸿蒙上正常点亮AMD GPU。
2. 交叉编译出AMD的 `Vulkan`用户态驱动。
3. 交叉编译出Vulkan sdk。
4. 移植 `llama.cpp`到 `OpenHarmony`上。

## 实践要点

### 点亮AMD GPU

1. 确保AMD GPU 内核态是正常的选用的内核版本为 `linux 6.6.22`,需要将内核的以下选项打开。

![4.jpg](https://forums-obs.openharmony.c ... a00fgqf322dqndg.jpg "4.jpg")

系统正常启动后,采用 `modetest`工具进行测试,在测试前需要关闭 `render_service`、`composer_host`和 `allocator_host`这三个进程,具体的命令如下:

![5.jpg](https://forums-obs.openharmony.c ... vf1wfa5z71to8oj.jpg "5.jpg")

在 `hdc shell`中运行以下命令:

![6.jpg](https://forums-obs.openharmony.c ... bsb3czorcr9v17v.jpg "6.jpg")

如果能够在显示屏上看到彩色的条纹,如下图,说明AMD GPU的内核态是正常的。

<div align="center"><img src="https://forums-obs.openharmony.cn/forum/202601/22/142527tthavqzyathvah9b.jpg" alt="图片描述"></div>
<div align="center">modetest测试结果</div>

2. 确保AMD GPU的用户态是正常的

首先通过 `mesa3d`交叉编译出AMD GPU的用户态驱动,主要为 `libEGL.so.1.0.0`、`libgallium_dri.so`、`libgbm.so.1.0.0`、`libglapi.so.0.0.0`、`libGLESv1_CM.so.1.1.0`和 `libGLESv2.so.2.0.0`这个5个动态库。

![8.png](https://forums-obs.openharmony.c ... tst3se5a9axengb.png "8.png")

大家可以参考laval社区的[《开源鸿蒙开源GPU库Mesa3D适配说明》](https://laval.csdn.net/64804567ade290484cb2ed06.html "开源鸿蒙开源GPU库Mesa3D适配说明")这篇文章,了解GPU的适配过程。这篇文章主要讲的是 `mali gpu`的 `mesa3d`点亮过程。由于跑 `Vulkan`的计算着色器可以不用到显示的功能,因此在这里具体的适配过程就不展开,感兴趣的读者可在AI Model SIG的 `ohos_vulkan`仓库获取相关的AMD GPU 的[mesa用户态驱动的库](https://gitcode.com/ai_model_sig/ohos_vulkan "库下载地址")。 成功适配后,可以在显示屏正常看到开源鸿蒙的桌面。

### `Vulkan`用户态驱动

这一步的核心是能够获得 `libvulkan_radeon.so`这个动态库。在 `mesa3d`中有 `Vulkan`用户态驱动的实现,因此通过编译 `mesa3d`这个开源项目编译出 `libvulkan_radeon.so`这个 `Vulkan`用户态驱动库。
在 `build_ohos.py`文件中需要指定 `-Dgallium-drivers=amd` 和 `-Dvulkan-drivers=amd`这两个参数,如下图:

![9.jpg](https://forums-obs.openharmony.c ... cnibc44n3xcbz3c.jpg "9.jpg")

通过以下指令:

![10.png](https://forums-obs.openharmony.c ... yyj7t2tywiwfte1.png "10.png")

便可以编译出 `libvulkan_radeon.so`这个动态库,如下图所示

![11.jpg](https://forums-obs.openharmony.c ... g56nlvdfod3l386.jpg "11.jpg")

### Vulkan sdk

`Vulkan sdk`的构成主要包含以下11个项目:

> https://github.com/KhronosGroup/glslang.git
> https://github.com/KhronosGroup/SPIRV-Headers.git
> https://github.com/KhronosGroup/SPIRV-Tools.git
> https://github.com/zeux/volk.git
> https://github.com/KhronosGroup/Vulkan-ExtensionLayer.git
> https://github.com/KhronosGroup/Vulkan-Headers.git
> https://github.com/KhronosGroup/Vulkan-Loader.git
> https://github.com/KhronosGroup/Vulkan-Tools.git
> https://github.com/KhronosGroup/Vulkan-Utility-Libraries.git
> https://github.com/KhronosGroup/Vulkan-ValidationLayers.git

在这里需要通过交叉编译的方式获得 `aarch64`版本的产物,如下图所示。

![12.png](https://forums-obs.openharmony.c ... 1sw2weveb699elz.png "12.png")

`Vulkan sdk`的编译比较复杂,可在[这里](https://gitcode.com/ai_model_sig/ohos_vulkan/pull/1)了解详情。
下面介绍一下如何将 `Vulkan sdk`部署在开源鸿蒙上:
![13.jpg](https://forums-obs.openharmony.c ... 6m56n939yoko5em.jpg "13.jpg")

通过运行 `vulkaninfo`可以获取 `vulkan`的相关信息,也能获取我们所用GPU的型号。
![14.jpg](https://forums-obs.openharmony.c ... pbu1y4x0744yubx.jpg "14.jpg")

![15.png](https://forums-obs.openharmony.c ... vjzzplj56qidtkm.png "15.png")

目前我们能将 `Vulkan`在开源鸿蒙上正式跑起来了,接下来需要写一个简单的例子来验证 `Vulkan`的计算着色器是否正常。笔者提供了一个简单的[利用计算着色器](https://laval.csdn.net/685bdb3d965a29319f2773cb.html)来进行矩阵并行计算。该例子的核心就是矩阵A和矩阵B相乘的到矩阵C,矩阵C的每个元素需要做**256次乘法**和**255次加法**。

<div align="center">
  <img src="https://forums-obs.openharmony.cn/forum/202601/22/142823i3peiqpq1pmj5357.png" alt="图片描述">
  </div>
<div align="center">计算着色器</div>



下面是例子的具体内容:

> 整体流程:初始化Vulkan → 创建矩阵缓冲区 → 构建计算管线 → 提交计算任务 → 同步获取结果 → 验证输出 → 资源释放;

编写计算着色器,如下图;
并行策略:每个线程计算输出矩阵的一个元素;
工作组配置:每个工作组包含16x16=256个并行线程;
执行粒度:与主程序中的 `vkCmdDispatch(MATRIX_SIZE/16, MATRIX_SIZE/16, 1)`配合,共调度 (256/16)^2 = 256个工作组覆盖整个矩阵; 线程总数:256 * 256 = 65536 个并行线程。

<div align="center">
  <img src="https://forums-obs.openharmony.cn/forum/202601/22/142834os5tjukz63kxtw6x.jpg" alt="图片描述">
  </div>
<div align="center">计算着色器</div>

假设矩阵A的元素全为1,矩阵B的元素全为2,那么矩阵C的计算结果应该全为512。如下图可见矩阵C的计算结果正确,总耗时大概在5毫秒左右。通过对比矩阵C的结果和耗时,初步可以确认 `Vulkan`的计算着色器能在开源鸿蒙上正常运行。

<div align="center">
  <img src="https://forums-obs.openharmony.cn/forum/202601/22/142858x350lj06lqleqqel.jpg" alt="图片描述">
  </div>

<div align="center">矩阵C的计算结果</div>

### 推理框架 `llama.cpp`

利用前一步得到的 `Vulkan sdk`,接下来需要交叉编译出 `llama.cpp`。下面是交叉编译的命令。

![19.jpg](https://forums-obs.openharmony.c ... n67a0iiut6a3ntn.jpg "19.jpg")

最终我们将编译的产物拷贝至开源鸿蒙设备上,然后运行。可以看到 `llama.cpp`能够正确识别我们的AMD GPU并将模型的权重加载至显卡上。
![20.jpg](https://forums-obs.openharmony.c ... z43zhgnwhgelzny.jpg "20.jpg")

![21.jpg](https://forums-obs.openharmony.c ... eeev913u31e6dxz.jpg "21.jpg")

# 总结

本文主要分享了如何在端侧打通大模型部署的整体思路和实践,从而补齐开源鸿蒙在端侧部署大模型的能力。目前能够利用图形接口 `Vulkan`的计算着色器的能力,能够在端侧的AMD的消费级显卡 `AMD 7900XTX`上部署类似 `DeepSeek 32B`这类的大模型,从而打造了AI能力的算力底座,为AI应用提供支撑。

[/md]




欢迎光临 OpenHarmony开发者论坛 (https://forums.openharmony.cn/) Powered by Discuz! X3.5