在ONNX Web Runtime v1.18.1中指定自定义JS/WASM运行时文件路径的解决方案(适配Vue+Vite+旧iOS Safari场景)
在ONNX Web Runtime v1.18.1中指定自定义JS/WASM运行时文件路径的解决方案(适配Vue+Vite+旧iOS Safari场景)
问题分析
你遇到的核心矛盾是:
- ONNX Web Runtime v1.18.1的
env.wasmPaths仅支持配置WASM文件路径,无法指定JS/Worker JS文件的自定义路径; - Vue+Vite的构建会给静态资源添加哈希后缀做缓存击穿,打破了ORT旧版本默认从脚本加载路径解析依赖文件的逻辑;
- 旧iOS Safari(<=16)不支持WASM SIMD,必须锁定v1.18.1版本的非SIMD构建。
最优解决方案:使用locateFile回调覆盖全类型文件路径
ONNX Web Runtime v1.18.1其实提供了**locateFile回调函数**(全局或会话级配置),它可以覆盖所有运行时依赖文件的路径解析逻辑,包括JS、WASM、Worker JS文件,这是比env.wasmPaths更全面的路径配置方案,完美适配你的场景。
步骤1:将ORT运行时文件放入项目并配置Vite资源处理
将v1.18.1版本的三个运行时文件(ort-wasm-threaded.wasm、ort-wasm-threaded.worker.js、ort-wasm-threaded.js)放入你的Vue项目的src/assets/ort/目录下。
如果Vite对这些文件的处理有异常,可在vite.config.js中添加资源类型声明:
import { defineConfig } from 'vite'; import vue from '@vitejs/plugin-vue'; export default defineConfig({ plugins: [vue()], assetsInclude: ['**/*.wasm', '**/*.worker.js'] // 确保Vite识别这些文件类型 });
步骤2:在代码中导入资源并配置locateFile回调
在你的模型推理模块/Vue组件中,通过Vite的?url后缀导入ORT运行时文件(获取带哈希的真实路径),然后在创建InferenceSession时传入locateFile回调:
import * as ort from 'onnxruntime-web'; // 导入ORT运行时文件,?url后缀让Vite返回处理后的带哈希的URL import ortWasmUrl from '@/assets/ort/ort-wasm-threaded.wasm?url'; import ortWorkerUrl from '@/assets/ort/ort-wasm-threaded.worker.js?url'; import ortJsUrl from '@/assets/ort/ort-wasm-threaded.js?url'; // 建立原始文件名到带哈希路径的映射 const ortFileMap = { 'ort-wasm-threaded.wasm': ortWasmUrl, 'ort-wasm-threaded.worker.js': ortWorkerUrl, 'ort-wasm-threaded.js': ortJsUrl }; // 初始化推理会话 async function initModel() { try { // 配置ORT运行时,禁用SIMD以适配旧iOS Safari ort.env.wasm.simd = false; ort.env.wasm.numThreads = 2; // 根据设备性能调整 const session = await ort.InferenceSession.create( // 你的ONNX模型路径(同样可通过?url导入获取哈希路径) new URL('@/assets/models/your-model.ort', import.meta.url).href, { executionProviders: ['wasm'], wasm: { // 核心:通过locateFile覆盖所有依赖文件的路径 locateFile: (filename) => { // 匹配原始文件名,返回对应的带哈希路径 return ortFileMap[filename] || filename; } } } ); console.log('模型初始化成功'); return session; } catch (error) { console.error('模型初始化失败:', error); throw error; } }
步骤3:验证适配旧iOS Safari
确保你使用的是非SIMD版本的ORT v1.18.1运行时文件,可从ONNX Runtime的GitHub Release页面下载v1.18.1的onnxruntime-web-1.18.1.tgz包,解压后取dist/ort-wasm-threaded相关文件(避免下载带simd后缀的文件)。
备选方案:将ORT文件放入Public目录(无自动哈希缓存击穿)
如果你可以接受手动管理缓存击穿(比如给文件名加版本号),可以将ORT运行时文件放入项目的public/ort/目录下,然后直接指定绝对路径:
async function initModel() { ort.env.wasm.wasmPaths = { 'ort-wasm-threaded.wasm': '/ort/ort-wasm-threaded.wasm' }; // 全局配置locateFile处理JS/Worker文件 ort.env.wasm.locateFile = (filename) => `/ort/${filename}`; const session = await ort.InferenceSession.create( '/models/your-model.ort', { executionProviders: ['wasm'] } ); return session; }
这个方案的优点是配置简单,但缺点是无法利用Vite的自动哈希缓存击穿,需要手动更新文件名版本来刷新缓存。
关键注意事项
- 版本锁定:确保package.json中锁定
onnxruntime-web版本为1.18.1,避免意外升级:"dependencies": { "onnxruntime-web": "1.18.1" } - Worker路径问题:线程模式下的Worker文件路径必须正确,否则会导致Safari中出现跨域或404错误,
locateFile回调会自动处理Worker的路径解析。 - Vite开发/生产环境一致性:使用
import.meta.url或?url导入资源可以保证开发和生产环境的路径一致,避免出现开发环境正常但生产环境路径错误的问题。
内容来源于stack exchange




