ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

HarmonyOS 7离线重建 vs 在线重建的能力边界

HarmonyOS 7离线重建 vs 在线重建的能力边界

我们做文物保护的客户提了个需求:野外文物采集,地点在山区没信号,3DGS 重建能不能纯离线跑。我们一开始拍胸脯说能——Spatial Recon Kit 是端侧重建,端侧就是离线。真到山里测才发现,端侧重建的某些环节偷偷要联网:特征提取用的模型默认从云端拉,离线时直接失败。这篇文章记录我们把重建流程的联网依赖摸清楚,做离线兜底,以及离线模式下质量和功能掉多少。

能力面:哪些环节要联网,哪些不要

3DGS 端侧重建的五个阶段(采集/特征提取/点云初始化/优化/导出),我们逐个测了断网情况下的行为。

阶段默认是否联网联网用途离线能否跑
采集否无能
特征提取是拉特征提取模型默认不能,需预置模型
点云初始化否无能
优化否无能
导出否无能
质量评估(可选)是拉评估模型默认不能,需预置模型

只有特征提取和可选的质量评估要联网。其他阶段纯端侧计算,断网不影响。问题出在特征提取——它用的 SfM 特征提取模型默认从云端拉,第一次使用时下载到本地缓存,之后用缓存。但第一次使用时断网就直接失败,不会等有网再试。

// entry/src/main/ets/offline/OfflineReconSetup.etsimport{spatialRender}from'@kit.SpatialReconKit';import{fileIo}from'@kit.FileKit';exportclassOfflineReconSetup{// 检查离线重建所需的本地资源是否就绪staticasynccheckReadiness():Promise<OfflineReadiness>{constchecks:OfflineReadiness={featureModel:false,assessModel:false,storageSpace:false};// 1. 特征提取模型是否已缓存到本地// 路径在应用沙箱 files/recon/models/feature.binconstmodelPath:string=`${getContext().filesDir}/recon/models/feature.bin`;try{conststat=awaitfileIo.statSync(modelPath);// 模型文件约 12 MB,小于 1 MB 认为未下载完整checks.featureModel=stat.size>1*1024*1024;}catch(e){checks.featureModel=false;}// 2. 质量评估模型(如果用端侧 NRQA)constassessPath:string=`${getContext().filesDir}/recon/models/assess.bin`;try{conststat=awaitfileIo.statSync(assessPath);checks.assessModel=stat.size>1*1024*1024;}catch(e){checks.assessModel=false;}// 3. 存储空间是否够(重建结果 + 中间张量,至少 500 MB)constfreeBytes:number=awaitgetFreeStorage();checks.storageSpace=freeBytes>500*1024*1024;returnchecks;}// 在有网时预拉模型,之后离线可用staticasyncprefetchModels():Promise<void>{// 触发一次特征提取,Kit 会自动下载并缓存模型// 用一张 1x1 占位图触发,目的是拉模型不是真重建constplaceholder:string='OhosRawFile://placeholder/1x1.png';constsession=awaitspatialRender.ReconSession.create({offline:true// 标记预拉模式,失败不抛异常});awaitsession.warmupModels();awaitsession.release();}}

prefetchModels要在有网时调一次,之后离线就能跑。我们把它放在应用首次启动时,用户有网时静默预拉,用户无感。野外采集前要确认这一步跑过,否则到了山里第一次重建就失败。

约束面:离线模式的功能缺失

离线不只是"能不能跑",还有"跑起来和在线有没有差"。我们对比了离线和在线模式下重建结果的质量和功能。

维度在线模式离线模式差异原因
特征提取模型最新版(云端拉)缓存版(可能旧)模型更新滞后
重建质量SSIM 0.88SSIM 0.84旧模型特征点少 15%
重建耗时6320 ms6800 ms离线模型未做端侧算子优化
质量评估可用不可用(模型未预置)评估模型大,没默认预置
模型更新自动需有网时手动触发离线无法拉新模型
错误恢复可查云端诊断只看本地日志无远程协助

离线模式重建质量降一档——SSIM 从 0.88 降到 0.84。原因是离线用的特征提取模型是缓存版,可能不是最新。云端模型迭代更新,离线缓存停在最后一次有网时的版本。我们测的范围内最新模型比缓存版特征点多 15%,重建质量更好。

质量评估在离线模式下不可用。第 36 篇说的 SSIM/PSNR 评估需要 holdout 帧对比,这部分纯端侧不联网。但如果用端侧 NRQA 模型(无参考评估),那个模型要单独预置,默认不预置(模型 8 MB,占空间)。我们的选择是离线时只用 SSIM/PSNR,不用 NRQA,够用。

场景落地:野外文物采集

我们跟文物保护客户去了一趟山区,采集一尊露天石佛。地点确实没信号,全程离线。

真机数据:离线 vs 在线重建对比

指标离线重建(山区现场)在线重建(回办公室重跑)
采集时长42 秒42 秒(同素材)
特征提取耗时1620 ms1380 ms
点云初始化耗时880 ms780 ms
优化耗时4100 ms3800 ms
导出耗时360 ms320 ms
重建总耗时6960 ms6280 ms
SSIM0.830.87
PSNR27.2 dB28.8 dB
文件体量14.2 MB13.8 MB

离线重建总耗时多 11%,SSIM 低 0.04,PSNR 低 1.6 dB。质量差异肉眼可辨——离线重建的石佛表面纹理略糊,在线重建的更清晰。客户问能不能接受,我们说能——野外采集的目的是留档,不是展示,质量差一档但够用。如果要做展陈级展示,回办公室用在线模式重跑一遍。

真机数据:模型版本对质量的影响

我们测了三个版本的特征提取模型,看版本差异多大。

模型版本发布时间特征点数SSIM离线可用
v2.1(最新)2026-0941000.88需有网拉
v2.02026-0638000.86已缓存
v1.92026-0335000.83旧设备缓存

模型版本差一档,SSIM 差 0.02-0.05。野外采集那次离线用的是 v2.0,比最新 v2.1 差 0.02,可接受。但如果设备缓存停在 v1.9,差 0.05 就比较明显了。离线模式的质量取决于上次有网时拉的是哪个版本,这不可控。

我们的处理是应用启动时如果有网,静默检查模型版本并更新。这样保证离线时用的是最新缓存版。但用户如果长期不联网(比如山区驻留一周),期间模型有更新也拿不到。

踩坑与取舍

坑一:以为全离线可用,结果特征提取要联网模型

这是开头说的痛。我们以为端侧重建就是离线重建,没做联网依赖排查。到了山区第一次重建直接失败,错误信息是"feature model download failed",才知道特征提取要联网拉模型。

教训:端侧 ≠ 离线。端侧指的是计算在设备上完成,离线指的是不依赖网络。端侧重建的某些环节(模型加载)可能依赖网络,要逐环节排查。排查方法就是断网跑一遍,看哪步失败。

坑二:离线模式质量降一档,客户预期没对齐

我们跟客户说"端侧重建可以离线跑",客户理解成"离线跑和在线跑一样好"。实际离线质量降一档,客户看到结果觉得"你们说能离线怎么质量差了"。

问题出在沟通没区分"能跑"和"跑得好"。能跑是功能问题,跑得好是质量问题。离线模式能跑,但质量降一档。后来我们改成"离线可跑,质量约为在线的 95%,展陈级需回在线重跑",客户接受。

坑三:模型预拉时机错了

最初把prefetchModels放在用户点"开始采集"时调,结果用户在山区点采集时触发预拉,没网直接失败。预拉要在用户有网时做,不是要用了才拉。

改成应用首次启动时静默预拉,但有用户首次启动时也没网(开箱即用场景),预拉失败。最后加了预拉失败时的引导:“本次采集需要离线模型,请先在有网环境打开应用一次”。引导跳转到模型下载页,等有网时下载。

坑四:被放弃的方案——把模型打进 APK

想过把特征提取模型直接打进 APK,省去预拉步骤。模型 12 MB,APK 从 80 MB 涨到 92 MB。问题是模型更新要发版——云端模型迭代更新,打进 APK 就只能跟版本走,用户不更新 APK 就用旧模型。

权衡后放弃了。预拉方案虽然要用户有网时打开一次,但模型能自动更新,长期看模型版本更新。APK 打包模型适合模型不更新的场景,3DGS 特征提取模型还在迭代,不适合。

坑五:存储空间检查漏了中间张量

离线采集时用户会连续重建多个文物。我们只检查了"重建结果存储空间",没算"中间张量临时占用"。中间张量一个重建约 300 MB,连续重建 5 个就是 1.5 GB 临时占用,加上结果文件,存储爆了。

修复是重建完立刻释放中间张量(Kit 提供session.releaseIntermediate()),并检查剩余空间不足 500 MB 时提示用户清理。这个坑在离线场景特别容易踩,因为离线用户倾向一次性多采集几个。

离线重建的完整流程

把上面的坑都填了,离线重建的完整流程是这样:

// entry/src/main/ets/offline/OfflineReconFlow.etsexportclassOfflineReconFlow{staticasyncrun(videoUri:string):Promise<ReconResult>{// 1. 离线就绪检查constreadiness:OfflineReadiness=awaitOfflineReconSetup.checkReadiness();if(!readiness.featureModel){thrownewError('特征提取模型未就绪,请先在有网环境打开应用');}if(!readiness.storageSpace){thrownewError('存储空间不足,需至少 500 MB 可用空间');}// 2. 创建离线 sessionconstsession=awaitspatialRender.ReconSession.create({offline:true,// 强制离线,不尝试联网config:AdaptiveReconConfig.build(/* frameCount */90,/* coverage */0.8)});try{// 3. 执行重建,各阶段耗时埋点constprofiler=newReconProfiler();profiler.attach(session);constresult=awaitsession.start(videoUri);// 4. 离线质量评估(仅 SSIM/PSNR,不用 NRQA)constquality=awaitQualityAssessor.assess(result.gsNode,result.holdoutFrames);console.log(`offline recon SSIM:${quality.ssim}`);// 5. 立刻释放中间张量,避免连续重建存储爆awaitsession.releaseIntermediate();return{result,quality,timings:profiler.getReport()};}finally{awaitsession.release();}}}

注意offline: true这个参数。不传或传 false 时,Kit 会尝试联网拉模型,离线场景下这次联网尝试会超时(默认 30 秒)才失败,用户等 30 秒看到错误,体验差。传 true 时直接走本地缓存,不尝试联网,失败立刻返回。

离线链路和在线链路的第一个岔口是有没有网。把判定画出来,才能看出预拉为什么必须提前做。

有网络

无网络

已预拉

未预拉

发起重建请求

当前是否有网络

拉取最新特征模型

执行在线重建

在线评估并上传诊断

特征模型是否已预拉

创建 offline 为 true 的 session

执行离线重建 质量降一档

只用 SSIM 和 PSNR 评估

重建完释放中间张量

提示先在有网环境打开应用

引导跳转模型下载页

图里最容易被忽略的是未预拉分支。它不报错,只是提示用户联网,避免线上 30 秒超时。

离线/在线能力对比

能力在线模式离线模式
重建支持支持(质量降一档)
质量评估 SSIM/PSNR支持支持
质量评估 NRQA支持不支持(模型未预置)
模型自动更新支持不支持
错误远程诊断支持不支持
多次连续重建支持支持(需主动释放中间张量)
首次使用直接可用需先在有网环境预拉模型

离线模式的能力缺失主要在模型更新和远程诊断,重建本身能力完整。如果接受质量降一档,离线模式可用。

小注意下哦

  • 端侧 ≠ 离线,特征提取默认要联网拉模型,离线前要预置模型
  • 模型预拉要在有网时做,不能等要用了才拉,应用首次启动静默预拉
  • 离线模式重建质量约为在线的 95%,SSIM 差 0.02-0.05,肉眼可辨
  • 离线模式 SSIM/PSNR 评估可用,NRQA 不可用,NRQA 模型默认不预置
  • offline: true要显式传,不传时 Kit 会尝试联网超时 30 秒才失败
  • 连续重建要主动释放中间张量,单次重建中间张量 300 MB,不释放会爆存储
  • 模型打进 APK 不适合迭代场景,特征提取模型还在更新,预拉方案更灵活
  • 离线存储空间检查要算中间张量,不能只算结果文件,单次重建需 500 MB 余量
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进