从百度搜索到CV实战:一个算法工程师的视觉项目踩坑记

MQ堵车了
2026-02-09 03:07
阅读 3000

上周五晚上十一点,我还在工位上盯着终端里不断滚动的训练日志。窗外中关村的写字楼基本都熄了灯,只剩我们这层还亮着几盏——产品经理明天就要看Demo,而我的模型在测试集上mAP卡在0.68死活上不去。这种场景,在百度干了三年多的我早就习惯了。不过这次不一样,因为这是我第一次把计算机视觉(CV)项目从0做到1,而且用的还是最近刚上手的Rust + PyTorch组合。

为什么突然搞起了CV?

别误会,我在百度一直做搜索相关算法,主要是Query理解、相关性排序这些NLP向的任务。但去年双11前,老板突然拉了个新项目:给电商搜索结果加“以图搜图”功能。简单说,用户上传一张商品图,系统得找出最相似的商品。听起来很常规,但难点在于——延迟必须压到300ms以内,而且每天要处理上亿次请求。

“你不是喜欢折腾新技术吗?这个交给你了。”老板拍着我肩膀说的时候,我其实心里一万个草泥马。毕竟CV不是我的主战场,但转念一想:反正最近在考虑换环境,不如趁机拓宽技术栈,简历上也能多写点东西。

初期方案:拿书当枕头,边学边干

说实话,一开始我连YOLO和ResNet的区别都说不清。好在公司内网有大量技术文档,加上我翻出尘封已久的《深度学习计算机视觉实战》(一本被我当枕头用了半年的书),总算理清了基本思路。

我们的目标很明确:构建一个轻量级、高精度的图像特征提取模型。考虑到线上服务的延迟要求,不能直接上ViT或者Swin Transformer这种大模型。于是初步定了两个方向:

  • 基于MobileNetV3的轻量化CNN
  • 使用蒸馏技术压缩ResNet50

为了快速验证,我先用PyTorch搭了个baseline。数据集是内部脱敏的百万级商品图,标签是商品ID。这里不得不吐槽一下:标注质量堪忧,有些图里商品只占画面10%,还有反光、遮挡、多商品混拍……产品经理说“用户就这样拍的”,我只能苦笑。

训练过程:Bug比代码还多

写模型代码时,我习惯用 Amazon Q(AWS那个AI编程助手)来生成一些样板代码。比如数据加载器、损失函数配置这些重复性工作,它确实能省不少时间。但有一次它给我生成了个CrossEntropyLoss,而我实际需要的是TripletMarginLoss来做度量学习——差点跑偏一周。

真正头疼的是训练不稳定。初期loss震荡得像心电图,调了三天学习率、batch size、优化器都没用。最后发现是数据预处理的问题:部分图片的EXIF信息没处理,导致旋转方向错误。这种低级错误,放在搜索业务里根本不会出现,但在CV领域简直是家常便饭。

# 修复后的图像预处理(关键!)
def correct_image_orientation(img):
    try:
        exif = img._getexif()
        if exif:
            orientation = exif.get(274)
            if orientation == 3:
                img = img.rotate(180, expand=True)
            elif orientation == 6:
                img = img.rotate(270, expand=True)
            elif orientation == 8:
                img = img.rotate(90, expand=True)
    except (AttributeError, TypeError):
        pass
    return img

加了这段代码后,mAP直接从0.62跳到0.71。那一刻我真想冲进产品办公室大声喊:“你们的烂数据害我熬了三个通宵!”

模型部署:从Python到Rust的冒险

模型训练好了,但Python的推理速度在高峰期还是超时。运维同事甩给我一句:“再超时就滚去用C++。” 我一咬牙,决定试试最近在研究的 Rust。

Rust的内存安全和零成本抽象太香了,尤其适合做高性能推理服务。我用tch-rs(PyTorch的Rust绑定)重写了推理逻辑,配合actix-web做API服务。虽然学习曲线陡峭(光是所有权概念就让我debug到凌晨三点),但效果惊人:

方案 平均延迟(ms) P99延迟(ms) 内存占用(MB)
Python + Flask 420 850 1200
Rust + actix-web 180 320 450

上线那天,监控大盘绿得发亮,产品经理终于没来找我茬。更爽的是,Rust的编译期检查帮我避免了好几个潜在的内存泄漏——这在C++时代可是噩梦。

效果与反思

最终,这个“以图搜图”功能在双11当天扛住了流量洪峰,准确率(Top-5召回率)达到89.2%,延迟稳定在200ms左右。虽然离理想状态还有差距,但至少没让老板在复盘会上骂人。

回过头看,这个项目让我意识到:AI编程工具(如Amazon Q)能提升效率,但不能替代领域知识。比如,它不会告诉你EXIF方向问题,也不会建议你用ArcFace代替普通softmax。这些经验,只能靠踩坑积累。

另外,跨语言迁移(Python → Rust)虽然痛苦,但长远看非常值得。现在很多公司都在推Rust for AI Infra,掌握它对跳槽绝对是加分项——毕竟,谁不想在面试时说“我用Rust重构了核心推理服务,性能提升2倍”呢?

给想入坑CV的朋友几点建议

  1. 别迷信SOTA模型:在工业场景,稳定、可维护、低延迟比mAP高0.5个点重要得多。
  2. 数据质量 > 模型复杂度:花80%时间清洗和增强数据,比调参有效。
  3. 善用AI编程,但保持警惕:Amazon Q、GitHub Copilot能帮你写脚手架,但核心逻辑必须自己掌控。
  4. 多读经典书籍:像《深度学习计算机视觉实战》这类书,虽然厚,但能帮你建立系统认知,避免成为“调包侠”。

现在,我正用业余时间把这套流程开源,顺便写个Rust版的ONNX Runtime封装。如果顺利,说不定下个月就能在GitHub Trending上看到我的名字——当然,前提是产品经理别再半夜钉钉我改需求了。

深夜写代码的效率是真的高,但头发掉得也快。各位同行,保重身体,且行且珍惜。

评论 0

最热最新
暂无评论
MQ堵车了Lv.1
0
影响力
0
文章
0
粉丝