在 ASUS ProArt P16 上安装 Arch Linux ARM 以本地运行 Qwen 推理
Putting Linux on my RTX Spark laptop because I don't have a Microsoft account
Arch Linux 包维护者 pfeifferj 在 128GB RAM、6,144 CUDA 核心的 ASUS ProArt P16 上跑通 Arch Linux ARM,让系统与 CUDA 共用 116.0 GiB 统一内存池。
作者在 ASUS ProArt P16 上跑通 Arch Linux ARM 并实测本地 Qwen 推理,给出统一内存池带来的显存差异和端侧部署的可复用路径。
简短结论 —— 微软坏坏。Arch Linux 在 7-Zip 中与 Windows 表现持平,并向操作系统和 CUDA 报告相同的 116.0 GiB 内存池。我最初的启动盘设置和补丁在 这里。这台机器是 ASUS ProArt P16 H7607BA-SE033W:配置 128 GB 内存、6,144 个 CUDA 核心和 2 TB 固态硬盘。

当传言开始流传,说有一款笔记本电脑的 GPU 可以访问超过 100 GiB 内存时,我开始思考能用它构建些什么,以及可以用多长时间来折腾各种优化。我非常支持开放权重模型。能够在本地运行东西,并在笔记本上玩玩 RL、量化和微调,那就太爽了。我已经在 Hugging Face 上发布了我自己的 GGUF 量化模型,过去一个月下载量超过 16 万次。
所以当我发现 只支持 Windows 的官方说明时,心情就不那么美丽了。讨厌 Windows 的理由多得很。我的理由包括安装时对隐私做出的让步,多年等待微软让人们再次把任务栏放到屏幕侧面,以及广告。最后一个链接是真实 Windows 推广内容的拼贴画,由 Pureinfotech 提供。你应该懂。我能一直说下去,所以我还是回到正题。
Arch 是我偏好的发行版,我是 Arch 团队的软件包维护者。我已经把它装到了 IBM 大型机上(我的 FOSDEM 幻灯片),所以它自然会成为我这里的起点。这个构建使用了 Arch Linux ARM,它是独立的项目,将 Arch 软件包移植到 ARM,并在此基础上添加了硬件支持。
NVIDIA 一直在为 Ubuntu 做内核工作,这给了我一个起点。我将其整合进来,修复了获得控制台所需的 ACPI 覆盖分配和 framebuffer 映射,并从笔记本自身的表中推导出了 ACPI 覆盖(感谢 astra <3)。NVIDIA 驱动和 ASUS 扬声器固件来自互联网上的官方渠道(请别起诉我,电脑公司们)。键盘支持需要一个打过补丁的 hid-asus,而音频也需要它自己的机器驱动。
我把这个组合到一张可启动的 U 盘中,并扩展了上游 Archinstall 4.5 来安装硬件支持。仓库里有构建脚本和补丁,包括如何本地转储你自己的 ACPI 表以及从 ASUS 驱动包中提取扬声器固件的步骤。我这台运行固件 H7607BA.300。
构建输入已经按哈希锁定。我周末整理出来的硬件软件包都使用我的 Arch Linux Package Maintainer 密钥签名,ACPI 覆盖则来自笔记本自身。
显示器以 3840 × 2400、120 Hz 运行,我使用 NetworkManager、PipeWire,以及带 NVIDIA CDI 的无 root 模式 Podman。安装器用 IgnorePkg 锁定内核、NVIDIA、电源管理和固件软件包,而普通软件包则继续从 Arch Linux ARM 持续更新。
CPU 性能
我于 10 月 19 日在原生 Arch Linux ARM 上运行了测试套件,使用的是内核 7.0.0-1022-nvidia 和 NVIDIA 驱动 615.78.08。笔记本接通电源,并选择了性能模式(performance profile)。在 CPU 对比方面,我使用了已发布的 Windows 测试结果。
CPU 测试是原生 ARM64 7-Zip 26.04,使用固定的 32 MiB 字典。我在每个线程数下都跑了一次热身和三组正式测试,然后取中位数:
| 线程数 | 压缩 (MiB/s) | 解压缩 (MiB/s) |
|---|---|---|
| 1 | 6.18 | 118.26 |
| 20 | 141.77 | 1,629.60 |
StorageReview 测试了一台搭载同款 20 核 N1X、运行原生 Windows ARM64 二进制的 128 GB HP OmniBook Ultra 16。他们报告的是 GIPS 单位的 7-Zip 评分,所以我把原始日志里的 MIPS 评分除以 1,000 来对齐。数值越高越好。
| 7-Zip 工作负载 | 我的 ProArt,Linux(GIPS) | HP OmniBook,Windows(GIPS) | 差距 |
|---|---|---|---|
| 单线程压缩 | 7.221 | 7.31 | −1.2% |
| 单线程解压缩 | 10.779 | 10.87 | −0.8% |
| 20 线程压缩 | 165.754 | 157.9 | +5.0% |
| 20 线程解压缩 | 148.471 | 144.5 | +2.7% |
单线程基本持平。20 线程全开时,我的 Linux 方案在压缩上领先约 5%,解压缩上领先 3%。HP 的评测没有标明 7-Zip 版本和字典大小,所以这些百分比比较的是两台笔记本的设置。
ComputerBase 也测试了一台搭载 20 核 N1X 的 ProArt P16。换算成 GIPS 后,它的 Windows 7-Zip 分数为 155.774;我三次运行的中位总数为 157.084。他们的结果落在我三次运行的 155.759 到 157.193 GIPS 范围内。他们测试的是 64 GB 配置,运行 7-Zip 26.00,图表里也没给出字典大小。
内存划分
内存才是更大的优势所在。我的 Linux 运行报告 116.0 GiB 同时作为系统内存和 CUDA 总容量,来自同一块物理内存池。Windows 把内存划分为专用 GPU、共享和仅 CPU 三个区域。CPU 工作负载无法使用专用 GPU 区域,GPU 分配也无法使用仅 CPU 区域。
Windows 的 NVIDIA 应用允许你更改专用预留并重启;Frandroid 的 128 GB ProArt P16 达到了 96 GiB。CUDA 还可进一步通过从共享内存分配来扩展,但受限于 Windows 的内存预算。
在 91 GiB 专用预留下,Frandroid 的 Windows 设置报告的 CUDA 总量为 109.7 GiB(含共享内存)。我的 Linux 设置报告为 116.0 GiB,多出约 6.3 GiB。我看重的是能让这块大内存也用于 CPU 工作,而不需要在不同工作负载之间来回拖动预留滑块并重启。
本地运行 Qwen
我在原生 ARM64 容器中,通过带有 B12X CUDA 内核的 vLLM 运行了 NVIDIA 的 Qwen3.8-Flash-Next-FP4-Local 检查点,使用混合量化和 FP8 KV 缓存。这次运行我关闭了思考模式。
加载模型前,Linux 报告可用内存 110.9 GiB。vLLM 记录模型加载占用 68.2 GiB,并为 KV 缓存另外分配了 21.1 GiB。在一台笔记本上,模型加 KV 缓存的分配接近 90 GiB。
模型加载和编译在首个请求到来前耗时约 16 分钟。下文计时从预热完成后开始。PLE 嵌入表由磁盘支撑,受益于温热的页面缓存;其他组件使用 CPU 卸载。CUDA 负责推理,模型部分超出 GPU 内存。
我让 Qwen 审查两个有缺陷的 Python 辅助函数,在一份包含一条失败操作的长事件日志中定位该操作,并把一条付款说明转换为 JSON。每个任务在预热后运行三次,并以已知答案进行核对。我想知道需要等多久,以及它是否返回了正确的字段。
| 任务 | 输入 tokens | 首个 token,中位(秒) | 完整响应,中位(秒) | 通过检查项 |
|---|---|---|---|---|
| Python 代码审查 | 208 | 0.316 | 4.008 | 3/3 |
| 在 128 条记录的事件日志中定位失败 | 9,775 | 4.532 | 5.768 | 3/3 |
| 付款说明抽取 | 87 | 0.256 | 2.035 | 3/3 |
事件任务读取了近 10,000 个 token,在 6 秒内返回了正确的请求、原因和后续动作。其回答仅有 39 个 token,折算下来整个请求约 6.8 tokens/s。大部分等待时间花在了处理提示上,所以对这个任务来说,响应时间比 tokens/s 数值更有参考意义。
对于代码审查,我将生成速度估算为(output tokens − 1) / (response time − time to first token),两次计时都以秒为单位。这包含流的开销。Frandroid 在其 Windows ProArt 上运行了 Qwen3.8-Flash-Next 编码任务:
| 系统 | 量化与运行时 | 生成速度(tokens/s) |
|---|---|---|
| 我的 ProArt P16,Linux | FP4-Local, vLLM B12X | 30.9(3 次中位数) |
| Frandroid 的 ProArt P16,Windows | UD-IQ4_XS, llama.cpp | 29.4 and 31.4 |
两套 ProArt 配置速度都约为 30 tokens/s。推理方面,Frandroid 使用了 85 GiB 的专用预留,上下文限制为 262,144 tokens;我的上下文限制为 32,768 tokens。提示词、量化、运行时以及计时方法均不同。这里比较的是两套可运行的配置,并不能孤立出操作系统的影响。
我还一次性发送了四个代码审查请求。中位数批次耗时 5.314 秒,四个请求合计生成 86.6 输出 tokens/s。该速率包含提示词处理与响应开销。三个批次共计 12 个回答全部通过检查。
随后我让它在三个任务之间循环,一次一个请求,持续运行十分钟。它完成了 150 个请求,每个任务各 50 个,全部回答都通过了检查。代码审查的中位响应时间为 4.036 秒,日志任务为 5.921 秒,抽取任务为 2.046 秒。对比每个任务的前十次和后十次重复,中位响应时间增长不到 1.6%。
全部 171 个测得的响应均通过检查。这是三个提示词在确定性解码下重复执行的结果;代码审查检查会验证回归输出。我保留了每一个回答和原始事件流,并将它们与摘要进行了核对。
来源:Hacker News · josie.lol