ZMonster's Blog 巧者劳而智者忧,无能者无所求,饱食而遨游,泛若不系之舟

对算法工程师一职的思考

如果要我想别人做自我介绍,那么大概我会这样来描述自己:

我是一个热爱幻想小说的理智而沉默的人,目前在一家在线教育公司中从事算法工程师一职。

然而有时候我发现自己并不能向别人很好地解释清楚”算法工程师“的具体含义,进而只好列举自己当前的工作内容。按理说作为算法工程师,我自己应该是对这个职位有足够的理解,但当我自问算法工程师究竟为何时,得到的也是含糊不清的回答。

我尝试去梳理自己对这个职位的理解,并记录下来,如果以后能一直从事相关工作,再回过头来看这篇文章,大概也会别有一番趣味。

从做过的工作说起

作为一个算法工程师的我,做过什么工作呢?从项目的角度上来说,主要有这么几个:

  • 说话人分割(Speaker Diarization): 对一段音频,确定 何人在何时说话
  • 情感识别: 对一段音频,判断说话者在其中表达的是 正面的情感 还是 负面的情感
  • 题库搜索
  • OCR
  • 学生能力评估

以上工作,都需要设计一个完整的算法或“系统”来去解决,然而这里作为一个具体解决方案的“算法”和“系统”,与普通的项目解决方案有什么本质上的区别呢?

第一点不同是,以上问题的“输入”都存在很大的不确定因素,而且对这些不确定因素不易检测和处理。对于普通的软件、APP以及网站来说,所谓的输入(主要为用户操作),是会限定在一个有限集合中的,因而可以按照设计好的逻辑进行处理;但在上述具体项目中,无法保证输入是符合要求的,对输入数据的处理(过滤、规整、变换)——即所谓的“预处理”是系统中的必需部分。

数据的预处理,在算法岗涉及的工作中,是非常重要的。核心的算法,在学术界的推动下,都有很多成熟、可靠的选择,但这些算法,往往都对输入的数据有严苛的要求,数据的预处理如果做得不好,再好的核心算法往往也无能为力。 但由于输入数据天然的不稳定性和复杂性,数据预处理往往也是烦琐而复杂的,需要根据实际的业务情况和数据情况设置各种各样的规则来处理。对于一些成熟的领域如语音、图像,异常数据的种类是有限的,因此也有通用的处理方法,所谓的“去噪”就是图像和语音识别中比较重要的预处理方法;但业务情况却随产品的定位和功能而千变万化,这就需要算法工程师对具体产品的业务有深入的理解。

以我做过的“说话人分割项目“来说,在预处理阶段,需要做这些事情:

  1. 音频格式转换

    收到的客户的音频数据往往格式杂乱,而且这些音频为了便于保存和传输,大都是经过压缩的格式,在进行转换后可能会有一定程度的失真。

  2. 去除明显的非人声和静音,所谓非人声包括: 通信噪音、场景噪音、音乐

    对于与人声不重叠的非人声,可以通过语音活性检测(Voice Activity Detection, VAD)来进行区分,难点在于如何处理与人声混杂在一起的噪声。

  3. 定位不同说话人连续语音的起始和结束点

    如果有两个人(甚至三个人以上)同时在说话,那么这个起始和结束点会不准确。

此外还有一些干扰情况,如音频是无效的、损坏的数据 —— 这种情况往往不多,但由于混杂在大量正常数据中,往往直到造成了问题才会被发现。

其他几个项目同样面临这个问题,甚至在一些项目上,数据如何才算有效、健康都尚待定义,这种情况数据预处理更为艰难。

但数据还不是影响算法工程师工作的首要环节,需求才是。

需求 > 数据 > 系统 > 算法

算法工程师,首先是作为工程师存在的,其工作成果当然也要为实际需求服务;其次,算法工程师的项目不会是孤立的,必然会和其他项目有关联。对项目提出的直接需求,以及对相关联项目的需求,都会对项目有很大影响:

  1. 需求会决定数据的来源和质量
  2. 需求会决定算法实现的复杂性

当然了,这一点不是算法工程师与其他开发人员的工作内容上的差异,因为其他开发人员同样要受到业务需求的影响。

也许有人会觉得算法工程师处理的问题都需要高深的理论基础,但其实不是的,或者说不单纯是。从项目实现角度上来说,现在已经有了非常多的、高效的系统和框架,各种具体的算法也有成熟的实现,单纯想要建立一个解决问题的系统,非算法工程师只要了解一下相关的专有名词,根据业务需求调研使用何种框架或库,熟读相关的文档和 tutorial,也是可以做到的。但得到一个基本可用的系统后,由于之前提到的数据问题,以及系统本身的问题,是无法得到完美的结果的,需要通过大量数据进行持续的调优,而这个过程,是需要对业务情况和相关理论有较深的理解的。

这是第二点不同,即项目需要使用大量的数据进行长期的观察、优化,从一个基本可用的项目到一个令人满意的项目,中间往往需要比较长的时间。

以上是个人根据自身经历得到的一些体会。

再谈这个职位

由于无法进行快速迭代,算法工程师的工作强度不算太大(相对而言),而且一般待遇不错,这算是这个职位的优点了。而相对的,算法工程师的工作会比较枯燥,远没有外行人所想象的那么“酷”,而且大部分时间是在做工程化和调优,其实并没有太多时间去做探索性的工作。

在我看来,要做好算法工程师的工作,首先确实需要有一定的理论基础,其次应该要一定的数据处理能力和意识,然后要有足够的耐心。另外一些人对算法工程师工作的看法的一个误区是,太过重视某种流行的模型、方法的作用,接触到问题后就想直接套用某个模型 —— 选择使用什么模型、方法应当慎之又慎,至少应当在对业务和数据有足够多的认识后再做决定,并且要有全局性的思维,从数据处理,特征工程,到模型,到结果解释,要对各个环节都有考虑。