RunAnywhere Web SDK 的 ONNX WebGPU 双构建方案浏览器端 STT/TTS/VAD 与 Embeddings 的 GPU 加速实战【免费下载链接】runanywhere-sdksProduction ready toolkit to run AI locally项目地址: https://gitcode.com/gh_mirrors/ru/runanywhere-sdks导读本文围绕 RunAnywhere Web SDK 中bindings/web/docs/ONNX_WEBGPU.md描述的CPU WebGPU 双 WASM 构建twins方案展开同一套 RACommons ONNX Runtime Sherpa 代码如何分别产出racommons-onnx-sherpa.{js,wasm}与racommons-onnx-sherpa-webgpu.{js,wasm}两套自包含产物让浏览器中的语音识别STT、语音合成TTS、语音活动检测VAD与 ONNX Embeddings 在具备 WebGPU 能力的浏览器中自动走 GPU 加速并在不可用时诚实地回退到 CPU。读完本文你将掌握这套双构建的目录布局、ONNX.register()的完整参数语义、从 vendoring 到发布验证的完整构建流程以及 ORT WebGPU EP 探针的底层实现原理。为什么需要双胞胎构建而不是一个带开关的 WASM浏览器端跑 ONNX RuntimeORT有两种执行提供者Execution ProviderCPUWASM 线程 SIMD与 WebGPU经由 Dawn/emdawn 桥接到浏览器navigator.gpu。RunAnywhere Web 的做法不是构建一个同时内嵌两套执行路径的巨型模块而是产出两个孪生 WASM 目标维度CPU 构建WebGPU 构建ORT 归档core/third_party/onnxruntime-wasm/core/third_party/onnxruntime-wasm-webgpu/Vendor 脚本bindings/web/wasm/scripts/vendor-onnxruntime-wasm.shbindings/web/wasm/scripts/vendor-onnxruntime-wasm-webgpu.shWASM 产物racommons-onnx-sherpa.{js,wasm}racommons-onnx-sherpa-webgpu.{js,wasm}WASM 产物目录bindings/web/packages/onnx/wasm/bindings/web/packages/onnx/wasm/从 bindings/web/wasm/CMakeLists.txt 可以看到RAC_WASM_ONNX开关控制racommons-onnx-sherpa目标的构建而RAC_WASM_ONNX_WEBGPU额外产出 WebGPU 变体option(RAC_WASM_ONNX Build the ONNX Sherpa Web SDK WASM target OFF) option(RAC_WASM_ONNX_WEBGPU Emit racommons-onnx-sherpa-webgpu (ORT WebGPU EP path) OFF)分离树的原因provenance 与构建缓存采用两棵独立 vendor 树而非一个脚本加个--webgpu标志的理由在文档中有明确交代且与 llama.cpp 的双构建模式保持一致Provenance 可追溯webgpuon这一属性只出现在 GPU 归档的.rac-wasm-provenance文件中CPU 归档绝不携带该标记。vendor 脚本会在归档头部写入componentonnxruntime-wasm-webgpu、threadson、webgpuon、recipe_schema7-webgpu等 provenance 字段见 vendor-onnxruntime-wasm-webgpu.sh构建前可用RAC_WASM_PROVENANCE_CHECK_ONLY1做幂等校验。构建缓存不冲突WebGPU 变体使用独立的 ORT 构建目录build/OS-webgpu/Release与 CPU 的build/MacOS/Release或 Linux分开避免 Dawn/ORT 并行编译时的缓存碰撞。Dawn emdawn JS 的暂存策略WebGPU 变体依赖 ORT 源码树中 Dawn 生成的 emdawn JS 胶水文件library_webgpu_enum_tables.js、library_webgpu_generated_sig_info.js、library_webgpu_generated_struct_info.js、library_webgpu.js等。脚本的write_dawn_link_hints()会把这些文件复制到onnxruntime-wasm-webgpu/emdawn/并生成.rac-webgpu-link-hints提示文件这样 ORT 的源码build/目录在 vendoring 完成后即可安全删除--onnx-webgpu的最终链接不再依赖它。ONNX.register()加速模式与线程的完整语义TS 侧入口是 bindings/web/packages/onnx/src/ONNX.ts 中的ONNX.register()。其核心签名与文档一致ONNX.register({ acceleration: auto | cpu | webgpu, threads })acceleration 三档语义取值行为auto默认浏览器 WebGPU、WebGPU 产物、ORT WebGPU EP 探针三者全部成功时启用 WebGPU任一失败则回退 CPU并通过ONNX.lastFallbackReason暴露原因webgpu强制要求真实 WebGPU EP探针失败直接throw绝不静默降级cpu只加载 CPU 产物不看 GPU 能力关键设计原则是**诚实加速honest accel**ONNX.accelerationMode只有在 ORT 的AppendExecutionProvider(WebGPU)真正成功后才返回webgpu。这一点在 workerOnnxRuntime.ts 的文件头注释中被明确写为纪律Never reportacceleration: webgpuunless the ORT append probe succeeds.threads 徽章的真相不是多 GPUONNX.register({ threads })中的threads是Sherpa/ORT 的 intra-op 线程数pthread被钳制在 1–8 之间UI 上展示的×N徽章指的就是这个线程数而不是多张 GPU 并行。代码中的钳制逻辑clampThreads在两处一致实现// bindings/web/packages/onnx/src/ONNX.ts function clampThreads(value: number | undefined): number { if (value null || !Number.isFinite(value)) return 2; // 默认 2 return Math.max(1, Math.min(8, Math.floor(value))); }默认示例使用threads: 2。线程计数会在加载路径上通过导出函数_rac_onnxrt_set_wasm_thread_counts(intraOp, interOp)写入 WASM 侧interOp 固定为 1并且在 ORT EP 探针之前完成配置见下文原理节。其余注册选项ONNXRegisterOptions还包含wasmUrl/webgpuWasmUrl分别覆盖 CPU 胶水文件racommons-onnx-sherpa.js与 WebGPU 胶水文件racommons-onnx-sherpa-webgpu.js的加载 URLbackendWorkerFactory/preferBackendWorker/requireBackendWorker控制 STT/TTS/VAD 是否在 Web Worker 中执行。浏览器环境默认requireBackendWorker: truefail-closed与 LlamaCPP 一致主桥保持在 CPU 侧以避免双堆 GPU 争用——加速推理归 Worker 所有注册成功后可用ONNX.accelerationMode、ONNX.threads、ONNX.lastFallbackReason、ONNX.lastWorkerDiagnostics做诊断展示。示例用法来自 packages/onnx/README.md 与 ONNX.ts 的注释import { RunAnywhere, SDKEnvironment } from runanywhere/web; import { ONNX } from runanywhere/web-onnx; await RunAnywhere.initialize({ environment: SDKEnvironment.SDK_ENVIRONMENT_DEVELOPMENT }); await ONNX.register({ acceleration: auto, threads: 2 }); await RunAnywhere.completeServicesInitialization(); const transcript await RunAnywhere.transcribe(audioSamples, { sampleRate: 16_000 });构建与发布流程完整构建链路定义在 bindings/web/package.json 的 npm scripts 中# 从 bindings/web 目录执行 source emsdk/emsdk_env.sh npm run vendor:wasm:speech # CPU ORT WebGPU ORT Sherpa 三份 vendor npm run build:wasm:all # 含 --onnx-webgpuvendor:wasm:speech实际展开为三个子步骤vendor:wasm:speech: npm run vendor:wasm:onnxruntime npm run vendor:wasm:onnxruntime-webgpu npm run vendor:wasm:sherpabuild:wasm:all则依次构建核心、llamacpp、onnx、webgpu、rag 与 onnx-webgpu 各目标build:wasm:all: npm run build:wasm -- --core --llamacpp --onnx npm run build:wasm -- --webgpu --rag npm run build:wasm -- --onnx-webgpuvendor 脚本的硬性要求vendor-onnxruntime-wasm-webgpu.sh 是 WebGPU 变体的权威 vendor 入口它有几个值得注意的工程细节Emscripten 版本锁定require_canonical_emscripten()会比对emcc --version与VERSIONS中锁定的EMSCRIPTEN_VERSION不一致直接失败源码 revision 校验ensure_source_checkout()要求 ORT checkout 的 HEAD 必须等于ONNX_COMMIT_WEB防止不可复现构建emsdk 路径陷阱脚本将 canonical emsdk 以 APFS clone或 rsync 回退暂存到 ORT 本地cmake/external/emsdk因为符号链接会让 emcc 的 sanity hash 在 symlink/realpath 间翻转从而中途清空 sysroot 缓存Python 版本门禁Emscripten 6 要求 Python ≥ 3.10脚本会显式导出EMSDK_PYTHON并同时固定PYTHON/Python_EXECUTABLE/Python3_EXECUTABLE防止宿主机 Anaconda 的旧 Python 被 CMake 误发现符号审计构建产物通过llvm-nm审计 protobuf 命名空间遮蔽google::rac_ort_protobuf不允许未遮蔽的google::protobuf符号与 Abseil EM_JS 遮蔽并确认归档包含 WebGPU 符号构建标志--use_webgpu --enable_wasm_simd --enable_wasm_threads --build_wasm_static_lib且通过-Dprotobufrac_ort_protobuf等宏做符号遮蔽避免与主模块冲突。不要回归WebGPU EP 的编译宏纪律文档与 runtimes/onnxrt/CMakeLists.txt 都强调了一条硬性规则WebGPU 孪生目标必须让rac_runtime_onnxrt以RAC_ONNXRT_EP_WEBGPU_ENABLED编译绝不要#define RAC_ONNXRT_EP_WEBGPU——因为RAC_ONNXRT_EP_*是rac_onnxrt_runtime_ep.h中的枚举值用作宏会与枚举冲突。仅靠最终 WASM 可执行文件的COMPILE_DEFS不够。CMake 注释解释了原因最终.js/.wasm可执行文件上的 COMPILE_DEFS不会传播进静态库rac_runtime_onnxrt因此该宏必须落在静态库自身的编译定义上否则probe_webgpu_ep()会被编译成 stub返回CAPABILITY_UNSUPPORTED导致探针永远失败。CMake 侧通过nm扫描归档中是否存在WebGpuExecutionProvider符号来自动决定是否启用# runtimes/onnxrt/CMakeLists.txt (Emscripten 分支摘要) if(_rac_onnxrt_webgpu_ep) target_compile_definitions(rac_runtime_onnxrt PRIVATE RAC_ONNXRT_EP_WEBGPU_ENABLED) else() message(STATUS ONNX Runtime WebGPU EP: unavailable in selected artifact; CPU fallback only) endif()底层原理WebGPU EP 探针与诚实回退Worker 侧加载逻辑位于 workerOnnxRuntime.ts 的WorkerOnnxRuntime类其tryLoadPath()是完整的加载流水线浏览器 WebGPU 预检detectWebGPU()检查navigator.gpu?.requestAdapter是否存在且 adapter 是否支持shader-f16feature——这是 ORT WebGPU 的实际运行前提动态 import 胶水按acceleration选择racommons-onnx-sherpa.js或racommons-onnx-sherpa-webgpu.js与 llama 一致不做 HEAD/Range 预检因为 Vitefs常拒绝这类请求导致误跳过 WebGPU 孪生直接尝试 import、失败再回退WASM ping调用_rac_wasm_ping()验证模块可运行返回值必须为42初始化平台适配器new PlatformAdapter(...)→register()→ 分配rac_config结构 →rac_init()→ 设置模型基目录/opfs线程池先行setThreadCounts()通过_rac_onnxrt_set_wasm_thread_counts(threads, 1)配置 intra-op 线程必须在 SharedOrt / EP 探针之前EP 探针与激活activatePreferredEp(preferWebGPU)调用导出符号_rac_onnxrt_activate_preferred_wasm_ep(1)或_rac_onnxrt_probe_webgpu_ep。这里有一个关键细节WebGPU 孪生是以 Asyncify 方式链接的EP 探针/append 可以穿过 Dawn 的等待并返回 Promise所以代码用Promise.resolve()吸收返回值后再与1比较——如果同步 1检查即使有真实 WebGPU EP 也会永远失败并诚实回退到 CPUSherpa provider 同步_rac_sherpa_set_wasm_compute(threads, provider)把webgpu或cpu字符串传给 Sherpa后端注册依次调用rac_backend_onnx_register与rac_backend_sherpa_registerRAC_ERROR_MODULE_ALREADY_REGISTERED视为成功健康上报Worker 将acceleration、threads、fallbackReason、最近 40 行 diagnostics 回传主线程最终决定ONNX.accelerationMode/ONNX.lastFallbackReason。auto模式下的失败路径会先teardown()卸载 WebGPU 模块释放独立 heap再加载 CPU 产物webgpu强制模式下任何失败都直接抛出附带_rac_onnxrt_last_webgpu_probe_error()读到的探针错误详情。发布门禁Gate与验证文档给出的发布验证要点与 web-lane-e2e.mjs、web-lane-finalize.mjs 等脚本所守护的检查一致产物非空两对 speech WASM 产物CPU 与 WebGPU 的{js,wasm}都必须存在demo release 依赖demo 仓库RunanywhereAI/runanywhere-web与本仓库平级克隆的release.sh要求dist中包含 WebGPU 产物对浏览器 COI 检查在跨源隔离COOP/COEP的浏览器会话中UI 应显示Speech/Embeddings: WebGPU且ONNX.lastFallbackReason null或读取__RUNANYWHERE_ONNX_DIAG__诊断全局强制模式必须失败当 WebGPU 孪生/探针损坏时强制webgpu必须throw而不是假装成功——这是诚实加速在发布链路上的最终保障。注意pthread 支撑的 ONNX BackendWorker WASM 依赖crossOriginIsolatedSharedArrayBuffer 前提。ONNX.register()在发现globalThis.crossOriginIsolated false时会打 warning提示生产环境必须以 COOP/COEP 头提供页面README 也要求按 bindings/web/README.md 配置跨源隔离头。线程浸泡测试可选文档最后建议的可选压力测试在 COOP/COEP 下对 Whisper Tiny、Canary、Nemotron 三组模型分别以线程数 1/2/4 运行测量 wall time 与是否出现Aborted()。这用于验证多线程 WASM 在长语音会话下的稳定性与线程收益曲线——threads的合理取值1–8与具体模型、硬件相关建议按实测数据选择默认值而不是盲目调高。小结RunAnywhere Web SDK 的 ONNX WebGPU 双构建方案用两棵 vendor 树 两个 WASM 孪生 一个诚实探针的组合在浏览器端同时拿到了 CPU 的兼容性与 WebGPU 的加速能力auto模式让支持 WebGPU 的浏览器自动加速语音与 EmbeddingslastFallbackReason让降级原因透明可见强制webgpu模式则为追求确定性的场景提供了失败即报错的严格语义。无论是想快速接入ONNX.register({ acceleration: webgpu })还是想复现整条vendor → build → release流水线本文所梳理的脚本、宏纪律与探针原理都能直接指导你的实践。关键参考路径构建入口与 npm scriptsbindings/web/package.jsonWebGPU ORT vendor 脚本bindings/web/wasm/scripts/vendor-onnxruntime-wasm-webgpu.shWASM 目标与开关定义bindings/web/wasm/CMakeLists.txtEP 编译宏与自动探测runtimes/onnxrt/CMakeLists.txt注册 API 与诊断字段bindings/web/packages/onnx/src/ONNX.tsWorker 侧加载与 EP 探针bindings/web/packages/onnx/src/workerOnnxRuntime.ts包使用示例bindings/web/packages/onnx/README.md【免费下载链接】runanywhere-sdksProduction ready toolkit to run AI locally项目地址: https://gitcode.com/gh_mirrors/ru/runanywhere-sdks创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
企业数字化 ERP 产品动态
相关推荐
红队钓鱼场景下的Nginx反向代理技术分析 在红队钓鱼中,攻击者通过Nginx反向代理(AiTM)透明转发受害者流量至真实站点,同时利用 proxy_pass 配合日志变量捕获明文账密($request_body)与会话Cookie($http_cookie);… · 2026/9/24 15:01:29
从异步复制到MGR:MySQL复制机制的三层演进与选型框架 大家好,我是小耶,写功课只是为了我踩过的坑,你们别再踩了!MySQL的主从复制是最常用的高可用方案,但默认的异步复制有一个硬伤:主库写完即返回成功,binlog还没传到从库时主库宕机,这部… · 2026/9/24 15:01:29
2026企业AI办公工具选型指南:框架、平台盘点与落地场景 企业引入AI办公工具时,很容易陷入以功能清单判断产品价值的误区。不少管理者会横向罗列各家平台的能力项,用功能数量多少作为取舍依据,或是单纯以采购成本、品牌声量决定选型方向。这种评估方式容易造成AI工具上线之后,难以融入现… · 2026/9/24 15:31:47
AI 生成的对比表格怎样转成可计算 Excel? 把 AI 回答里的表格粘进 Excel 后,表面看像一张表,却常常无法求和、筛选或透视。原因通常不在 Excel,而在输入:Markdown 表格只是文本结构;货币符号、百分号、千分位逗号和空格也可能让数字被当作文本。最省事的方式是… · 2026/9/24 15:31:35
2026 HUAWEI HiCar 认证新变化,车载设备研发必看要 2026 年是 HiCar 认证变化较多的一年。V6.0.0 规范已经全面落地,HarmonyOS NEXT 生态全面铺开,安全要求提升了多个等级。这些变化叠加在一起,对做前装车机、后装盒子、车载应用的厂商都产生了实际影响。这篇文章把 2026 年较为关键的几个变… · 2026/9/24 15:31:35
奥赛一本通 1467 Radio Transmission 1467 Radio Transmission
题目大意
给定一个字符串,求一个长度尽可能短的串,使得原先的串是这个短串重复若干次之后的子串。
知识要点
KMP
解题思路
首先,求解的这个短串一定可以是原串的前缀,如果不是前缀的话,将这个… · 2026/9/24 15:31:29
STM32无DAC怎么办?用PWM加RC滤波实现低成本模拟输出 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/24 15:31:29
基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程 简介:这是一套面向计算机、人工智能、自动化等专业学生与教师的毕业设计级项目资源,围绕YOLOv8实现渔船作业监控系统,可用于毕设、课程设计、大作业或项目立项演示。压缩包共97个文件,约24.21MB,以70个Python源码文件为… · 2026/9/24 0:00:13
1D-CNN时间序列建模实战:从Conv1d原理到工业落地 简介:面向时间序列数据建模的一维卷积神经网络完整实现,适合深度学习入门者及需要快速验证时序模型的研究者,能够从音频、文本、传感器或股价等序列中挖掘局部特征与时间依赖。压缩包体积很小,只有3KB,内含3个Python脚… · 2026/9/24 0:00:26
柔软的L:汉语语流中被忽视的舌肌张力控制 1. 这个“L”不是字母表里的L,而是舌尖上的L最近在几个方言群和语音教学社群里,反复看到有人发一句:“也说字母L:柔软的长舌”。初看以为是英语发音课笔记,点开才发现全是方言爱好者、播音系学生、语言康复师甚至戏曲演… · 2026/9/24 0:00:44