ARM上运行llama.cpp
编译
1 | git clone https://github.com/ggerganov/llama.cpp |
运行
使用taskset -c 1限制单核运行
ggml源码梳理
llama.cpp使用ggml算子库,其源码位于llama.cpp/ggml。
以下说明基于checkout fa42aa6d8902cc4eaf31866b3b3b7b61b69da930
基本说明
ggml算子库整体使用C风格编写,使用封装了数个函数指针的结构体实现多态。
文件说明
ggml.h包含了供外部其他源文件调用的API
类型说明
算子相关类型
struct ggml_tensor表示一个张量。在ggml中,张量是“懒计算”的,因此,此结构中还储存着源张量、运算类型等信息。此结构中包含数个“源张量”的指针以及运算类型信息,而“源张量”中可能也包含着其他张量的指针,这就形成了“计算图”。
struct ggml_backend_buffer描述一个计算后端,其中包含着计算后端相关的数个函数指针。
struct ggml_context表示计算的上下文,其中包含着计算数据的指针。
实现相关类型
struct ggml_backend_i包含计算后端相关的函数指针,张量的据具体运算在其中定义的函数指针的实现里实现
流程说明
初始化
- 调用
ggml_backend_cpu_init()函数,返回一个ggml_backend_t对象- 根据需要调用
ggml_backend_***_init()函数,可选CPU、CUDA、Vulkan等后端 - 返回的
ggml_backend_t对象中包含后端设备进行计算所需的函数指针 - 这一部分目前并不是多态的,应根据需要直接调用对应的
ggml_backend_***_init()函数
- 根据需要调用
计算流程
我们以算子GGML_OP_ADD为例梳理执行流程。
算子
GGML_OP_ADD对应ggml.h:861函数1
2
3
4GGML_API struct ggml_tensor * ggml_add(
struct ggml_context * ctx,
struct ggml_tensor * a,
struct ggml_tensor * b);ggml_add函数内调用ggml_add_impl函数,此函数返回一个新的struct ggml_tensor *对象指针,其中包含所有源ggml_tensor的指针以及运算类型信息。此函数并不进行实际的计算,只是对“计算图”做了延伸,并返回了新的计算图的根结点。