Jetson AGX Orin 上部署 Fun-ASR
在 Jetson AGX Orin 上部署 Fun-ASR-Nano-2512踩坑、shim 与实时推理目标在 NVIDIA Jetson AGX OrinJetPack 6.x / CUDA 12.x上用 Python 3.10 conda 环境把Fun-ASR-Nano-2512部署到 GPU并达到实时语音识别。最终成果RTF ≈ 0.275.6 秒音频 1.5 秒出结果支持离线文件、HTTP 服务、实时麦克风三种用法。目录背景与选型硬件与软件环境部署架构总览踩坑一torchaudio 与 Jetson PyTorch 的 C ABI 冲突踩坑二cuDNN 8 vs 9 与 CUBLAS 库路径顺序踩坑三Qwen3 需要 transformers 4.51一键安装与模型下载环境校验与端到端验证性能测试三种使用方式可复现性总结进一步优化方向背景与选型Fun-ASR-Nano-2512 是阿里巴巴通义实验室开源的端到端语音识别大模型支持中/英/日及多方言、多口音参数量 800M。它基于 FunASR 框架音频编码器是 SenseVoiceEncoderSmallLLM 是 Qwen3-0.6B。在 Jetson 这类边缘设备上部署 LLM-ASR 模型最大的挑战不是模型本身而是PyTorch 生态在 ARM JetPack 上的兼容性。官方 PyPI 的 aarch64 wheel 大多是 CPU 版或者与 NVIDIA Jetson 专用 PyTorch 的 C ABI 不兼容。因此本次部署没有走pip install torch pip install torchaudio的常规路线而是使用 NVIDIA 为 JetPack 6 编译的 PyTorch wheel在项目内实现一个纯 Python 的torchaudioshim用 conda 安装 cuDNN 8.9 解决 Jetson PyTorch 对libcudnn.so.8的依赖从源码安装 FunASR 并固定 commit硬件与软件环境项目配置设备NVIDIA Jetson AGX Orin 64GBL4T36.4.4JetPack6.xCUDA12.6Python3.10conda 环境funasr-nanoPyTorchtorch-2.4.0a007cecf4168.nv24.05transformers4.57.6funasr源码 editable 安装固定 commitf9937385部署架构总览┌─────────────────────────────────────────────┐ │ 应用层infer_file.py / asr_server.py │ │ / realtime_mic.py │ ├─────────────────────────────────────────────┤ │ 框架层FunASR源码 editable 安装 │ ├─────────────────────────────────────────────┤ │ 兼容层torchaudio/ 纯 Python shim │ ├─────────────────────────────────────────────┤ │ 运行时PyTorch Jetson wheel conda cuDNN 8 │ ├─────────────────────────────────────────────┤ │ 系统层JetPack 6.x / CUDA 12.6 / cuDNN 9.x │ └─────────────────────────────────────────────┘踩坑一torchaudio 与 Jetson PyTorch 的 C ABI 冲突现象安装 PyPI 的torchaudio2.4.0后import 报错OSError:.../libtorchaudio.so:undefined symbol:_ZNK3c105Error4whatEv本质是 PyPI wheel 针对官方 PyTorch 编译而 NVIDIA Jetson PyTorch 的 C ABI尤其是c10::Error与官方版不同。解决思路既然 funasr 对 torchaudio 的使用非常有限何苦非要装那个带 C 扩展的 wheel我检查了 funasr 实际用到的接口torchaudio.load音频文件读取torchaudio.transforms.Resample重采样torchaudio.compliance.kaldi.fbankKaldi 风格滤波器组torchaudio.functional.create_dct/istft少量符号这些都是纯 Python 可实现的。实现 torchaudio shim在项目根目录下新建torchaudio/包torchaudio/ ├── __init__.py # load() 用 soundfile 实现预加载子模块 ├── compliance/ │ ├── __init__.py │ └── kaldi.py # 从 torchaudio 源码拷贝的纯 Python fbank ├── functional/ │ └── __init__.py # resample / create_dct / istft ├── transforms/ │ └── __init__.py # Resample 纯 PyTorch 实现 └── sox_effects/ └── __init__.py # 占位关键代码片段# torchaudio/__init__.pydefload(filepath,*args,**kwargs):importsoundfileassf data,srsf.read(filepath,dtypefloat32,always_2dTrue)datadata.T# [channels, samples]returntorch.from_numpy(data),sr# torchaudio/functional/__init__.py# _get_sinc_resample_kernel / _apply_sinc_resample_kernel# 直接从 torchaudio 源码搬运去掉对 libtorchaudio.so 的依赖然后让PYTHONPATH把项目根目录放在最前面funasr 内部import torchaudio就会自动走到这个 shim。效果python-cimport torchaudio; print(torchaudio.__version__)# 2.4.0-jetson-shimpython-cimport torchaudio; print(torchaudio.__file__)# /home/dog-8/workspace/Audio/asr/torchaudio/__init__.py不再报 ABI 错误fbank、resample、音频读取全部正常工作。踩坑二cuDNN 8 vs 9 与 CUBLAS 库路径顺序现象 1libcudnn.so.8 找不到Jetson PyTorch wheel 启动时报ImportError:libcudnn.so.8:cannotopensharedobjectfile:No suchfileordirectory原因JetPack 6.x 系统级 cuDNN 是 9.x但 NVIDIA 这个 PyTorch wheel 编译时链的是 cuDNN 8.x。解决在 conda 环境里单独装一套 cuDNN 8.9condainstall-ycudnn8.9.2.26然后把$CONDA_PREFIX/lib加到LD_LIBRARY_PATH。现象 2CUBLAS_STATUS_ALLOC_FAILED解决 cuDNN 后torch 能 import 了但一跑 CUDA matmul 就报错RuntimeError:CUDA error:CUBLAS_STATUS_ALLOC_FAILED when calling cublasCreate(handle)原因conda 的 cuDNN 包里也带了libcublas.so.12但版本比系统 CUDA 12.6 的旧。如果 conda lib 排在系统 CUDA 前面cublas 初始化就会失败。解决LD_LIBRARY_PATH必须让系统 CUDA 优先exportLD_LIBRARY_PATH/usr/local/cuda-12.6/lib64:${CONDA_PREFIX}/lib:${LD_LIBRARY_PATH}而不是反过来。我把这个设置写进了 conda activate 钩子每次激活环境自动生效# $CONDA_PREFIX/etc/conda/activate.d/funasr-nano-env.shexport_OLD_LD_LIBRARY_PATH${LD_LIBRARY_PATH}exportLD_LIBRARY_PATH/usr/local/cuda-12.6/lib64:${CONDA_PREFIX}/lib:${LD_LIBRARY_PATH}export_OLD_PYTHONPATH${PYTHONPATH}exportPYTHONPATH/home/dog-8/workspace/Audio/asr:${PYTHONPATH}踩坑三Qwen3 需要 transformers 4.51现象加载模型时ValueError:The checkpoint you are trying to load has modeltypeqwen3 but Transformers doesnotrecognize this architecture.解决把 transformers 从4.45.0升级到4.51,5pipinstalltransformers4.51,5同时 requirements.txt 中也相应锁定。一键安装与模型下载环境安装bashscripts/install_jetson_deps.sh funasr-nano3.10这个脚本现在做了这些事检查 aarch64 平台自动检测 conda base 和 CUDA 路径创建 conda 环境下载并安装 Jetson PyTorch 2.4.0安装 conda cuDNN 8.9安装 requirements.txt 依赖从FunASR/子目录或 GitHub 源码安装 FunASReditable固定 FunASR 到验证通过的 commit降级 numpy 到 1.x写入 conda 激活/退出钩子模型下载bashscripts/download_model.sh优先从 ModelScope 下载FunAudioLLM/Fun-ASR-Nano-2512失败则 fallback 到 HuggingFace。环境校验与端到端验证环境校验conda activate funasr-nano python scripts/check_env.py输出示例[1/7] 平台架构检查 ✅ 平台: aarch64 [2/7] conda 环境检查 ✅ conda 环境: funasr-nano [3/7] PyTorch GPU 检查 ✅ torch version: 2.4.0a007cecf4168.nv24.05 ✅ CUDA available: True ✅ CUDA version: 12.2 ✅ GPU: Orin ✅ CUDA matmul 测试通过 [5/7] torchaudio shim 检查 ✅ torchaudio 路径: /home/dog-8/workspace/Audio/asr/torchaudio ✅ torchaudio 版本: 2.4.0-jetson-shim ✅ fbank 输出 shape: torch.Size([98, 80]) [6/7] FunASR 源码安装检查 ✅ funasr path: /home/dog-8/workspace/Audio/asr/FunASR/funasr/__init__.py ✅ funasr 确实从项目内源码加载 [7/7] 模型目录检查 ✅ 模型目录完整: /home/dog-8/models/Fun-ASR-Nano-2512torchaudio shim 单元测试python tests/test_torchaudio_shim.py5 个测试全部通过。端到端验证bashscripts/verify_deployment.sh会依次跑环境校验 → shim 测试 → 离线推理 → HTTP 服务 curl 测试。 端到端验证全部通过性能测试在 Jetson AGX Orin 64GB 上使用example/zh.mp35.6 秒中文音频指标数值模型冷加载约 36 秒推理耗时约 1.5 秒RTF0.270.30识别结果开饭时间早上九点至下午五点RTF 1.0 即视为实时0.27 意味着处理速度是音频播放速度的约 3.7 倍边缘场景完全够用。三种使用方式1. 离线文件识别bashscripts/test_offline.sh\/home/dog-8/models/Fun-ASR-Nano-2512\/home/dog-8/models/Fun-ASR-Nano-2512/example/zh.mp32. HTTP 服务OpenAI 风格bashscripts/start_server.sh /home/dog-8/models/Fun-ASR-Nano-25120.0.0.08000测试curl-XPOST http://localhost:8000/v1/audio/transcriptions\-Ffile/home/dog-8/models/Fun-ASR-Nano-2512/example/zh.mp3\-Flanguage中文返回{text:开饭时间早上九点至下午五点。}3. 实时麦克风识别python src/realtime_mic.py\--model/home/dog-8/models/Fun-ASR-Nano-2512\--language中文--chunk_duration5可复现性总结为了让另一台相同 JetPack 版本的 Jetson AGX Orin 也能一键复现我做了这些改造改造点说明自动检测 conda baseconda info --base不再写死${HOME}/miniconda3自动检测 CUDA 路径优先/usr/local/cudafallback/usr/local/cuda-*FunASR 源码自动获取子目录存在则直接用否则自动 cloneFunASR commit 固定f9937385避免未来源码更新破坏兼容性模型自动下载scripts/download_model.shModelScope HuggingFace 双源环境自动配置conda activate 钩子自动设置 LD_LIBRARY_PATH 和 PYTHONPATH完整校验链check_env.pytest_torchaudio_shim.pyverify_deployment.sh现在给新机器复现只需gitclone仓库~/workspace/Audio/asrcd~/workspace/Audio/asrbashscripts/install_jetson_deps.sh funasr-nano3.10bashscripts/download_model.sh conda activate funasr-nanobashscripts/verify_deployment.sh进一步优化方向当前 RTF 0.27 已经满足实时但想更低延迟或更高吞吐可以优先考虑LLM 解码加速用 vLLM 或 llama.cpp 替换 Qwen3-0.6B 的自回归解码这是当前耗时最大头收益最高Audio encoder TensorRT / ONNX 化SenseVoiceEncoderSmall 做 TensorRT 推理收益次之但对长音频效果明显服务化优化用 gunicorn / uvicorn 替换 Flask 开发服务器加推理队列和批处理提升并发吞吐模型量化LLM 用 INT8/INT4audio encoder 用 FP16在 Orin 上可降低显存占用并提速结语在 Jetson 上部署现代 LLM-ASR 模型最大的工作量往往不是模型推理本身而是让 PyTorch 生态在 ARM JetPack 上跑起来。通过源码安装 FunASR、用纯 Python shim 替代 torchaudio、正确配置 cuDNN/cublas 库路径最终实现了稳定可复现的 GPU 实时语音识别。如果你也在做类似的事情希望这篇笔记能帮你少踩几个坑。项目结构参考. ├── FunASR/ # FunASR 源码 ├── requirements.txt ├── scripts/ │ ├── install_jetson_deps.sh │ ├── download_model.sh │ ├── env.sh │ ├── check_env.py │ ├── verify_deployment.sh │ ├── start_server.sh │ └── test_offline.sh ├── src/ │ ├── infer_file.py │ ├── asr_server.py │ └── realtime_mic.py ├── tests/ │ └── test_torchaudio_shim.py └── torchaudio/ # Jetson 兼容 shim