端侧模型多端部署实战:从格式转换到灰度发布,Web 和移动端统一部署流水线

摘要: 产品从 Web 端扩展到移动端之后,同一个模型、同一段输入,移动端推理结果和 Web 端对不上------评测通过率从九成出头掉到七成多。本文从格式转换、多端适配、加载优化、灰度发布到版本管理,分享一套 Web + 移动端统一部署流水线的搭建过程,以及我在每个环节踩过的坑。

文章目录

先说背景

产品上线之后,反馈来得比预期快------用户说"电脑上用得挺好,手机上有吗?"

当时我们只在 Web 端做了推理,用 Transformers.js 2.17.2 加载量化后的模型,跑在 WebGPU 上。用户量不大时问题不大,但移动端的需求一冒出来,事情就变了。

第一版部署完,我拿手机测了一下,同一个模型、同一段输入,移动端推理结果和 Web 端对不上。不是差一点点,是差得离谱------Web 端生成结果的评测通过率九成出头,移动端掉到了七成多。

排查了三天,发现表面上是一个问题,实际上整个部署链路里藏着好几个隐患。后来我搭了一套统一的部署流水线,把格式转换、多端适配、灰度发布、版本管理串在了一起。这篇文章就聊聊这条流水线是怎么搭的,以及每步踩了什么坑。

核心挑战:多端部署要解决三个问题

先说结论,再展开。端侧模型做多端部署,归根结底要解决三个问题:

挑战 影响 解决方案
模型格式怎么统一 一套模型维护多套格式,版本管理会乱 统一转成 ONNX,作为唯一事实来源
推理后端怎么兼容 Web 端可跑 WebGPU,手机浏览器不一定支持,原生 App 更是不同引擎 分端适配,共享同一份 ONNX 模型文件
版本怎么对齐 模型更新了,Web 端和移动端不能同时更新,灰度怎么控制 远程配置中心统一控制灰度比例和版本号

下图是我最终搭出来的多端部署架构,箭头表示数据流方向:
#mermaid-svg-ExYC8BZJ3TanrzqR{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-ExYC8BZJ3TanrzqR .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-ExYC8BZJ3TanrzqR .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-ExYC8BZJ3TanrzqR .error-icon{fill:#552222;}#mermaid-svg-ExYC8BZJ3TanrzqR .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-ExYC8BZJ3TanrzqR .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-ExYC8BZJ3TanrzqR .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-ExYC8BZJ3TanrzqR .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-ExYC8BZJ3TanrzqR .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-ExYC8BZJ3TanrzqR .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-ExYC8BZJ3TanrzqR .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-ExYC8BZJ3TanrzqR .marker{fill:#333333;stroke:#333333;}#mermaid-svg-ExYC8BZJ3TanrzqR .marker.cross{stroke:#333333;}#mermaid-svg-ExYC8BZJ3TanrzqR svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-ExYC8BZJ3TanrzqR p{margin:0;}#mermaid-svg-ExYC8BZJ3TanrzqR .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-ExYC8BZJ3TanrzqR .cluster-label text{fill:#333;}#mermaid-svg-ExYC8BZJ3TanrzqR .cluster-label span{color:#333;}#mermaid-svg-ExYC8BZJ3TanrzqR .cluster-label span p{background-color:transparent;}#mermaid-svg-ExYC8BZJ3TanrzqR .label text,#mermaid-svg-ExYC8BZJ3TanrzqR span{fill:#333;color:#333;}#mermaid-svg-ExYC8BZJ3TanrzqR .node rect,#mermaid-svg-ExYC8BZJ3TanrzqR .node circle,#mermaid-svg-ExYC8BZJ3TanrzqR .node ellipse,#mermaid-svg-ExYC8BZJ3TanrzqR .node polygon,#mermaid-svg-ExYC8BZJ3TanrzqR .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-ExYC8BZJ3TanrzqR .rough-node .label text,#mermaid-svg-ExYC8BZJ3TanrzqR .node .label text,#mermaid-svg-ExYC8BZJ3TanrzqR .image-shape .label,#mermaid-svg-ExYC8BZJ3TanrzqR .icon-shape .label{text-anchor:middle;}#mermaid-svg-ExYC8BZJ3TanrzqR .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-ExYC8BZJ3TanrzqR .rough-node .label,#mermaid-svg-ExYC8BZJ3TanrzqR .node .label,#mermaid-svg-ExYC8BZJ3TanrzqR .image-shape .label,#mermaid-svg-ExYC8BZJ3TanrzqR .icon-shape .label{text-align:center;}#mermaid-svg-ExYC8BZJ3TanrzqR .node.clickable{cursor:pointer;}#mermaid-svg-ExYC8BZJ3TanrzqR .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-ExYC8BZJ3TanrzqR .arrowheadPath{fill:#333333;}#mermaid-svg-ExYC8BZJ3TanrzqR .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-ExYC8BZJ3TanrzqR .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-ExYC8BZJ3TanrzqR .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-ExYC8BZJ3TanrzqR .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-ExYC8BZJ3TanrzqR .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-ExYC8BZJ3TanrzqR .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-ExYC8BZJ3TanrzqR .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-ExYC8BZJ3TanrzqR .cluster text{fill:#333;}#mermaid-svg-ExYC8BZJ3TanrzqR .cluster span{color:#333;}#mermaid-svg-ExYC8BZJ3TanrzqR div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-ExYC8BZJ3TanrzqR .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-ExYC8BZJ3TanrzqR rect.text{fill:none;stroke-width:0;}#mermaid-svg-ExYC8BZJ3TanrzqR .icon-shape,#mermaid-svg-ExYC8BZJ3TanrzqR .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-ExYC8BZJ3TanrzqR .icon-shape p,#mermaid-svg-ExYC8BZJ3TanrzqR .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-ExYC8BZJ3TanrzqR .icon-shape .label rect,#mermaid-svg-ExYC8BZJ3TanrzqR .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-ExYC8BZJ3TanrzqR .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-ExYC8BZJ3TanrzqR .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-ExYC8BZJ3TanrzqR :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 原始模型
Optimum 转换
ONNX 模型库
onnxruntime-web (Web端)
onnxruntime-react-native (移动端)
远程配置中心

灰度比例 / 版本号

这套架构里,ONNX 模型库是唯一的事实来源,Web 端和移动端共享同一份模型文件,灰度比例和版本号由远程配置中心统一控制。

Step 1:模型格式转换

为什么要转

Transformers.js 可以直接从 HuggingFace 加载模型,在 Web 端开发体验确实好。但移动端不会认这个格式------不管是 ONNX Runtime Mobile 还是 TFLite,都需要 ONNX 格式的模型文件。

所以第一步就是把模型从原始格式转成 ONNX。我用的是 HuggingFace 官方的 Optimum 工具链,一条命令就能跑完(转换流程参考 Transformers.js 官方文档):

bash 复制代码
python -m scripts.convert --quantize --model_id Qwen/Qwen2.5-0.5B-Instruct

这个命令来自 Transformers.js 官方仓库,它会自动下载模型、转成 ONNX、再做 INT8 量化。输出目录结构是这样的:

text 复制代码
models/Qwen2.5-0.5B-Instruct/
├── config.json
├── tokenizer.json
├── tokenizer_config.json
└── onnx/
    ├── model.onnx
    └── model_quantized.onnx

model.onnx 是 FP32 版本,model_quantized.onnx 是 INT8 量化版。移动端一般用量化版,体积小很多,加载速度也快

边界说明

不是所有模型都能用这条命令直接转。一些自定义算子或者特殊的 attention 实现(比如 Qwen2 使用的 GQA,Grouped Query Attention),在 ONNX 导出时如果 Optimum 的转换脚本没有自动识别 num_key_value_heads 配置,就需要手动指定,否则会报错。我一开始没注意这个细节,卡了半天。

另外,INT8 量化会有精度损失。我的经验是分类这类简单任务损失不大(1-2 个点),但生成式任务在长文本场景下差异会更明显。如果精度敏感,建议先跑一遍对齐测试。

Step 2:多端推理后端适配

选型策略

模型转好了,但 Web 端和移动端用的是不同的推理后端。我的做法是分端做适配,共享同一份 ONNX 模型文件:

Web 端onnxruntime-web,推理后端按优先级降级:WebGPU → WebGL → CPU。逻辑很简单------先试最快的,不行就降级(后端的完整列表见 ONNX Runtime JavaScript API 文档)。

javascript 复制代码
/**
 * 创建 ONNX Runtime 推理会话(初版,存在资源泄漏问题)
 *
 * 作用:按优先级依次尝试 WebGPU → WebGL → wasm(CPU) 创建推理会话,
 *      优先使用最快的后端,失败时自动降级到较慢的后端。
 *
 * 注意:这个版本有个隐患------每次 try/catch 之间没有释放失败的 session,
 *      降级时可能因 GPU 资源未释放而报 context lost,详见下方修复版。
 */
async function createSession(modelPath) {
  // 优先 WebGPU,不行就降级
  let backend = 'webgpu';
  try {
    // 尝试用 WebGPU 创建会话;executionProviders 指定推理后端
    return await ort.InferenceSession.create(modelPath, {
      executionProviders: [backend]
    });
  } catch (e) {
    // WebGPU 初始化失败(如浏览器不支持、驱动异常),降级到 WebGL
    console.warn(`${backend} 初始化失败,降级到 webgl`);
    backend = 'webgl';
  }
  try {
    // 尝试用 WebGL 创建会话
    return await ort.InferenceSession.create(modelPath, {
      executionProviders: [backend]
    });
  } catch (e) {
    // WebGL 也失败,最后降级到 wasm(CPU 的 WebAssembly 加速)
    console.warn(`${backend} 初始化失败,降级到 wasm`);
    return await ort.InferenceSession.create(modelPath, {
      executionProviders: ['wasm']
    });
  }
}

这段代码看着简单,但少了一个关键细节------每次 try/catch 之间要清理上一次失败的 session 上下文,否则 WebGL 降级时可能因为 GPU 资源没释放而失败。我第一次写的时候没注意,WebGPU 降级到 WebGL 时一直报 context lost,排查了半天才发现是 session 没销毁。修复后的代码要显式释放失败的 session:

javascript 复制代码
/**
 * 创建 ONNX Runtime 推理会话(修复版,显式释放失败的 session)
 *
 * 改进点:用 for 循环统一遍历后端列表,避免重复代码;
 *        每次 catch 中显式调用 session.release() 释放 GPU/内存资源,
 *        防止降级时因资源未释放导致 context lost。
 *
 * 降级策略:按 ['webgpu', 'webgl', 'wasm'] 顺序尝试,
 *        第一个创建成功的后端即为最终使用的推理后端。
 */
async function createSession(modelPath) {
  let session = null;
  // 按优先级从快到慢依次尝试各推理后端
  for (const backend of ['webgpu', 'webgl', 'wasm']) {
    try {
      // 尝试用当前后端创建会话
      session = await ort.InferenceSession.create(modelPath, {
        executionProviders: [backend]
      });
      // 创建成功,直接返回,不再尝试更慢的后端
      return session;
    } catch (e) {
      // 关键:释放失败的 session,避免 GPU 资源泄漏
      // 如果上一次循环已创建了 session 但后续操作失败,必须手动 release
      if (session) {
        await session.release();
        session = null;
      }
      console.warn(`${backend} 初始化失败,降级`);
    }
  }
  // 所有后端都失败,抛出明确错误,便于上层捕获处理
  throw new Error('所有推理后端均不可用');
}
```运行结果:
```text
// WebGPU 可用时,没有提示,正常创建 session
// WebGPU 不可用时,控制台依次输出:
[WARN] webgpu 初始化失败,降级到 webgl
// 如果 WebGL 也不可用:
[WARN] webgl 初始化失败,降级到 wasm
// 注意:如果没清理 session,WebGPU 降级时会报
[ERROR] context lost

小提示: onnxruntime-web 的 execution provider 名称是 wasm(对应 CPU 的 WebAssembly 加速)、webglwebgpu。没有 cpu 这个写法,写 ['cpu'] 会直接初始化失败。

移动端 我用的是 onnxruntime-react-native,原生绑定,性能和 Web 端不在一个量级。同一个 INT8 量化模型,Web 端 WebGPU 推理不到一秒,移动端原生推理只要零点几秒。但代价是打包体积增大了,ONNX Runtime 的 native 库本身就有几十兆。

边界说明

这套降级策略在主流浏览器上表现稳定,但在一些特定场景下会出问题:

  • Chrome 在部分 Android 机型上 WebGPU 后端有 bug------我遇到过 Chrome 133 在骁龙 8 Gen 2 上 WebGPU 初始化成功但推理结果全是 NaN 的情况。降级到 WebGL 才正常。
  • iOS 的 WebGPU 支持来得晚------iOS 18 才全面支持 WebGPU,之前只能用 WebGL 或者 CPU。如果用户群体 iPhone 占比高,WebGPU 的覆盖率其实没想象中那么高。
  • onnxruntime-react-native 的版本兼容性------这个库的版本和 React Native 版本有绑定关系,新版 ONNX Runtime(比如 1.24.x)通常要求较新的 RN 版本,升级 RN 时 ONNX Runtime 也要跟着升,否则编译报错。

Step 3:模型加载优化

问题在哪

模型转好了、后端选好了,但用户打开页面还是要等。一个 INT8 量化后的 5 亿参数模型约 500MB,走 CDN 加载也要好几秒,加上模型初始化时间,用户看到的第一屏就是白屏。

我的做法

分三步走:

第一,模型分片加载。 把一个大 ONNX 文件拆成多个分片,并行下载。onnxruntime-web 支持 External Data 格式,可以把权重数据拆到多个 .bin 文件里,模型结构文件单独加载。

javascript 复制代码
import { pipeline, env } from '@xenova/transformers';

// 指定本地模型路径:模型文件放在 /models/ 目录下,走本地加载
env.localModelPath = '/models/';
// 禁止从远程下载模型:只从本地加载,避免运行时意外请求 HuggingFace
env.allowRemoteModels = false;

/**
 * 创建文本生成 pipeline(模型分片加载 + 进度回调)
 *
 * 作用:加载 Qwen2.5-0.5B-Instruct 模型并创建 text-generation 管道。
 *      模型权重被拆成多个分片并行下载,通过 progress_callback 实时上报进度。
 *
 * 注意:
 * 1. progress_callback 是 Transformers.js 提供的接口,加载过程中会多次回调;
 * 2. progress 对象包含 loaded(已加载字节数)和 total(总字节数)两个字段;
 * 3. 计算百分比时注意 loaded/total 可能为小数,需用 Math.round 取整;
 * 4. 分片加载能显著缩短首屏等待时间,但首次加载仍需下载完整模型。
 */
const pipe = await pipeline('text-generation', 'Qwen/Qwen2.5-0.5B-Instruct', {
  // 注册加载进度回调:每次下载一个分片都会触发
  progress_callback: (progress) => {
    // progress 包含 loaded / total 字段
    // 计算已加载百分比(0-100),并更新页面上的进度条
    updateLoadingBar(Math.round(progress.loaded / progress.total * 100));
  }
});

progress_callback 是 Transformers.js 提供的接口,加载进度可以实时展示给用户。我跑了大概几十次加载测试,平均加载时间从好几秒降到了一两秒,用户感知好很多。

运行结果示例:

text 复制代码
// progress_callback 每次回调输出(total 约为 500MB,progress 是 0-100 的百分比):
{ loaded: 1048576, total: 524288000, progress: 0.2 }
{ loaded: 2097152, total: 524288000, progress: 0.4 }
// ... 中间省略几百次回调 ...
{ loaded: 524288000, total: 524288000, progress: 100 }
// 加载完成,模型初始化成功

第二,模型预缓存。 用户第一次加载完成后,把模型文件缓存到 IndexedDB 或者 Cache Storage。下次打开页面时先检查本地缓存,有就直接加载。首次加载好几秒,后续打开基本在一秒以内。

第三,模型预加载策略。 如果用户访问的是首页,可以在后台提前加载模型资源。等用户真正进入推理页面时,模型已经准备好了。这个做法的代价是首页加载流量会增加,但换来的是用户进入推理页面的"零等待"体验。

边界说明

预缓存方案在 Web 端好用,但移动端原生环境不一样------移动端没有 IndexedDB,用的是本地文件系统。模型文件存哪、怎么管理缓存过期,需要额外处理。我的做法是把模型文件集成到 App 的 assets 目录里,随版本发布,不走远程下载。缺点是模型更新需要发版,不能热更新。

Step 4:灰度发布策略

为什么需要灰度

模型不是写死的。今天跑 INT8 量化,明天可能跑 INT4,后天可能换更大的模型。如果直接全量推送给所有用户,出了问题连回滚的窗口都没有。

我的方案

用户分桶 + 按模型版本号分发。分桶逻辑按用户 ID 的 hash 值取模,决定用户落在哪个模型版本组里。

方案 做法 优点 缺点
全量部署 所有用户用同一版本 简单 出了问题影响面大
灰度发布 按用户分桶逐步推送 风险可控 需要版本管理
蓝绿部署 两套环境同时在线,切流量 回滚快 资源消耗翻倍

我用的是灰度发布。第一阶段推一小部分用户,观察一天;没问题扩到两成;再观察一天;最后全量。每个阶段都有自动回滚条件------如果某模型版本导致错误率明显上升,自动切回上一版本。

第一次翻车

灰度上线的第一天,我设置了一小部分灰度比例,但第二天一看数据,绝大部分用户都在用新模型。排查发现,模型版本号缓存在 CDN 层,旧的缓存被新模型的请求覆盖了,导致后续用户请求都命中了新版本。

修复方案是加了一层版本号校验:前端从远程配置中心拉取当前用户的模型版本号,再和本地缓存的版本号对比,不一致就重新下载。同时把模型版本号和代码版本号绑定,代码回滚时模型也跟着回。

Step 5:热更新与版本管理

模型版本和代码版本对齐

模型更新最怕的是"模型换了,代码没换"。我遇到过这种情况:新模型输出的 logits 分布变了,但代码里 softmax 的温度参数还是旧值,推理结果直接错乱。

我的做法是维护一个版本兼容性矩阵:

模型版本 代码版本 v1.0 代码版本 v1.1 代码版本 v2.0
v1.0 ✅ 兼容 ✅ 兼容 ❌ 不兼容
v1.1 ✅ 兼容 ✅ 兼容 ❌ 不兼容
v2.0 ❌ 不兼容 ❌ 不兼容 ✅ 兼容

每次发布新模型时,必须指定最低兼容的代码版本。如果用户当前代码版本低于这个值,走 CDN 下载新模型之前先弹更新提示,让用户升级 App 或刷新页面。

热更新实现

热更新不做全量模型替换,而是用远程配置控制模型版本号。用户打开页面时,先请求一个轻量级的配置接口,返回当前用户应该使用的模型版本号,然后根据这个版本号去加载本地缓存或远程下载。

json 复制代码
{
  "model_version": "v2.0",
  "min_code_version": "1.2.0",
  "rollout_percentage": 20,
  "fallback_version": "v1.1"
}

这个配置接口返回的内容包含灰度比例、模型版本、回滚版本。前端根据这些信息决定加载哪个模型。如果接口请求失败,默认使用上一个已知的稳定版本。

边界说明

这套热更新机制在 Web 端效果好,因为页面刷新就是一次"重新拉配置"的机会。但移动端原生 App 不一样------用户可能一个月不重启 App,配置一直走缓存,新模型发了一个月用户还没收到。我的做法是给移动端加一个定时刷新机制,每天或每次 App 从后台切到前台时重新拉配置。

整体效果

部署流水线跑通之后,多端部署从"手动操作"变成了"一次配置、自动分发"。同一套 ONNX 模型文件,Web 端和移动端共享,灰度比例和版本号由远程配置控制,回滚一条命令。

指标 部署前 部署后
模型部署耗时 半天(手动上传) 十分钟(CI/CD)
多端一致性 经常对不上 精度对齐测试通过
回滚速度 半小时 一分钟
灰度控制 没有 按比例 + 自动回滚

常见问题

Q:模型转换成 ONNX 后,推理速度比原始 PyTorch 慢?

A:ONNX Runtime 的推理速度通常比 PyTorch jit 快,但 Web 端受限于 WebAssembly 和 WebGPU 的线程模型,不一定比原生快。如果 Web 端慢,建议检查是否跑在 CPU 后端上。

Q:移动端用 ONNX Runtime 还是 TFLite?

A:如果你的模型有 TFLite 版本且量化工具链成熟,TFLite 在 Android 上性能更好。ONNX Runtime 的优势是跨平台统一------Web 和移动端共用 ONNX 格式,减少维护成本。

Q:灰度发布的比例怎么定?

A:我的经验是第一阶段别超过 5%,而且最好选内部用户或者测试账号。第二阶段 20%,观察 24 小时。如果模型涉及生成式任务,我会在灰度期间加人工抽检,因为自动监控指标不一定能捕捉到"回答质量下降"这类问题。

局限性

总结

这条部署流水线的核心,是把「格式转换 → 多端适配 → 加载优化 → 灰度发布 → 版本管理」串成一条可复用的链路:ONNX 模型库作为唯一事实来源,Web 端和移动端共享同一份模型文件,灰度比例和版本号由远程配置中心统一控制。每一步都有对应的坑------格式转换的算子兼容、后端降级的资源泄漏、CDN 缓存导致的灰度失控、模型与代码版本错位------但踩过之后,多端部署就从"手动操作"变成了"一次配置、自动分发"。

这套方案有几个前提:

  • 用户量需要有一定规模------灰度发布和版本管理带来的复杂度,在日活几百的场景下收益不大,全量部署加手动回滚反而更省事。
  • 模型体积不能太大------超过两个 G 的模型在 Web 端加载体验很差,即使分片加载也扛不住。大规模模型建议走服务端推理。
  • 团队需有 DevOps 基础------CI/CD 流水线、远程配置中心、监控告警,这些基础设施缺了任何一个,部署流水线就跑不起来。

下一步我打算做的是模型蒸馏------把 5 亿参数模型蒸馏到 2 亿参数以下,这样移动端和 Web 端都能跑得更快,甚至不需要降级到 CPU。

相关推荐
深小乐1 小时前
用AI做了6首歌曲MV后,我最大的收获不是会做了,而是干中学
人工智能
郑午时光1 小时前
全球首发!2026年适合IP短剧长视频的AI视频生成工具,即梦seedance2.5轻松做短剧
人工智能·tcp/ip·音视频
智道天成1 小时前
浙江代办食品生产许可证怎么办理,哪些企业可以申请全程代办服务
人工智能
汇策研习社2 小时前
双指标共振交易体系:GMMA趋势骨架 + MACD动能验证实战全解
大数据·人工智能·信息可视化·金融·区块链·fastbull
皮皮虾❀2 小时前
阿里巴巴“千问办公”公测深度解析:企业级Agent如何重塑智能办公
人工智能·阿里云·云计算
G31135422732 小时前
大模型不可用时,业务还能不能继续:企业需要设计降级方案
大数据·服务器·数据库·人工智能·深度学习
TechEdu2026062 小时前
[人工智能]TensorFlow深度学习框架工程实践概览
人工智能·深度学习·ai·tensorflow
qq_454245032 小时前
大模型循环调用:从协议级到应用级的循环控制谱系
人工智能
万物皆智能2 小时前
AI合规面试:AI合规常见面试题与答题思路
人工智能·面试·职场和发展