1. 从一根漏水的水管说起:AquaPulse 到底想解决什么问题
城市供水管网有个很反直觉的事实:漏损率长期居高不下,很多老城区的管网漏损能到20%甚至更高。也就是说,水厂送出去十吨水,有两吨在到达用户水表之前就已经渗进地下或者白白流走了。传统做法是靠人工巡检、听漏棒、分区计量(DMA)来定位漏点,但这些东西要么依赖老师傅的耳朵,要么需要大范围停水做对比测试,响应周期动辄几天甚至几周。
AquaPulse 这个项目标题里的三个词其实已经把答案说得很清楚了:Aqua(水)+ Pulse(脉冲/脉动)+ Edge AI(边缘智能)。它想做的事情,是把振动传感、声学采集和边缘推理塞进一个贴在管道外壁的小盒子里,让管道自己"说话"——通过持续监测管壁的振动频谱,在本地判断有没有异常泄漏、管道结构是否劣化,只把结论和关键特征上传,而不是把原始音频全部回传。
这套思路解决的核心痛点有三个。第一是带宽和功耗,一根主管道如果按48kHz采样率持续上传原始音频,一天的数据量轻松上GB,电池根本扛不住,4G/NB-IoT的流量费也吃不消。第二是响应延迟,漏水是持续恶化的过程,早一小时发现可能只是换个卡箍,晚一周可能就是路面塌陷。第三是隐私与合规,管道沿线的声学数据里可能混入人声、车辆等环境音,原始数据不出本地是更稳妥的做法。
适合读这篇内容的人,我大致分三类:一是做智慧水务、市政物联网的工程师,想了解边缘AI在管网场景怎么落地;二是嵌入式/AI方向的开发者,手上有类似"传感器+边缘推理"的项目,想抄一套可复现的架构;三是对 Edge AI 感兴趣、最近在折腾 Google AI Edge Gallery 这类端侧模型工具链的玩家,想看看真实工业场景里端侧模型是怎么被约束和优化的。不管你基础如何,我都会把原理、选型、参数计算和踩坑经验讲透,尽量让你看完能直接动手。
2. 整体架构设计:为什么把智能放在管道边上
2.1 边缘优先的架构取舍逻辑
AquaPulse 最核心的设计决策就是"边缘优先"。我见过不少同类项目一开始图省事,传感器只管采集,数据全部丢到云端跑模型,结果上线三个月就撑不住了。原因很现实:管道监测点是分散的,一个城市几百上千个点位,每个点位持续上传高频振动数据,光是网络成本就能吃掉整个项目的预算。
边缘优先的架构可以拆成四层。感知层是贴在管壁上的压电式振动传感器或MEMS加速度计,负责把管壁的机械振动转成电信号。边缘层是一块带MCU或轻量NPU的板子,做信号调理、特征提取和本地推理。通信层用NB-IoT或LoRa这类低功耗广域网,只在有事件或定时上报时传少量数据。云端层负责多点位数据聚合、长期趋势分析、模型迭代下发和告警工单派发。
这个分层的关键在于:把"高频、海量、实时"的处理留在边缘,把"低频、聚合、全局"的分析放到云端。振动信号的特征提取和异常判断是高频实时的,必须本地做;而"这条街过去三个月漏点频发,是不是该整体换管"这种判断需要跨点位、跨时间的数据,放云端更合适。
2.2 端侧模型选型的现实约束
选什么模型,不是看哪个精度高,而是看你的硬件能给多少算力、多少内存、多少电。AquaPulse 这类场景的典型约束是:MCU级设备内存可能只有几百KB到几MB,NPU算力在0.1到1 TOPS之间,电池要撑一到三年。
在这种约束下,我一般推荐两条路线。第一条是传统信号处理+轻量分类器:先用FFT或小波变换把振动信号转成频谱特征,再用一个几十KB的决策树或小型神经网络做分类。这条路的好处是算力需求极低,可解释性强,出问题好排查。第二条是端侧CNN或TinyML模型:直接把一段时域波形或频谱图喂给量化后的卷积网络,端到端出结果。这条路精度上限更高,但对内存和算力要求也更高。
最近 Google AI Edge Gallery 这类工具火起来,其实给端侧模型部署提供了不少便利——它把模型转换、量化、在设备上跑推理的流程做得比较顺,你可以先在手机上验证模型效果,再迁移到嵌入式设备。不过要注意,Gallery 上的模型大多是视觉和语言类的,声学振动这块还是得自己训、自己量化,工具链可以借鉴,模型不能直接拿来用。
2.3 通信与供电方案怎么定
通信方案的选择直接决定了整个系统的续航和成本。我做过一个粗略的对比,假设每个点位每天上报20次、每次200字节,几种方案的差异很明显:
| 方案 | 单次传输功耗 | 覆盖能力 | 适合场景 | 备注 |
|---|---|---|---|---|
| NB-IoT | 中等 | 强,室内外均可 | 城市管网、地下井 | 需运营商网络,有月租 |
| LoRa | 低 | 中等,需网关 | 园区、郊区管网 | 自建网关,无月租 |
| 4G Cat-1 | 高 | 强 | 有市电的点位 | 功耗大,不适合电池供电 |
| 有线/RS485 | 极低 | 受布线限制 | 泵房、厂区内部 | 稳定但部署成本高 |
供电这块,如果点位附近有市电,直接用市电+超级电容做掉电保护最省心。如果是纯电池场景,就得算清楚功耗预算:假设用一节3.6V/19Ah的锂亚电池,设备平均功耗要控制在0.5mW以内才能撑五年。这意味着MCU大部分时间必须处于深度睡眠,靠传感器的硬件中断或定时器唤醒,醒来后快速采集、快速推理、快速上报,然后立刻睡回去。
提示:电池供电的点位,千万不要让传感器持续供电采集。压电传感器本身不耗电,但后面的运放和ADC是耗电大户,一定要用MCU的GPIO控制它们的供电,做到"用时才通电"。
3. 核心细节拆解:从振动信号到泄漏判断
3.1 振动信号里到底藏着什么信息
管道泄漏的本质,是高压水从破口喷出时产生的高频湍流和管壁的受迫振动。这个振动信号有几个特征:频率集中在特定频段(通常泄漏噪声在几百Hz到几kHz之间,具体和管径、压力、材质有关),能量随距离衰减,在时域上表现为持续的宽带噪声。而正常的管道振动主要来自水流本身、水泵、阀门操作和外部环境,频率和时域特征都不一样。
所以泄漏检测的核心,就是从混合振动信号里把泄漏特征分离出来。这里有个经验:金属管道的泄漏信号频率偏高、衰减快,塑料管道(PE/PVC)的泄漏信号频率偏低、传播远。做特征提取时,采样率至少要覆盖到目标频段的两倍以上,一般选8kHz到48kHz之间。如果只关心低频泄漏特征,8kHz采样率配一个抗混叠滤波器就够了,能省不少算力和存储。
3.2 特征提取:FFT、小波还是直接上CNN
特征提取是端侧推理前最关键的一步,选错了后面全白搭。我按实际用过的顺序说一下。
FFT频谱特征是最经典的。把一段1024或2048点的时域信号做FFT,得到频谱,然后提取几个关键指标:特定频段的能量占比、频谱质心、频谱带宽、峰值频率。这些指标加起来可能就十几个浮点数,喂给一个简单分类器就能出结果。优点是计算量小、可解释,缺点是丢失了时间信息,对瞬态事件不敏感。
小波变换适合捕捉瞬态和突变。泄漏刚开始时往往有一个冲击特征,小波能同时在时域和频域定位这个突变。但小波的计算量比FFT大,端侧实现要小心。
端到端CNN是最近几年流行的做法。直接把一段时域波形或者频谱图(把连续多帧FFT拼成二维图)喂给卷积网络。这条路省去了手工特征工程,但需要更多训练数据和更强的算力。我的建议是:如果MCU算力在100MHz以下、内存小于512KB,老老实实用FFT+轻量分类器;如果有NPU或者算力在几百MHz以上,可以尝试量化后的TinyML CNN。
3.3 端侧推理的量化与内存优化
模型训练好只是第一步,能不能塞进设备才是关键。端侧部署绕不开量化。浮点32位模型转成int8量化模型,体积能缩小到四分之一,推理速度提升2到4倍,精度损失通常在1%到3%之间,对泄漏检测这种二分类/多分类任务完全可接受。
量化的具体操作,以TensorFlow Lite为例,大致流程是:训练时用浮点模型,导出SavedModel,然后用TFLite转换器做训练后量化(Post-Training Quantization),提供一个代表性数据集让转换器校准量化参数。如果精度掉得太多,就用量化感知训练(QAT),在训练阶段就模拟量化误差,让模型自己适应。
内存优化还有几个技巧。一是算子融合,把卷积、批归一化、激活函数融合成一个算子,减少中间张量的内存占用。二是内存复用,让不同层的中间结果共用同一块内存。三是模型剪枝,把不重要的权重置零,稀疏化后再压缩存储。这些操作在TFLite Micro和CMSIS-NN里都有现成支持。
注意:量化校准用的代表性数据一定要覆盖真实场景的各种工况——不同压力、不同流量、有泄漏和无泄漏、不同环境噪声。如果校准数据太单一,量化后的模型在真实场景里会崩得很惨。
4. 实操过程:从零搭一个 AquaPulse 原型
4.1 硬件选型与信号链路搭建
先说硬件。传感器我推荐压电式振动传感器,比如常见的压电陶瓷片或者工业级加速度计。压电式的灵敏度高、频响宽、本身不耗电,缺点是输出阻抗高,需要配合电荷放大器或高输入阻抗的运放。如果预算充足,用IEPE加速度计更省心,但需要恒流源供电,功耗上去了。
信号链路是这样的:传感器 → 电荷放大器/运放 → 抗混叠低通滤波器 → ADC → MCU。抗混叠滤波器的截止频率设在采样率的一半以下,比如采样率16kHz,截止频率就设7kHz左右,用二阶或四阶巴特沃斯滤波器。这一步千万别省,否则高频噪声混叠进来,频谱全是假的。
MCU选型看算力需求。如果只做FFT+决策树,一颗Cortex-M4F(比如STM32F4系列)就够了,主频100MHz左右,带FPU做浮点FFT很快。如果要跑量化CNN,选带NPU的MCU或者Cortex-M7,比如STM32H7或者带Ethos-U55的芯片。开发板阶段我建议先用STM32F4 Discovery或者nRF52840 DK,便宜、资料多、社区活跃。
4.2 数据采集与标注的实操细节
数据是这类项目的命根子。没有真实泄漏数据,模型就是空中楼阁。我的做法是搭一个小型测试台:一段几米长的PVC管或金属管,一端接自来水,中间装一个可调节的模拟泄漏阀(用针阀或小孔板模拟不同大小的漏口),另一端封堵。传感器贴在管壁上,距离漏点不同位置各贴一个,采集不同压力、不同漏口大小、不同距离下的振动数据。
采集时要注意几点。采样率固定,别一会儿8k一会儿48k,后期处理会乱。每段数据要有元信息:压力、流量、漏口大小、传感器距离、管道材质、环境温度。无泄漏的基线数据也要采,而且要采够,因为真实场景里99%的时间是无泄漏的,模型必须学会不误报。环境噪声要单独采:旁边走过人、车辆经过、水泵启停,这些都要录进去当负样本。
标注相对简单,因为是受控实验,每段数据对应什么工况是已知的。但真实部署后会有概念漂移——管道老化、季节变化、用水模式改变都会让数据分布变化,所以模型要定期用新数据微调。
4.3 模型训练、量化与部署的完整流程
训练阶段,我一般先用Python在PC上把流程跑通。用librosa或scipy做特征提取,用scikit-learn或PyTorch训模型。特征提取的代码大概长这样:
import numpy as np from scipy.fft import rfft, rfftfreq def extract_features(signal, fs=16000, nperseg=2048): # 分帧 frames = [signal[i:i+nperseg] for i in range(0, len(signal)-nperseg, nperseg//2)] feats = [] freqs = rfftfreq(nperseg, 1/fs) for frame in frames: # 加汉宁窗 windowed = frame * np.hanning(len(frame)) spectrum = np.abs(rfft(windowed)) # 提取特征:频段能量占比、质心、带宽、峰值频率 band_energy = np.sum(spectrum[(freqs>500)&(freqs<3000)]) total_energy = np.sum(spectrum) + 1e-9 centroid = np.sum(freqs * spectrum) / total_energy bandwidth = np.sqrt(np.sum(((freqs-centroid)**2) * spectrum) / total_energy) peak_freq = freqs[np.argmax(spectrum)] feats.append([band_energy/total_energy, centroid, bandwidth, peak_freq]) return np.array(feats)模型先用一个简单的全连接网络或一维CNN,训练到验证集准确率95%以上。然后导出成TFLite,做int8量化:
import tensorflow as tf converter = tf.lite.TFLiteConverter.from_saved_model('saved_model') converter.optimizations = [tf.lite.Optimize.DEFAULT] converter.representative_dataset = representative_data_gen converter.target_spec.supported_ops = [tf.lite.OpsSet.TFLITE_BUILTINS_INT8] converter.inference_input_type = tf.int8 converter.inference_output_type = tf.int8 tflite_quant_model = converter.convert() open('aquapulse_int8.tflite', 'wb').write(tflite_quant_model)部署到MCU时,用TFLite Micro或者CMSIS-NN。TFLite Micro的推理代码框架是:加载模型数组 → 创建解释器 → 分配张量内存 → 设置输入 → 调用Invoke → 读输出。CMSIS-NN则针对Cortex-M做了汇编级优化,同样的模型能快不少,但需要手动把算子映射过去,工作量大一些。
4.4 功耗预算与续航估算
电池供电的点位,功耗预算必须提前算清楚。假设用STM32L4系列(低功耗M4),工作模式电流约10mA,深度睡眠电流约1μA。每次采集+推理耗时200ms,每天触发20次,上报用NB-IoT每次约2秒、峰值电流200mA。
算一下日均功耗:工作部分 10mA × 0.2s × 20次 = 40mA·s;上报部分 200mA × 2s × 20次 = 8000mA·s;睡眠部分 0.001mA × 86400s ≈ 86mA·s。总计约8126mA·s,换算成mA·h是8126/3600 ≈ 2.26mAh/天。用19Ah的锂亚电池,理论续航约8400天,也就是23年——当然这是理想值,实际要考虑电池自放电、温度影响、NB-IoT信号差时的重传,打个三折也有六七年,完全够用。
提示:NB-IoT上报是功耗大头,能合并上报就合并,能降低上报频率就降低。很多项目失败就败在通信功耗上,不是推理功耗。
5. 常见问题与排查技巧实录
5.1 误报和漏报怎么破
误报和漏报是这类系统最头疼的问题。误报多了,运维人员就不信任系统了,直接忽略告警;漏报多了,系统等于没用。我踩过的坑里,误报主要来自几个源头:环境噪声(车辆、施工、水泵启停)、传感器松动(耦合变差导致信号异常)、温度漂移(影响传感器灵敏度)。
解决办法是多特征联合判断+时间持续性验证。单一特征容易误判,但如果是真泄漏,多个特征会同时异常,而且会持续存在。我一般要求连续多个采集周期(比如连续5次,每次间隔10分钟)都判定为异常,才触发告警。这样能过滤掉大部分瞬态干扰。另外,传感器安装要用耦合剂或者磁吸底座,确保接触良好,安装后要采集基线数据做校准。
漏报主要来自模型泛化不足。训练数据里没有的漏口大小、没有的管道材质,模型就识别不出来。对策是数据增强:在已有数据上做加噪、变速、频移,模拟更多工况;以及在线学习:把现场确认的漏点数据回传,定期重新训练模型。
5.2 端侧模型精度掉点的排查思路
模型在PC上准确率95%,部署到设备上掉到80%,这种情况太常见了。排查顺序我一般是这样的:
| 排查项 | 可能原因 | 验证方法 |
|---|---|---|
| 输入数据 | 端侧特征提取和PC不一致 | 同一段原始数据,两端跑特征,逐值对比 |
| 量化误差 | int8量化损失过大 | 用浮点模型在设备上跑,看精度是否恢复 |
| 内存越界 | 张量内存分配不足 | 检查解释器分配的arena大小是否够 |
| 算子不支持 | 某些算子回退到浮点 | 查看TFLite Micro的算子支持列表 |
| 数值溢出 | int8累加溢出 | 检查中间层输出范围,必要时用int16累加 |
最常见的是第一条和第二条。特征提取不一致,往往是窗函数、帧移、归一化方式在两端实现不同。量化误差大,就上量化感知训练,或者对敏感层保留浮点。
5.3 现场部署的独家避坑经验
现场部署和实验室完全是两回事。分享几个我踩过的坑。
第一,管道材质和管径要提前确认。金属管和塑料管的振动传播特性差异巨大,模型不能通用。部署前一定要拿到管网的材质、管径、压力、埋深信息,最好能现场采一段基线数据。
第二,传感器安装位置有讲究。要贴在阀门、弯头、三通这些"节点"附近,因为这些地方振动信号强、传播路径清晰。直管段中间信号衰减大,不推荐。安装前要打磨管壁、涂耦合剂,用卡箍或磁吸固定牢。
第三,防水和防腐要做足。地下井里潮湿、有腐蚀性气体,设备外壳至少IP67,接线端子要灌胶。我见过设备装上去三个月就因为进水报废的。
第四,通信信号要实测。地下井里NB-IoT信号可能很弱,部署前用测试设备实测信号强度,弱的地方要么加天线延长线,要么换LoRa自建网关。
第五,告警阈值要现场调。实验室定的阈值到了现场可能完全不适用,因为背景噪声水平不一样。部署后要跑一到两周的观察期,根据实际数据调整阈值。
5.4 模型迭代与长期运维
系统上线不是终点,而是起点。管道会老化,用水模式会变,模型必须持续迭代。我的做法是建立一个数据回流闭环:现场确认的漏点、误报、漏报数据,都带上标签回传到云端;云端定期(比如每季度)用新数据重新训练模型,量化后通过OTA下发到设备。
OTA升级要注意几点:差分升级省流量,只传模型变化的部分;双分区备份,升级失败能回滚;分批灰度,先升10%的设备,观察一周没问题再全量。这些在嵌入式里都有成熟方案,别自己造轮子。
另外,设备的健康状态也要监控。电池电压、信号强度、传感器阻抗、推理耗时,这些指标定期上报,能提前发现设备异常。我一般设几个阈值:电池电压低于3.0V告警,信号强度低于-120dBm告警,推理耗时超过500ms告警。
6. 这套方案还能怎么扩展
AquaPulse 这套"振动传感+边缘AI"的框架,其实不只能做漏水检测。同样的思路可以迁移到很多场景:管道结构健康监测(检测管壁腐蚀、裂纹)、水泵故障预警(通过振动频谱判断轴承磨损、叶轮不平衡)、阀门内漏检测(阀门关闭后仍有流量振动特征)。核心逻辑是一样的——把机械振动信号转成特征,用端侧模型做分类或异常检测。
硬件上也有优化空间。比如用多传感器阵列做波束成形,判断泄漏信号的方向,从而定位漏点位置而不只是判断有无泄漏。再比如用能量采集(管道振动本身就能发电)给设备供电,彻底摆脱电池更换的麻烦。这些方向我都在关注,有些已经在做原型验证。
如果你正在做类似的项目,我的建议是先把最小可用原型跑通——一个传感器、一块开发板、一个简单的分类模型,能在实验室里区分"有漏"和"无漏"就行。然后再逐步加特征、加模型复杂度、加通信和云端。别一上来就追求大而全,那样很容易卡在某个环节出不来。端侧AI这东西,跑通比跑好重要得多,先让它动起来,再慢慢优化。