Arm64 Mac 压片指北

为什么?

可能因为我是抖M吧((

工具

俗话说,工欲善其事必先利其器。。。。。 废话省略

以下将分为这几个部分

  1. vapoursynth 框架
  2. 常用 vapoursynth 插件及脚本
  3. 编码器 (x264, x265)

vapoursynth 的安装与调教

Vaporusynth(以下有可能简称为VS) 是一个开源的frame server。具体定义这里不再赘述。

它有一个积极开发的主分支(目前最新为R70),和由 amusement club 维护的 classic 分支。这两个分支都能很好地完成压片的任务,可以随意选用;这片文章也会同时涉猎两者。

upstream 的安装

在 macos 上安装最新 VS 非常简单,直接使用 brew 包管理器即可。

brew install vapoursynth

然后就可以试着运行 vspipe

vspipe

如果打印出了详细的使用说明,那么恭喜你安装成功了!

classic 分支的安装

相比 upstream, classic 对于旧脚本兼容性更好,且代码较为稳定,可以进行魔改。然而,兼任旧脚本也就意味着牺牲部分新功能,这需要自行斟酌。

安装方式相对较为复杂,不过下面的命令可以基本照抄

cd ~
git clone https://github.com/AmusementClub/vapoursynth-classic
cd ./vapoursynth-classic
brew update
brew install automake llvm
export CC=/opt/homebrew/opt/llvm/bin/clang
export CXX=/opt/homebrew/opt/llvm/bin/clang++
export LDFLAGS="-fuse-ld=lld -L/opt/homebrew/opt/llvm/lib/c++ -Wl,-rpath,/opt/homebrew/opt/llvm/lib/c++"
export PATH=/opt/homebrew/opt/llvm/bin:$PATH
export CPATH=/usr/local/include:$CPATH
export LIBRARY_PATH=/usr/local/lib:$LIBRARY_PATH
pip install -U cython setuptools wheel
echo 'export PYTHONPATH=/usr/local/lib/python3.12/site-packages'  >> ~/.zshrc (这里换成适合自己的,如conda环境等) 注意⚠️ 这会使得 conda 失效,请自行处理;我没有更好的解决方案,还请大佬不惜赐教
source ~/.zshrc

git clone https://bitbucket.org/the-sekrit-twc/zimg.git --depth 1 --recurse-submodules --shallow-submodules
pushd zimg
./autogen.sh
./configure
make -j
sudo make install -j
popd
rm -rf zimg

mv /usr/local/Cellar/libtool /usr/local/Cellar/libtool_1
brew install libtool

echo 'PATH="/opt/homebrew/opt/libtool/libexec/gnubin:$PATH"'  >> ~/.zshrc
source ~/.zshrc

./autogen.sh
./configure
CMAKE_ARGS="-DLLAMA_METAL=on -DCMAKE_OSX_ARCHITECTURES=arm64"
make CFLAGS+="$(pkg-config --cflags lqr-1)" LDFLAGS+="$(pkg-config --libs lqr-1) -L/opt/homebrew/Cellar/liblqr/0.4.3/lib" -j 这里 liblqr 版本换成适合的
sudo make install -j
ARCHFLAGS="-arch arm64" pip install . --compile --no-cache-dir

然后同样运行 vspipe 进行测试,不再赘述

PS. 有勇气的朋友可以尝试我基于 classic 进行少量修改的版本,理论上会有略好的性能。只须将仓库地址换成 https://github.com/yuygfgg/vapoursynth-classic 即可。

vspreview

这是用于预览 VS 脚本的程序。它同样有多个版本。下面列举2个版本,其他版本请按需使用。

JET版

这个版本配合 upstream vapoursynth 使用。

pip install vspreview

Amusement club版

配合 classic 使用。


git clone https://github.com/AkarinVS/vapoursynth-preview

cd vapoursynth-preview

pip install -r requirements.txt

然后把 vspreview 文件夹拷贝到 $PYTHONPATH 下即可。

插件,脚本的安装

插件目录 & 脚本目录

插件目录是放置插件的地方(废话):对于 upstream,它在 /opt/homebrew/lib/vapoursynth; 对于 classic,它在 /usr/local/lib/vapoursynth

(其实上面讲的不准确,不过对于照抄上面命令的人应该够用了,自行修改的应该也有能力搞清楚)

脚本目录则非常简单,就是 $PYTHONPATH

通用的插件安装方式

这部分能让 80% 的插件以 75% 的效率走起来。

  • step1: 找到那个插件的 github 地址,并 clone
  • step2: meson setup build && ninja -C build install classic 用户注意:有时链接器会报错,请确保使用的是和编译 VS 时一样的链接器 (即重新运行上面的一堆 export 命令)
    (构建系统有时可能是 cmake, 具体请参照 readme)
  • step3: 观察输出,解决可能存在的编译问题,输入密码授予安装权限(仅 classic 需要)。少数情况可能会安装错目录,可以自行复制到插件目录。
  • step4: enjoy~

高性能的插件安装方式

这部分能让 99% 的插件以 95% 的效率跑起来。

这部分内容极为复杂,所以只是简略记录一下思路,还请见谅。

simd

绝大多数 VS 插件都只实现了 X86 的 simd 加速;然而,新 Mac 都是基于 Arm 架构的,所以需要将 SSE, AVX 等 x86 指令集转换为 NEON, SVE 等 arm 指令集。这个操作非常机械化,但是同时需要一些经验和 GPT 余额,所以这里简单带过,只列举几个有用的工具。

  1. sse2neon.h

正如它的名字,这是用于将 sse 转换为 neon 的库。使用方法是将 sse 的头文件换成这个。

  1. simde

全称 SIMD Everywhere; 可以将几乎任意一种 SIMD 转换为本机支持的,不过使用上略微繁琐。

除此以外,还需要对 CPUID 等函数进行修改;

注意:sse2neon 只能转换 128bit 的 simd,而最新的 M4 已经支持 SVE512。如果需要最佳性能请始终选择 simde

编译优化

有一部分插件在编写时完全没有考虑非 X86 平台,导致一些跨平台的优化也没有应用。最典型的如编译器优化,这是在一切平台都可以进行的,然而部分插件在编写时只启用了 X86 的优化,导致 Arm 等平台白白流失数十倍的性能。

方法非常简单,修改 meson.build,手动加入相关逻辑(chatgpt 乐意代劳)

例如:

  if host_machine.cpu_family().startswith('x86')
    add_project_arguments('-mfpmath=sse', '-msse2', language : 'cpp') # 没有 Arm 平台相关编译优化
  endif

修改后:

  if host_machine.cpu_family().startswith('x86')
    add_project_arguments('-mfpmath=sse', '-msse2', language : 'cpp')
  elif host_machine.cpu_family().startswith('arm') or host_machine.cpu_family() == 'aarch64'
    add_project_arguments('-O3', '-fno-math-errno', '-fno-trapping-math', language: 'cpp') # 加入了 Arm 平台也适用的通用优化。
  endif

有没有现成的?

还真有。

请到 https://github.com/yuygfgg/Macos_vapoursynth_plugins 获取编译好的常用插件。遇到问题(即使是自己编译的)也最好能来吱一声

使用方法请参考 CI 配置。由于只是简单的文件复制粘贴和脚本运行,这里不再赘述。

编码器

我是学艺不精,所以这里只介绍 x264 和 x265; AV1 出门我也不知道往哪拐,去我也不知道哪。

原版

同样,先安装原版。方便起见,直接安装 ffmpeg 即可

brew install ffmpeg
brew install chromaprint
brew uninstall --ignore-dependencies ffmpeg

# 上面三行用于绕过循环引用

brew tap homebrew-ffmpeg/ffmpeg
brew install homebrew-ffmpeg/ffmpeg/ffmpeg --with-dvd --with-game-music-emu --with-jack --with-jpeg-xl --with-libaribcaption --with-libbluray --with-libbs2b --with-libcaca --with-libdvdnav --with-libdvdread --with-libgsm --with-libmodplug --with-libopenmpt --with-libplacebo --with-librist --with-librsvg --with-libsoxr --with-libssh --with-libtensorflow --with-libvidstab --with-libvmaf --with-libxml2 --with-opencore-amr --with-openh264 --with-openjpeg --with-openssl --with-openvino --with-rav1e --with-rtmpdump --with-rubberband --with-speex --with-srt --with-svt-av1 --with-tensorflow --with-tesseract --with-two-lame --with-webp --with-xvid --with-zeromq --with-zimg --HEAD

这里我们安装尽可能多的库,以备不时之需。

x265-Yuuki-Asuna

X265的异变版本。

我修改了一些不兼容 macos 的部分

git clone https://github.com/yuygfgg/x265-Yuuki-Asuna
cd x265-Yuuki-Asuna/build/linux #你没看错,就是linux
sh multilib.sh
sudo make install
brew unlink x265

运行 x265 可能会有报错,此时请尝试 Macos_vapoursynth_plugins/tools/checkdylib.py (可能需要sudo)

有时可能会报错几个 VS 头文件找不到,简单办法是直接去修改 source/input/vpy.h。运行时报找不到 VS 库也去这里改。

  • classic : /usr/local/include/vapoursynth & /usr/local/lib/libvapoursynth-script.dylib
  • upstream: /opt/homebrew/include/vapoursynth & /opt/homebrew/lib/libvapoursynth-script.dylib

我知道这很糙但是懒得改了((

相比 brew 安装的版本,这个能提供一些性能提升。这是由于 homebrew 在 M1 上编译所有包,而 x265 暂时不支持运行时 CPU 探测,所以无法利用新的 CPU 特性 (如 I8MM, SVE)

x264-Mod-by-Patman

这是一个修改版的 X264。 X264的修改版众多,这里只是随便列举一个。

git clone https://github.com/Patman86/x264-Mod-by-Patman
cd x264-Mod-by-Patman
./configure --disable-avs --enable-lto --disable-ffms --disable-swscale --disable-lavf  --disable-gpac  --disable-lsmash # 按需修改
make -j
sudo make install
brew unlink x264

比较难以安装的工具就是这些了,祝你幸福(

其余的常用工具还请利用 GPT 和 google,篇幅限制不可能全部列举。

一些不消耗性能的不妨使用 wine。

brew install --cask --no-quarantine gcenx/wine/wine-crossover

wine /path/to/.exe

使用

有了工具,还要会用。这里简单介绍一下独属于 Mac 平台的几个坑点。

vsort相关

fp16, ml_program?

这是非常复杂的问题,具体请参考 https://github.com/AmusementClub/vs-mlrt/pull/116

简而言之,ML_program enables fp16 computation on ANE, instead of allocating all to CPU. However, the MLprogram is not well-supported currently, supporting much less EPs than regular NeuralNetwork.

在不考虑 EP 支持差异情况下的大致性能:

ml_program=1 + fp16=True: ANE 120% usage, 10.52fps
ml_program=1 + fp16=False: GPU 97% usage, 5.40fps
ml_program=0 + fp16=True: CPU 100% usage, ~0fps
ml_program=0 + fp16=False: ANE 114% usage, 10.23fps

script:

import vapoursynth as vs
from vapoursynth import core
import vsmlrt

src = core.lsmas.LWLibavSource('/path/to/source').resize.Spline36(1920//2, 1080//2, format=vs.RGBS, matrix_in_s="709") # same performance if format=RGBH
fin = vsmlrt.Waifu2x(clip=src, noise=-1, scale=2, backend=vsmlrt.Backend.ORT_COREML(ml_program=1, fp16=True), model=vsmlrt.Waifu2xModel.anime_style_art_rgb) # anime_style_art_rgb uses simplest Ops, almost all supported by tested backends

fin.set_output(0)

为什么我的硬盘莫名其妙的满了?

请参考 https://github.com/AmusementClub/vs-mlrt/issues/107。

总之,得手动清理(((

opencl 相关

为什么...

apple 已经放弃了 opencl,所以啥问题都不意外。我只能保证,在 M2pro, Macos 15.1.1 (24B91) 上,nnedi3cl 和 eedi3m 是正常工作的,而 KNLM 有问题。

有消息表明,M4 上 nnedi3cl 也出现了问题 (好在可以 workaround):https://github.com/yuygfgg/Macos_vapoursynth_plugins/issues/3


好的,Mac 视频压制的准备工作基本上完成了,是不是非常简单呢(迫真

上面的内容一定有大量的疏漏,加上我本人不善常编程,请各位大佬多多指教!