上文说到, 天下苦 N 卡久矣, 直接使用 CPU 推理又太慢. 那么, 在没有 N 卡的情况下, 本地运行 AI (神经网络) 大模型, 能够达到怎样的速度 ?
同志们好, 欢迎来到 胖喵穷人实验室 ! 这里专注于 低成本, 低难度, 低风险 的 “三低” 小实验.
胖喵穷人实验室 (PM-PLab-E)
正式名称: 紫腹巨蚊 (Toxorhynchites gravelyi) 系列
穷人 (Poor people) 实验室
这里是 穷人小水滴, 专注于 穷人友好型 低成本技术. (本文为 56 号作品. )
注意: 本文的测试结果仅供参考, 重点是测量的方法和过程. 硬件配置, 软件/驱动的版本, 运行的模型, 设置的参数, 甚至环境温度等很多因素, 都可能会影响实际运行速度.
相关文章:
- 《编译运行 llama.cpp (vulkan, Intel GPU SYCL)》 https://blog.csdn.net/secext2022/article/details/141473795
- 《QEMU/KVM 虚拟机显卡透传 (vfio-pci)》 https://blog.csdn.net/secext2022/article/details/141473097
- 《自制神之嘴: fish-speech 容器镜像 (文本转语音 AI 大模型)》 https://blog.csdn.net/secext2022/article/details/141224704
目录
- 1 背景知识和测量方法
- 1.1 模型量化
- 1.2 模型选择 (llama2-7B.q4, qwen2-7B.q8, gguf)
- 1.3 llama.cpp 软件版本 (b3617, avx2, vulkan, SYCL)
- 2 软硬件配置
- 2.1 笔记本 (4 号 PC) i5-6200U (ArchLinux)
- 2.2 服务器 (5 号) e5-2650v3 (Fedora CoreOS)
- 2.3 台式机 (6 号 PC) r5-5600g (ArchLinux)
- 2.4 虚拟机 (6 号) A770 (16GB) Ubuntu 22.04
- 3 详细测量过程
- 3.1 CPU (i5-6200U, 2C/4T/2.8GHz) x86_64 AVX2
- 3.2 CPU (E5-2650v3, 10C/10T/3.0GHz) x86_64 AVX2
- 3.3 CPU (r5-5600g, 6C/12T/4.4GHz) x86_64 AVX2
- 3.4 iGPU (Intel HD520, i5-6200U) vulkan
- 3.5 iGPU (AMD Radeon Vega 7, r5-5600g) vulkan
- 3.6 dGPU (A770) vulkan
- 3.7 dGPU (A770) SYCL
- 3.8 Windows (CPU) r5-5600g AVX2
- 3.9 Windows (GPU) A770 vulkan
- 4 结果对比
- 4.1 CPU 运行
- 4.2 iGPU 运行
- 4.3 dGPU (A770) 运行
- 4.4 Linux 和 Windows 对比
- 5 总结与展望
1 背景知识和测量方法
基于 神经网络 (Neural Network) 的 AI 模型, 其底层的运算主要是 乘法 和 加法 (矩阵相乘). 神经网络通常分为多层 (深度神经网络), 每层包含许多 “神经元” (感知机). 通常神经网络的各层从前向后依次连接 (前馈神经网络), 而同一层的神经元之间没有直接连接.
所以, 神经网络的每一层需要按先后顺序计算, 算完一层才能算下一层. 但是同一层内部却可以大规模 并行运算, 加快速度.
所谓 大模型, 顾名思义, 就是模型很大. 比如 7B 模型有 70 亿个参数 (B
表示 10 亿), 目前最先进的大模型参数超过千亿 (比如 400B 模型). 参数 是一个数字 (权重), 表示两个神经元之间连接的强弱, 比如 0.0
表示连接很弱, 1.0
表示连接很强. 大模型的层数很多, 每层之中的神经元很多, 神经元之间的连接, 也就是参数, 自然也很多.
模型大, 参数多, 运算量也很大, 如何计算是个很大的困难.
CPU 的工作方式是串行计算, 也就是一个接一个的计算, 所以速度比较慢. 即使是多核 CPU, 同时能够进行的计算也不是很多, 比如 8 核 16 线程, 可以简单理解为同时只能进行 16 个计算.
GPU (显卡) 的核心就很多了, 比如几百个甚至几千个计算核心 (流处理器 SM), 很适合大规模并行计算. 所以 N 卡 (CUDA) 才会那么厉害, 在 AI 大模型时代一骑绝尘.
不过 CPU 并没有坐以待毙, 这边有 SIMD (单指令多数据) 技术. 虽然 CPU 是一条接一条执行指令的, 这个祖宗之法不可变, 但是如果一条指令能够同时计算多个数据, 那么速度不就快了 ? 比如 x86_64 CPU 的 avx 指令集, 能够同时计算 128bit 数据, avx2 指令集可以计算 256bit, 最新的 avx512 指令集则增加到了 512bit (宽度).
除了 x86_64, 别的 CPU 也有 SIMD 技术, 比如 ARM 的 NEON 指令集, RISC-V 的 V
扩展 (向量指令集). 其中 RISC-V 的向量指令, 采用动态宽度设计, 不像 x86_64 那样每次增加宽度都要推出新的指令集, RISC-V 的指令可以直接适应新的更强大的硬件, 所以未来可能会很好的发展.
神经网络在模型搭建好 (设计好模型结构) 之后, 主要分为 训练 (training) 和 推理 (inference) 这两个阶段. 训练可以简单理解为制造成品模型的过程, 而推理是实际使用这个模型.
模型设计好之后, 这个模型有多少层, 每层有多少神经元, 神经元之间如何连接, 这些已经确定了, 也就是一共有多少参数确定了, 比如模型有 7B 参数. 但是每个参数的具体数值还是不知道的 (也就是比如有 70 亿个未知数).
这么多参数, 人工设定每一个参数的具体数值显然是不可能的. 训练模型就是 自动 获得参数的具体数值的过程. 通过给模型投喂大量数据 (训练集), 使用损失函数, 反向传播, 梯度下降 等方法, 一步一步逐渐调整模型的参数, 最终让模型能够得到一个比较高的准确率. 这个过程又被称为 “机器学习”.
对于固定大小的模型, 投喂的训练数据越多, 训练的时间 (步数) 越长, 模型的效果越好. 如果训练数据太少, 很可能只能获得一个智障.
训练大模型并不是普通人能够玩的起的: 首先需要准备很多 TB 的训练数据, 除了收集数据, 还要对数据进行清洗, 整理, 标注等. 然后需要大规模硬件, 比如成千上万张显卡, 消耗很多很多电能, 才能完成模型的训练. 所以训练大模型超级费钱, 比如训练一个模型需要千万甚至上亿美元.
模型训练好之后, 使用起来就容易多了. 如果模型不是特别大, 只需要一张显卡即可运行. 对于更小的模型, 消费级硬件, 甚至 CPU 都可以运行.
这也是普通人更容易参与的事情: 在本地运行 AI 大模型 (推理).
为什么非要在本地运行 ? 直接使用在线的服务不好嘛 ? 嗯, 这个问题, 就和有了网盘, 为什么还要买硬盘, 组建 NAS 存储服务器, 差不多.
- (1) 成本问题. 与在线服务相比, 购买硬件 (特别是二手硬件) 在本地运行, 有些情况下更便宜.
- (2) 自主可控和靠谱程度. 在线服务说关就关, 存储的文件说丢就丢. 在本地运行的话, 什么时候关, 自己说了算.
- (3) 模型定制及个性化选项. 本地运行, 有更丰富的模型可供选择, 甚至还可以考虑模型 微调 (fine tuning) 等高级玩法.
1.1 模型量化
训练时, 模型的参数通常用 f32
(32 位浮点数) 或 f16
(16 位浮点数) 等高精度格式存储. 但是这导致模型占用很大的存储空间, 比如 7B 模型 f32 存储大约 28GB, f16 存储大约 14GB, 高精度数字也需要消耗更多的计算资源.
所以就有了模型量化技术, 通过降低一部分参数的精度, 减小存储空间占用, 降低计算量. 比如 8bit 量化, 一个参数只用 8 位二进制存储, 类似的还有 4bit, 2bit 甚至 1bit.
模型量化因为降低了参数的精度, 会导致模型变差 (准确度降低), 但是合理的量化不会导致模型变差太多, 仍然可以正常使用. 同时因为量化显著降低了存储大小, 加快了运行速度, 使得消费级的硬件也可以使用. 所以模型量化还是很香的.
1.2 模型选择 (llama2-7B.q4, qwen2-7B.q8, gguf)
此处选择了两个 AI 语言模型 (生成文本), 从这里下载: https://hf-mirror.com/TheBloke/Llama-2-7B-GGUF https://hf-mirror.com/Qwen/Qwen2-7B-Instruct-GGUF
下载的模型文件:
> ls -l
-r--r--r-- 1 s2 s2 4081004224 8月19日 13:20 llama-2-7b.Q4_K_M.gguf
-r--r--r-- 1 s2 s2 8098522912 8月20日 09:52 qwen2-7b-instruct-q8_0.gguf
其中 gguf
是 llama.cpp
推出的模型格式, 只需要一个文件即可运行, 很方便.
-
llama-2-7b.Q4_K_M.gguf
: 这个是 llama-2, 国外开源的英文模型. 参数约 7B, 采用 4bit 量化. 模型文件大小约 4GB, 运行 (A770) 占用显存约 7GB.这个是比较小的模型, 运行起来比较容易, 同时模型质量也不会太差.
-
qwen2-7b-instruct-q8_0.gguf
: 这个是千问 2, 国产开源的模型, 中文能力比较好. 参数约 7B, 采用 8bit 量化. 模型文件大小约 8GB, 运行 (A770) 占用显存约 12GB.这个模型相对就比较大了, 更大的模型就难以运行了. 因为如果模型继续增大, 占用的显存很可能会超过 16GB, 此时就需要很贵的高端显卡 (比如 4090) 才可以运行.
1.3 llama.cpp 软件版本 (b3617, avx2, vulkan, SYCL)
llama.cpp 是一个用来运行 (推理) AI 大语言模型的开源软件, 支持多种后端:
-
CPU 后端, 可以使用 SIMD 指令集进行加速. 比如 x86_64 CPU 的 avx2 指令集.
-
GPU 通用后端. 比如 vulkan, 通过使用 计算着色器 (compute shader), 支持很多种不同的显卡.
-
GPU 专用后端. 这种只支持一种显卡, 进行专门的优化. 比如 N 卡的 CUDA, A 卡的 ROCm, Intel 的 SYCL 等.
本文使用 SYCL 后端在 A770 显卡运行.
本文使用的版本是 b3617
, 从这里下载: https://github.com/ggerganov/llama.cpp/releases
其中用于 GNU/Linux 系统的 vulkan 后端和 SYCL 后端没有官方编译的版本, 所以是自己编译的, 详见文章 《编译运行 llama.cpp (vulkan, Intel GPU SYCL)》.
其中编译 SYCL 后端的 Dockerfile
如下:
# llama.cpp SYCL
FROM ubuntu-intel-base as build
WORKDIR /app
COPY llama.cpp-b3617 .
RUN . /opt/intel/oneapi/setvars.sh && \
cmake -B build -DGGML_SYCL=ON -DCMAKE_C_COMPILER=icx -DCMAKE_CXX_COMPILER=icpx -DBUILD_SHARED_LIBS=OFF && \
cmake --build build --config Release --target llama-cli
# 阶段 2
FROM ubuntu-intel-base as runtime
COPY --from=build /app/build/bin/llama-cli /usr/bin/llama-cli
CMD /bin/bash
这是编译 f32
版本的. 编译 f16
SYCL 版本使用如下命令:
cmake -B build -DGGML_SYCL=ON -DGGML_SYCL_F16=ON -DCMAKE_C_COMPILER=icx -DCMAKE_CXX_COMPILER=icpx -DBUILD_SHARED_LIBS=OFF
注意多了 -DGGML_SYCL_F16=ON
参数.
2 软硬件配置
为了使测量结果更容易复现, 本章节详细描述运行设备的软硬件配置情况.
2.1 笔记本 (4 号 PC) i5-6200U (ArchLinux)
CPU: Intel Core i5-6200U
> lscpu
架构: x86_64
CPU 运行模式: 32-bit, 64-bit
Address sizes: 39 bits physical, 48 bits virtual
字节序: Little Endian
CPU: 4
在线 CPU 列表: 0-3
厂商 ID: GenuineIntel
型号名称: Intel(R) Core(TM) i5-6200U CPU @ 2.30GHz
CPU 系列: 6
型号: 78
每个核的线程数: 2
每个座的核数: 2
座: 1
步进: 3
CPU(s) scaling MHz: 30%
CPU 最大 MHz: 2800.0000
CPU 最小 MHz: 400.0000
BogoMIPS: 4800.00
标记: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge m
ca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 s
s ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc
art arch_perfmon pebs bts rep_good nopl xtopology nons
top_tsc cpuid aperfmperf pni pclmulqdq dtes64 monitor
ds_cpl vmx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid
sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer a
es xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpu
id_fault epb pti ssbd ibrs ibpb stibp tpr_shadow flexp
riority ept vpid ept_ad fsgsbase tsc_adjust bmi1 avx2
smep bmi2 erms invpcid mpx rdseed adx smap clflushopt
intel_pt xsaveopt xsavec xgetbv1 xsaves dtherm ida ara
t pln pts hwp hwp_notify hwp_act_window hwp_epp vnmi m
d_clear flush_l1d arch_capabilities
Virtualization features:
虚拟化: VT-x
Caches (sum of all):
L1d: 64 KiB (2 instances)
L1i: 64 KiB (2 instances)
L2: 512 KiB (2 instances)
L3: 3 MiB (1 instance)
NUMA:
NUMA 节点: 1
NUMA 节点0 CPU: 0-3
Vulnerabilities:
Gather data sampling: Vulnerable: No microcode
Itlb multihit: KVM: Mitigation: VMX disabled
L1tf: Mitigation; PTE Inversion; VMX conditional cache flush
es, SMT vulnerable
Mds: Mitigation; Clear CPU buffers; SMT vulnerable
Meltdown: Mitigation; PTI
Mmio stale data: Mitigation; Clear CPU buffers; SMT vulnerable
Reg file data sampling: Not affected
Retbleed: Mitigation; IBRS
Spec rstack overflow: Not affected
Spec store bypass: Mitigation; Speculative Store Bypass disabled via prct
l
Spectre v1: Mitigation; usercopy/swapgs barriers and __user pointe
r sanitization
Spectre v2: Mitigation; IBRS; IBPB conditional; STIBP conditional;
RSB filling; PBRSB-eIBRS Not affected; BHI Not affect
ed
Srbds: Mitigation; Microcode
Tsx async abort: Not affected
内存: DDR3L-1600MHz 16GB (双通道, 8GB x2)
集成显卡: Skylake GT2 [HD Graphics 520]
操作系统: ArchLinux
> uname -a
Linux S2L 6.10.6-zen1-1-zen #1 ZEN SMP PREEMPT_DYNAMIC Mon, 19 Aug 2024 17:02:05 +0000 x86_64 GNU/Linux
2.2 服务器 (5 号) e5-2650v3 (Fedora CoreOS)
CPU: Intel Xeon E5-2650v3
fc-test@MiWiFi-RA74-srv:~$ lscpu
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Address sizes: 46 bits physical, 48 bits virtual
Byte Order: Little Endian
CPU(s): 20
On-line CPU(s) list: 0-9
Off-line CPU(s) list: 10-19
Vendor ID: GenuineIntel
Model name: Intel(R) Xeon(R) CPU E5-2650 v3 @ 2.30GHz
CPU family: 6
Model: 63
Thread(s) per core: 1
Core(s) per socket: 10
Socket(s): 1
Stepping: 2
CPU(s) scaling MHz: 48%
CPU max MHz: 3000.0000
CPU min MHz: 0.0000
BogoMIPS: 4589.44
Flags: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge m
ca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 s
s ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc
arch_perfmon pebs bts rep_good nopl xtopology nonstop_
tsc cpuid aperfmperf pni pclmulqdq dtes64 monitor ds_c
pl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid
dca sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_tim
er aes xsave avx f16c rdrand lahf_lm abm cpuid_fault e
pb pti intel_ppin ssbd ibrs ibpb stibp tpr_shadow flex
priority ept vpid ept_ad fsgsbase tsc_adjust bmi1 avx2
smep bmi2 erms invpcid cqm xsaveopt cqm_llc cqm_occup
_llc dtherm ida arat pln pts vnmi md_clear flush_l1d
Virtualization features:
Virtualization: VT-x
Caches (sum of all):
L1d: 320 KiB (10 instances)
L1i: 320 KiB (10 instances)
L2: 2.5 MiB (10 instances)
L3: 25 MiB (1 instance)
NUMA:
NUMA node(s): 1
NUMA node0 CPU(s): 0-9
Vulnerabilities:
Gather data sampling: Not affected
Itlb multihit: KVM: Mitigation: VMX disabled
L1tf: Mitigation; PTE Inversion; VMX conditional cache flush
es, SMT disabled
Mds: Mitigation; Clear CPU buffers; SMT disabled
Meltdown: Mitigation; PTI
Mmio stale data: Mitigation; Clear CPU buffers; SMT disabled
Reg file data sampling: Not affected
Retbleed: Not affected
Spec rstack overflow: Not affected
Spec store bypass: Mitigation; Speculative Store Bypass disabled via prct
l
Spectre v1: Mitigation; usercopy/swapgs barriers and __user pointe
r sanitization
Spectre v2: Mitigation; Retpolines; IBPB conditional; IBRS_FW; RSB
filling; PBRSB-eIBRS Not affected; BHI Not affected
Srbds: Not affected
Tsx async abort: Not affected
内存: DDR4-2133MHz REG ECC 32GB (四通道, 8GB x4)
操作系统: Fedora CoreOS 40
fc-test@MiWiFi-RA74-srv:~$ uname -a
Linux MiWiFi-RA74-srv 6.9.11-200.fc40.x86_64 #1 SMP PREEMPT_DYNAMIC Thu Jul 25 18:17:34 UTC 2024 x86_64 GNU/Linux
fc-test@MiWiFi-RA74-srv:~$ rpm-ostree status
State: idle
warning: Failed to query journal: couldn't find current boot in journal
AutomaticUpdatesDriver: Zincati
DriverState: active; periodically polling for updates (last checked Sat 2024-08-24 10:27:49 UTC)
Deployments:
● fedora:fedora/x86_64/coreos/stable
Version: 40.20240728.3.0 (2024-08-12T20:22:19Z)
BaseCommit: 2098f40910d5d7c0171a8f7173d81cb070f4047e1e81d9d5228d5d62e24fe722
GPGSignature: Valid signature by 115DF9AEF857853EE8445D0A0727707EA15B79CC
LayeredPackages: smartmontools snapper systemd-networkd
fc-test@MiWiFi-RA74-srv:~$ free -h
total used free shared buff/cache available
Mem: 31Gi 1.3Gi 2.3Gi 9.8Mi 28Gi 29Gi
Swap: 0B 0B 0B
2.3 台式机 (6 号 PC) r5-5600g (ArchLinux)
CPU: AMD Ryzen 5 5600G with Radeon Graphics
> lscpu
架构: x86_64
CPU 运行模式: 32-bit, 64-bit
Address sizes: 48 bits physical, 48 bits virtual
字节序: Little Endian
CPU: 12
在线 CPU 列表: 0-11
厂商 ID: AuthenticAMD
型号名称: AMD Ryzen 5 5600G with Radeon Graphics
CPU 系列: 25
型号: 80
每个核的线程数: 2
每个座的核数: 6
座: 1
步进: 0
CPU(s) scaling MHz: 51%
CPU 最大 MHz: 4464.0000
CPU 最小 MHz: 400.0000
BogoMIPS: 7785.61
标记: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge m
ca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall
nx mmxext fxsr_opt pdpe1gb rdtscp lm constant_tsc rep
_good nopl xtopology nonstop_tsc cpuid extd_apicid ape
rfmperf rapl pni pclmulqdq monitor ssse3 fma cx16 sse4
_1 sse4_2 x2apic movbe popcnt aes xsave avx f16c rdran
d lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a
misalignsse 3dnowprefetch osvw ibs skinit wdt tce topo
ext perfctr_core perfctr_nb bpext perfctr_llc mwaitx c
pb cat_l3 cdp_l3 hw_pstate ssbd mba ibrs ibpb stibp vm
mcall fsgsbase bmi1 avx2 smep bmi2 erms invpcid cqm rd
t_a rdseed adx smap clflushopt clwb sha_ni xsaveopt xs
avec xgetbv1 xsaves cqm_llc cqm_occup_llc cqm_mbm_tota
l cqm_mbm_local user_shstk clzero irperf xsaveerptr rd
pru wbnoinvd cppc arat npt lbrv svm_lock nrip_save tsc
_scale vmcb_clean flushbyasid decodeassists pausefilte
r pfthreshold avic v_vmsave_vmload vgif v_spec_ctrl um
ip pku ospke vaes vpclmulqdq rdpid overflow_recov succ
or smca fsrm debug_swap
Virtualization features:
虚拟化: AMD-V
Caches (sum of all):
L1d: 192 KiB (6 instances)
L1i: 192 KiB (6 instances)
L2: 3 MiB (6 instances)
L3: 16 MiB (1 instance)
NUMA:
NUMA 节点: 1
NUMA 节点0 CPU: 0-11
Vulnerabilities:
Gather data sampling: Not affected
Itlb multihit: Not affected
L1tf: Not affected
Mds: Not affected
Meltdown: Not affected
Mmio stale data: Not affected
Reg file data sampling: Not affected
Retbleed: Not affected
Spec rstack overflow: Vulnerable: Safe RET, no microcode
Spec store bypass: Mitigation; Speculative Store Bypass disabled via prct
l
Spectre v1: Mitigation; usercopy/swapgs barriers and __user pointe
r sanitization
Spectre v2: Mitigation; Retpolines; IBPB conditional; IBRS_FW; STI
BP always-on; RSB filling; PBRSB-eIBRS Not affected; B
HI Not affected
Srbds: Not affected
Tsx async abort: Not affected
内存: DDR4-3200MHz 32GB (双通道, 16GB x2)
集成显卡: AMD Radeon Graphics (RADV RENOIR)
操作系统: ArchLinux
> uname -a
Linux a2 6.10.6-zen1-1-zen #1 ZEN SMP PREEMPT_DYNAMIC Mon, 19 Aug 2024 17:02:05 +0000 x86_64 GNU/Linux
2.4 虚拟机 (6 号) A770 (16GB) Ubuntu 22.04
详见文章 《QEMU/KVM 虚拟机显卡透传 (vfio-pci)》.
显卡: Intel Arc A770 (16GB)
a2@a2s:~$ clinfo -l
Platform #0: Intel(R) OpenCL Graphics
`-- Device #0: Intel(R) Arc(TM) A770 Graphics
操作系统: Ubuntu 22.04
> ssh u2
a2@a2s:~$ uname -a
Linux a2s 6.8.0-40-generic #40~22.04.3-Ubuntu SMP PREEMPT_DYNAMIC Tue Jul 30 17:30:19 UTC 2 x86_64 x86_64 x86_64 GNU/Linux
3 详细测量过程
使用相同版本的 llama.cpp (b3617
), 相同的模型文件, 在不同的设备上运行.
使用相同的输入 (提示词):
-p "hello, this is a very very long story"
因为生成长度会影响运行速度, 所以使用 100
, 200
, 500
, 1000
的生成长度, 用来覆盖常见的情况.
本章节比较长, 读者可以考虑跳过这一章节.
由于本文太长, 分开发布, 方便阅读. 分篇链接: https://blog.csdn.net/secext2022/article/details/141563727
4 结果对比
上面的测量结果汇总如下表:
数据单位: token/s
注意 token 并不相当于字符. 一个 token 有时候对应一个字符 (数字, 标点, 空格 等), 有时候对应一个单词, 有时候对应半个单词.
4.1 CPU 运行
这 3 个都是 x86_64 CPU, 都使用 avx2 指令集进行 SIMD 加速.
弱鸡老旧笔记本 CPU (i5-6200U, 2 核 4 线程) 确实很慢, e5-2650v3 (10 核 10 线程) 和 r5-5600g (6 核 12 线程) 打的难舍难分. 对于 7B.q4 模型 r5-5600g 更快一些, 对于 7B.q8 模型 e5-2650v3 更快一些.
4.2 iGPU 运行
这是集成显卡 (核显), 都使用 vulkan 运行.
弱鸡核显, 速度甚至比自己隔壁的 CPU 更慢, 基本没有实用价值.
4.3 dGPU (A770) 运行
这是 A770 (16GB) 显卡, 分别以 vulkan, SYCL (f32), SYCL (f16) 运行. 左侧是 CPU (avx2) 的对比.
A770 的速度大约可以达到 CPU 的 2 ~ 3 倍. 对于 7B.q4 模型 SYCL (f32) 更快, 对于 7B.q8 模型 vulkan 更快.
SYCL 的 f32 和 f16 区别不大, 通常 f32 更快一点.
4.4 Linux 和 Windows 对比
这是 CPU (r5-5600g, avx2) 和 dGPU (A770, vulkan) 的速度对比, 标记 “Win” 的是 Windows 系统, 没有标记的是 GNU/Linux 系统.
CPU 运行速度基本没有区别, vulkan 运行速度 Linux 更快一些.
本章节图表绘制软件: LibreOffice Calc.
5 总结与展望
通过 llama.cpp
运行 7B.q4 (4bit 量化), 7B.q8 (8bit 量化) 模型, 测量了生成式 AI 语言模型在多种硬件上的运行 (推理) 速度.
根据上述测量结果, 可以得到以下初步结论:
-
(1) 显存 (内存) 大就是正义 ! 大, 就是正义 !!
限制能够运行的模型规模的最主要因素, 就是显存的大小. 目前的大部分显卡 (除了高端的比如 4090), 显存都不超过 16GB.
即使显卡计算能力弱鸡, 如果显存够大, 那么也能慢慢运行大模型. 但是如果显存不够, 那么不好意思, 基本上就是无法运行 ! 所以, 在条件允许的情况下, 优先选显存更大的显卡.
-
(2) 生成长度越长, 推理速度越慢. 从上面的测量数据可以发现这个规律. 但是随着生成长度的增加, 推理速度下降的幅度很小, 影响不大.
-
(3) 弱鸡核显 (iGPU vulkan) 可能比 CPU (avx2) 更慢. 核显有可能比 CPU 更慢, 这种情况下, 使用核显基本上就没有意义, 直接使用 CPU 是更好的选择.
-
(4) e5 宝刀未老: avx2 运行 AI 模型仍有一战之力.
本文中 e5 的成绩是很惊艳的. 要知道, e5 (v3) 是一颗很古老, 很便宜的 CPU, 在淘宝一颗 e5 可能只要几十元. 但是 e5 却可以达到甚至超过 r5-5600g 的速度, 所以 e5 的性价比应该是很高的.
运行大模型时, 内存带宽可能是瓶颈. e5 作为服务器 CPU, 有多通道内存的优势. 比如本文中 e5 配备 4 通道 DDR4 内存, 这也可能是 e5 成绩好的原因.
本文中没有近几年的新 CPU, 所以只支持 avx2 指令集, 没有最新的 axv512 指令集. 具有 avx512 指令集的新 CPU, 在运行 AI 大模型时应该更有优势.
-
(5) A770 vulkan 不算太慢, 可以日常使用. 本文中 A770 的推理速度可达 20 ~ 30 token/s, 虽然不算很快, 但基本能用了.
-
(6) Linux 和 Windows 的 CPU 性能基本相同. 很好, 这说明两个系统都没有明显的性能方面的问题.
-
(7) Linux 的 vulkan 性能比 Windows 好一些. 这可能和显卡驱动的优化有关, 还需要进一步分析可能的原因.
-
(8) SYCL 性能需要继续努力优化.
vulkan 是通用的 GPU 接口, 支持多种显卡. 而 SYCL 是专用的 GPU 接口, 为 Intel GPU 专门优化, 比如支持 XMX (矩阵乘法加速). SYCL 对于 Intel GPU 的地位, 就类似于 CUDA 对于 N 卡. 所以 SYCL 理应比 vulkan 速度更快, 这才正常.
在运行 7B.q4 模型时, SYCL 确实比 vulkan 快很多. 但是运行 7B.q8 模型时, SYCL 居然反而比 vulkan 更慢 ! 这种速度是不正常的, 肯定是哪里优化的问题. 可能是 llama.cpp 的优化不到位, 也可能是 Intel 显卡驱动的优化不到位. 所以相关团队需要继续努力哟 ~
本文只是简单测量了神经网络模型的推理速度, 还有很多有趣的问题没有探索. 比如运行大模型时, 整机功耗及发热情况, 内存带宽与运行速度的关系等.
llama.cpp 用来加速运行模型的各种方法, 比如模型量化 (8bit, 4bit 等), SIMD (avx2), vulkan (GPU), SYCL (Intel GPU) 等, 也都很值得学习和借鉴.
本文使用 CC-BY-SA 4.0 许可发布.