心法利器
本栏目主要和大家一起讨论近期自己学习的心得和体会。具体介绍:仓颉专项:飞机大炮我都会,利器心法我还有。
2023年新的文章合集已经发布,获取方式看这里:又添十万字-CS的陋室2023年文章合集来袭,更有历史文章合集,欢迎下载。
往期回顾
今天想要聊的是最近领悟的一项新的思维方式,是在项目内逐步探索发现的,就是要有迭代和发展的思维方式。
这次也算是试试水,做一次尝试,写一下日常方案设计过程中的一些方法论,看大家是否感兴趣,如果喜欢我会多写点。
在这里,我先把这个“迭代的思维方式”展开解释一下,我这里是指,对于一个任务,在并不容易一次性解决的时候要把他拆解成逐步推进各个击破的长期任务,至于这里怎么拆,如何设计和推进,看我后面慢慢解释。
思路的来源
最近是在做一些大方案的技术设计,在设计过程汇总,会发现很多很好的方案,在现阶段可能并没有很好的落地条件,总结下来,包括但不限于下面原因:
数据层面的基础工作不够。现实上,缺少标注数据,某些数据尚未积累,数据表还没建立,某些数据甚至还没打通,理想上的数据理解尚未到位。
工程技术尚未成熟,某些算法工程做需要依赖工程支持,除了上面可能有涉及的埋点,还有类似AB实验工程、某些用户行为方案没上线、机器资源等。
大而复杂的模型,影响因素过多,可能会出现众多的问题,模型结构、数据集、训练、测试等,出现问题后难以定位,直接上线的成本高。
当下问题的现状,复杂模型或者方案下,能解决的问题很多,他是解决综合问题的一个组合解,并没有那么对症,然而在现实中,我们需要了解到当下环境的核心痛点,因地制宜(这个词我好像也在公众号里反复提到过),才能更高效,也更有利于推进解决问题。
人的问题,合作起来存在一定困难,分工难以平衡,设置可能会影响一些人的利益(如工作被合并),从而出现困难或者未知风险。
在这里列举下来,也是希望大家能够理解这个迭代思路的核心来源,让大家在设计方案时能够更留意到这些问题,以便进一步推进。
因此在项目实施过程,直接把一些现行看到的很好的方案直接落地,而需要有计划地拆解,找到合适的切入点,逐步迭代完成最终的落地实施。
概述这个思路的核心点
这只是一个比较宏观的方法论,在运用过程,要注意的部分我先列举出来,然后后面逐步展开解释。
明确最终愿景和形态。明确适合这个场景的最终方案。
了解现状。现状是一个广义概念,里面包含的东西很多,项目现状、资源现状、研究现状等。
以痛点为出发点,配合现有资源的情况,开始初始方案。
方案的设计,除了要求解决当下痛点,还要考虑逐步满足达成最终方案的条件。
维持稳定增长的技术储备。
我理解的核心点就是上面这些,后面我会逐步展开解释。
明确最终愿景和形态
这里强调“最终”,就是因为我们需要一个最终的目标。目标的重要性已经在管理学、哲学等多门学科里被强调多次重要性,在这里,也仍旧需要强调。
这里的最终愿景要明确清楚,可以通过回答以下问题来实现:
你做的是一个什么项目,最根本的是要解决什么问题,有什么评价标准
要完成这个项目,目前比较前沿或者理想的方案是什么
由哪些部分组成,每个部分的职责是什么
这几个部分下的常用方案是什么
每个部分是怎么协同的
逐步拆解这个方案内部的内容
为什么要选这个方案,优缺点是什么
要达成这个愿景,需要什么条件。
最后这点,“要达成这个愿景,需要什么条件”非常重要,这是我们后续要逐步迭代的一个重要线索,我们设计的每一次迭代,除了要满足每一步所遇到或者遗留的短期问题,还需要把愿景中未满足的条件给满足了,才能最终达成我们的愿景,所以,最好盘点出来。
了解现状
了解现状是现实工作中非常重要的步骤,在新接触一个项目时、要做方案升级时、逐步迭代过程中都非常需要,而且“现状”一次的概念也非常广,重点在于,要了解哪些现状,对一个算法技术设计而言,主要有如下方面:
目前是否有使用什么算法方案,这个方案的效果如何(指标),使用的什么测试集
从bad case分析反馈而言,目前有什么问题,重要程度如何(问题占比)
用户角度的问题有哪些诉求。(此处注意多沟通挖掘)
该方案目前的SOTA和口碑比较好的方案有哪些
制约方案的因素要了解清楚。
上线需要多少多少耗时、并发,有多少机器资源(CPU核、内存、显卡型号显存等,涉及数据库中间件还有硬盘大小等)
能支持提供多少的训练数据(无论是挖掘、自动标注还是人工标注,盘点清楚)
排期时间。简单的,2天能做的事和10天能做的事肯定不一样。
能尽可能理清这些问题,大概率就能对现状有个比较清楚的把控了。
初始方案的设计
有关技术方案设计,之前已经有过类似的文章了:心法利器[56] | 算法技术设计思路小结。
但是在这,要补充一块比较重要的内容,那就是要逐步满足最终愿景所需要的条件。在最终方案中,往往需要更多的资源和基础,例如需要埋点数据、需要基础的工程支持、需要特定数据的积累,甚至有些坑是需要提前踩的这些事,我们是可以通过前期的方案设计,把这些内容带上车一起推进。
举个例子,我们要构造完整的搜索系统(前沿重器[48-54] 合集:四万字聊搜索系统),我们要有NLU、召回、排序,早期一蹴而就并不可能,但是类似召回需要的中间件、或者是用户点击之类的反馈信息,那我们完全可以在早期就提前安排,尤其像埋点这种,很早就可以安排,并行推进的,就可以在尽快安排上线。
维持稳定增长的技术储备
持续学习肯定是非常有必要的,我们往往会纠结于学习方向是什么,而在结合项目的进展持续深入学习则是一个很好的方向。
要设计方案的前提,是手里有足够多的牌,如果手里就没什么牌,轻则找不到很优秀的方案,重则无从下手,时常和朋友聊起的很扎心的话:
你不会除了微调没有别的方法了吧。
现在让你微调了,你不会还微调不好吧。
所以维持稳定增长的技术储备是非常有必要的,大到整个框架愿景,小到每个部分,都值得持续调研学习,看论文、看分享、分析具体场景的case,都是常用的学习提升更新方案,慢慢你就会发现自己在这个领域逐步得心应手了。
案例
在这里,我提供一个案例来体现这种迭代思维。先修知识还是先看看我最近写的搜索系统合集(前沿重器[48-54] 合集:四万字聊搜索系统)。
现在手里拿到一个产品需求,是要为一个场景做一个知识类的搜索系统,面向的用户主要是专业人士,做专业知识的查询。目前已经有一些业务方提供的知识库,非结构化的书籍材料,由于是新产品,所以暂时完全没有用户日志数据。
要做成完整的搜索系统,肯定不是一蹴而就的,确定好目标和规划,按照计划进行即可。
首先对于最终形态,还是比较明确的,就是构造架构比较完善的NLU、召回、排序模块,内部结合用户搜索习惯和知识库情况划分好模块分情况处理,配合大模型的RAG能力为用户提供最精准的知识查询服务。
显然这里并不能全部立刻完成,这里有几个核心的痛点需要优先考虑开展工作:
因为书籍材料并不结构化,所以需要进行切片或者是问题挖掘之类工作。
没有用户搜索习惯数据,尽快有个baseline进行小尝试是个不错的方案。
目前无任何基础工作,向量或字面搜索的快速baseline可以先建立起来。NLU暂时不急,排序模块数据也不足,直接用一个召回模块快速形成搜索是个不错的方式。
字面搜索可以考虑ES,从简在数据少的情况下也可以直接用python写一个复杂度高点的字面检索模块也可以。
向量召回的引擎可以用FAISS来做,模型的话参考BGE系列的模型能做较高的basleine。
重点是快速成型,形成完整流程,确认效果。
效果验证可以让大模型、产品经理等角色出一些必过的case,然后在看开源的数据集是否有,可以先作为参考,等后续有了用户数据再来升级数据集。
在完成了简单的baseline后,再结合产品反馈、数据集反馈的方式来优化,形成可用版本后就可以开始小范围内测使用,最终形成上线产品,待产品上线后再来考虑逐步扩展,形成项目所需的各个模块,当然随着技术变迁和需求演化,很多必要的设计在后续会有变化,到时候再见招拆招。
这里可以看到:
充分了解现状,在前面我有提到面向的用户、目前已有和缺少的关键资源。
愿景是有的,但是会比较粗,只要有个相对明确的目标即可。(当然这里要注意拆解模块,这个我在后续的章节会谈如何拆解)
开展的工作基本是围绕当前的关键问题以及构造最终用形态雏形来推进的。
初步方案里,对于最终目标中暂时在现在并不重要的模块,会选择性的先忽略,如NLU模块,排序模块等,或因为当前效果短板并不在此,或因为当前并无足够的数据支持该项工作。
相反,在当前情况,物料,即这里的书籍材料,才是比较重要的部分,巧妇难为无米之炊,搜索系统的基础物料在早期是很重要的,处理好了后续的搜索推理阶段的工作会事半功倍。
小结
今天主要是想给大家分享一个算法技术设计的思维方式,即迭代的思维方式,要把复杂的任务拆解放到时间线中来逐步处理,并详细解释了整个迭代的具体实施过程。在这里再补充一下这个思路的优势。
拆解后把整体的项目压力分到了后续的时间线上,按计划推进会更明确也更有自信。
构造出了入手点,让复杂的无从下手的事情有了入手点,这在方案设计这件事上,无疑是一个重大的推进。
巧妙权衡了前沿技术和项目需求上的结构性差异,前沿技术可能并不符合项目目前存在的问题,但两者可以通过这个方式进行有机结合。我曾经见过很多人会吐槽搜索、推荐的论文在现实中没什么用,大概率就是这个原因,推荐系统中论文提到的某些方案是针对某些问题的,但是这个问题在现阶段场景并未暴露或成为关键点,此时用起来肯定就没什么收益甚至负收益。
最后在这也问问大家,有关这块的思想和方法论,有没有比较成体系的学科或者理论学习,感觉这块可能已经有一些研究,但没有找到,有兴趣的欢迎在评论区讨论,另外类似的文章不知道大家的喜好怎么样,有兴趣也可以评论一下。