
做深度学习的人收藏夹里几乎都有一个叫备用或者待看的文件夹。里面塞着几十上百条东西某篇讲注意力机制的论文预印本、某个开源实现的代码仓库、某篇把分布式训练讲透的长文、某个数据集的主页、某个课程的视频列表。存的时候都觉得自己捡到宝了半年后再点开一半打不开剩下能打开的也不知道当初为什么要存它——标题看着眼熟内容完全陌生还得从头判断这玩意儿到底有没有用。这篇东西要解决的就是这个看起来很小、实际非常消耗精力的问题怎么把一堆散乱的深度学习相关链接整理成真正能在需要时救命的资产。它适合三类人刚入门、正在疯狂收集资料但收完就忘的新手做了一段时间、需要频繁在新任务之间切换的中期从业者以及需要给团队维护一份公共参考清单的人。不需要你有多深的模型功底但需要你愿意花两个小时把收藏这件事从囤积改成建档。1. 备用清单为什么会烂在收藏夹里1.1 收藏动作和取用动作之间断了一整条链绝大多数人的收藏行为是在信息消费的瞬间发生的而取用行为是在任务卡住的瞬间发生的。这两个瞬间之间隔着完全不同的上下文。收藏的那一刻你脑子里装着刚刚读到的内容你知道它讲的是什么问题、用了什么方法、哪一段最关键而半年后取用的那一刻你脑子里装的是当前的报错信息和一个具体的工程约束你需要的是能立刻解决这个问题的东西而不是一篇我当年觉得写得很好的文章。中间断掉的那条链本质上是语境没有跟着链接一起被保存下来。你存了地址没存我为什么存它。所以清理收藏夹的时候判断标准会退化成这标题看起来有没有用而这个标准基本等于抛硬币。我见过太多人用一整个周末整理收藏夹整理完三个月又乱成一锅粥原因就在于他只是给链接换了分组没有给链接补上语境。解决思路很直接**收藏的那一刻必须顺手写下存它的理由理由的格式要固定不需要长篇大论一句话、几个标签就够。**固定格式是关键因为格式自由就意味着你每次都会偷懒跳过。后面第 3 节会给出具体的字段模板这里先记住原则。1.2 深度学习资源有三种不同的过期方式混在一起管就会互相拖累普通网页的过期只有一种链接打不开。深度学习相关的资源要麻烦得多我把它分成三类这三类如果放在同一个清单里用同一套标准管理必然出问题。第一种是地址过期。开源仓库改名、作者删库、博客域名换了、课程平台调整了目录结构链接直接 404。这类问题最好发现也最容易修——搜索一下标题基本都能找回来或者找到内容完全相同的转载版本。第二种是内容过期但地址还活着。这个最阴险。同一篇文章作者可能已经更新过三版你当年读的那版讲的结论现在被推翻了同一个代码仓库主分支早就重构过你记忆里的接口名全部变了README 里也不再提那个被废弃的参数。你点开链接页面正常显示你以为自己拿到了当年的东西其实拿到的是完全不同的内容。第三种是环境过期。这一种在深度学习领域尤其致命。一条教程链接本身没坏内容也没变但它依赖的那个库的版本、那个预训练权重的格式、那个数据集的划分方式已经在两年内变了好几轮。教程里的十行代码放到今天跑报错能报出七八个。而这条链接本身永远不会告诉你这件事它就在那儿安安静静地躺着等着你花三个小时去试。把这三类混在一起你会在地址过期上花大量时间做无用功因为这类最好查、查起来最有成就感而真正会浪费你时间的环境过期却完全被忽略。所以分类轴的选择比整理本身更重要这是下一节要讲的核心。2. 分类轴换掉按取用时怎么找重组而不是按资源类型分2.1 论文、教程、代码的三分法为什么不好用大部分人的收藏夹结构是这样的论文一堆、教程一堆、代码仓库一堆、数据集一堆。这个分法看起来很整洁实际用起来非常糟糕原因在于你在真实场景里从来不会只缺其中一种。举个具体的场景你要在一个新任务上试试某种序列建模的思路。你需要的不是一篇论文而是这个思路的原始论文 一个别人跑通过的实现 一份说明它在什么规模的数据上有效的经验帖 一个可以对照的基线数字。这四样东西分属你收藏夹里的三个不同文件夹。你为了完成一件事要在三个分类之间来回跳然后每一类里还有几十条候选你得逐条点开确认是不是你要的那个。更深一层的问题是按类型分类隐含了一个假设资源的价值由它的形态决定。但实际上一篇综述和一篇方法论文都是论文它们在你工作流里扮演的角色完全不同——综述是入门期用来建立坐标系的方法论文是在你已经有坐标系之后用来解决具体问题的。同样的形态不同的用途按形态分类等于把用途信息抹掉了。2.2 换成任务驱动四分法查证、复现、兜底、扫盲我自己的清单现在拆成四个区每个区对应一个非常具体的我会在什么时刻打开它。查证区用来回答这个东西到底成不成立。里面放的是原始论文、权威基准的排行榜页面、以及那些把实验设置写得足够细的技术报告。打开这个区的典型时刻是有人跟你说某个方法效果很好你要判断这句话在你的场景下能不能信。复现区用来回答怎么把它跑起来。里面放的是可直接克隆的实现、能对上的配置文件、别人写好的训练脚本、以及那些把坑写在明面上的复现笔记。打开这个区的典型时刻是你已经决定要试现在缺的是能跑的第一版骨架。兜底区用来回答出问题了怎么办。里面放的是常见报错的排查帖、某个库的行为变更记录、显存和吞吐相关的经验总结、数据预处理里那些反直觉的细节。打开这个区的典型时刻是程序跑起来了但结果不对或者跑着跑着崩了。扫盲区用来回答这个领域我完全不懂从哪开始。里面放的是综述、课程、体系化的长文、名词解释。打开这个区的典型时刻是你要接手一个完全陌生的方向需要在两天内建立基本判断力。这个四分法最关键的好处是它让该不该存这个问题有了判断依据。一条链接如果你说不清它属于哪个区那它大概率不该进清单。反过来如果一条链接同时能进两个区说明它质量不错值得在备注里标一下双向可用。2.3 每个区设一个入口条其余全部下沉四个区各自会积累很多条目如果全平铺还是找不到。我的做法是每个区顶部只保留三到五条入口条其余的全部下沉到下面。入口条的挑选标准不是最重要而是最通用——也就是不管你现在做的是什么任务只要进这个区先看这几条都不会错。比如复现区的入口条我留的是一条环境配置的通用检查清单、一条最小可跑示例的骨架、一条数据集加载的标准写法。这三条覆盖了九成的复现起点。剩下那些针对特定任务、特定模型结构的实现全部下沉。这样一来你打开复现区第一眼看到的三条永远是有用的不会因为条目膨胀而失去方向感。提示入口条的数量一定要严格控制。超过五条人眼就不会认真看了会直接往下滚那入口条就失去了意义。宁可把某条优质资源下沉也不要让入口区变成第二个大列表。3. 一条链接该记什么比地址值钱的六个字段3.1 版本锚点与环境锚点这两个字段决定了链接还能不能用我在前面说过内容过期和环境过期是最难发现的。解决办法是在存链接的时候就把锚点钉死让过期这件事变得可见。版本锚点记录的是我存的那一版是什么。对于文章类资源记下它的发布或最后更新年月对于代码仓库记下当时看的那个提交标识或者版本标签哪怕只记前几位对于有版本的文档站记下版本号。这个东西的作用是当你以后再打开它发现内容变了你至少知道变了而不是傻乎乎地以为这就是当年那版。环境锚点记录的是这条资源在当时依赖什么。最少要记三样运行时的主要版本号、核心依赖库的大版本、以及硬件相关的约束比如是否需要特定显存容量才能跑起来。这三样东西不需要精确到小版本号但大版本必须记因为大版本之间的破坏性变更才是真正会让你踩坑的地方。实测下来这两个字段是整份清单里唯一真正防得住三个月后回来一脸懵的东西。其他字段都是锦上添花这两个是刚需。麻烦的地方在于填它们要花三十秒而这三十秒在你收藏的当下感觉完全没有必要——这正是大部分人最终没填的原因。3.2 可信度标记和最后验证日期用来对抗看起来很有道理深度学习领域的信息密度很高但质量分布极不均匀。同样一个结论可能来自一篇有完整消融实验的正式论文也可能来自某个只有一段代码和一句亲测有效的随手记录。这两种东西都可以存但不能混着用。我给每条链接打一个简单的可信度标记只分三档标记含义典型来源使用方式硬有可复现的实验设置和对照正式论文、官方技术报告、带完整配置的开源实现可以直接作为技术选型依据中有实践但缺对照工程博客、复现笔记、经验总结帖作为思路参考结论需要自己验证软单点经验或个人观点问答区回答、短评、单条推文只用来发现线索不采信结论另一个字段是最后验证日期。这个字段的价值在于它会自己变旧。你看到一条链接的最后验证日期是两年前你在心里就会自动给它打个折扣会更谨慎地去试。而如果这个字段不存在你就没有任何依据判断它是不是还成立只能默认它成立——这恰恰是最危险的状态。3.3 一份可以直接照抄的字段模板把上面说的东西合起来我用的模板是这样七个字段用任何笔记工具、表格工具甚至纯文本都能维护字段必填填写要点示例写法虚构示意标题是原资源标题不改写某类序列建模方法的原始论文归属区是查证/复现/兜底/扫盲只选一个主区复现一句话用途是我在什么时刻会打开它需要给新任务搭第一版训练骨架时版本锚点是更新年月或提交标识更新于某年某月提交标识前七位环境锚点是运行时大版本、核心依赖大版本、硬件约束运行时 2.x核心库 1.x需 16G 以上显存可信度是硬/中/软中最后验证是我最后一次实际跑通或读完的日期某年某月这张表里最容易被跳过的是一句话用途。很多人觉得这字段没用因为我存的时候当然知道用途。但你要意识到这个字段是写给半年后的自己看的而半年后的自己跟你不是一个人——他手上有一个具体的、跟你当时完全不同的任务。一句话用途的作用就是把当时的语境压缩成一个可以被未来的自己解压的种子。4. 地址失效的两套兜底方案4.1 内容快照存一份死了也能看的副本地址失效这件事没法完全避免但可以把损失控制住。我的做法是对清单里所有标记为硬可信度的条目以及所有一句话用途里写着关键时刻要用的条目额外保存一份内容快照。快照的形式分两种选哪种取决于内容形态。文字类资源文章、教程、说明文档存成纯文本或者单文件格式最稳妥因为体积小、不依赖外部资源、几十年后还能打开。代码类资源至少要把核心的那几个文件复制出来尤其是配置文件、依赖清单和入口脚本——这三个文件基本能还原出这玩意儿当年是怎么跑的比存整个仓库更实用也更容易在仓库消失后重新理解。这里有个取舍要说清楚快照不是为了让你以后不用原链接而是为了在原链接死掉的时候你至少还能看到内容、判断它是否还值得去找替代品。如果只存地址链接一死你就彻底失联连这东西讲的是什么都想不起来那这条收藏就等于从来没存在过。注意快照要跟主清单放在一起并且在字段里注明快照的位置。我见过有人快照存了一堆但清单里没写快照在哪结果链接死了、快照也找不到了等于白存。4.2 仓库改名和接口重写之后的找回路径地址过期里最常见的一类是开源仓库的地址变了。作者换了组织、项目改了名字、或者干脆拆成了多个子项目。这种情况下的找回路径是有套路的按顺序试基本都能找回来。第一步用资源的唯一标识性内容去搜而不是用标题。标题会被改但方法名、关键的类名或函数名、论文里的核心公式名这些通常不会变。第二步去查这个资源的上游来源——很多实现是某个原始项目的衍生原始项目还在衍生项目死了从上游往下找往往能找到仍在维护的分支。第三步找引用它的地方比如某篇综述的文章列表、某个基准测试的对比表这些地方通常会同时列出新旧地址。接口重写的情况要麻烦一点因为地址是对的内容也是对的只是用法变了。这种情况我的处理方式是不修改原条目而是在同一个条目下面追加一条变更记录写清楚哪天发现什么变了、新的用法是什么。这样做的理由是你以后可能会遇到还在用旧版本的环境旧的用法不能丢同时变更记录本身积累起来就是一份关于这个资源演进历史的一手材料比任何官方变更日志都贴近你的实际使用场景。5. 从存了到跑通把链接变成可执行的东西5.1 最小复现笔记的四段式一条链接如果只是被读完、被收藏它的价值顶多是我知道了有这么个东西。真正的价值转折点在于你把它跑起来一次。而跑起来这件事如果每次都从零开始试成本高到没人愿意做第二次。我的做法是凡是进复现区的条目跑通之后必须留一份最小复现笔记固定四段每段不超过五句话**第一段它解决什么问题。**用一句人话说清楚输入是什么、输出是什么、中间大概做了什么。不要抄摘要摘要里全是术语。这一段的作用是让你三个月后能立刻判断这个能不能用到我现在的任务上。**第二段最小可跑的命令序列。**从零开始按顺序列出你实际敲过的命令包括创建环境、安装依赖、准备数据、启动训练或者推理。这里的关键是实际敲过的不是文档上写的。文档上写的往往假设你已经有一堆前置条件而你实际踩过的顺序才是可复现的。**第三段我改了什么。**文档里的示例配置通常是为了跑通演示跟你手上的真实数据对不上。这一段记录你为了让它吃自己的数据改了哪几个参数、动了哪几个文件。这是整份笔记里复用价值最高的部分。**第四段跑完之后的结果长什么样。**记下关键指标的大致范围、日志里应该出现的标志性输出、以及跑完之后产出的文件放在哪。这一段的作用是让你下次跑的时候知道成功了是什么样而不是盯着日志猜。这四段加起来通常不超过一屏写起来大概十分钟。但它省下的时间是以小时计的因为你下次再用到它的时候不需要重新读一遍原始文档、重新试一遍装依赖的顺序。5.2 一个具体的过程拆解从一篇方法论文到一个能跑的脚本我拿一个虚构的典型场景走一遍让你看清楚这条链是怎么接起来的。假设你在查证区看到一篇论文讲的是某种改进的序列建模结构摘要说在几个基准上有提升。你把它标成硬可信度版本锚点记下更新年月环境锚点记下它实验用的硬件规模。到这一步它只是个待验证的结论。接下来你决定要试。这时候你打开复现区先看入口条里的环境检查清单确认自己的环境能撑住这个规模的实验——如果原文用的是大规模集群你手上只有单卡那你要做的第一件事不是复现而是判断小规模下这个方法还有没有意义这个判断本身就该记进一句话用途里。然后你去查证区的这条论文条目下面追加一条链接找到的第三方实现。这条实现进复现区标中可信度因为它是别人写的不一定忠实于原文。你按照四段式跑一遍第一段写清楚它做什么第二段记下实际命令序列第三段记下你为了让数据格式对上改了什么第四段记下跑出来的指标。关键的一步在这里如果跑出来的数字跟原文差很多不要急着放弃也不要急着相信原文。先检查三件事——数据预处理是不是一致、评估口径是不是一致、训练轮数是不是一致。这三件事里任意一件不同数字就没有可比性。这个检查过程本身要写进复现笔记的第三段因为它是你下次遇到同类问题时的第一反应清单。整个过程走完你手上就有了一条论文条目、一条实现条目、一份复现笔记、以及一份什么情况下这个方法值得试的判断。这四样东西合起来才叫一条链接真正变成了资产。而如果你当初只是在收藏夹里点了个星你现在手上什么都没有。6. 维护节奏多长时间清一次按什么标准淘汰6.1 季度体检的具体检查项清单不维护就会腐化这是必然的。但维护不能靠想起来就整理一下那样要么不做要么一次做一整天然后半年不想碰。我的做法是每个季度做一次固定动作时间控制在一小时以内检查项固定。检查项操作判断标准抽查地址有效性随机点开两成条目失效比例超过三成说明该整体迁移快照方案校验版本锚点看标记为硬可信度的条目是否已有明确的新版本有新版本就追加变更记录不删旧记录更新最后验证日期只更新这个季度里实际用过的条目没用过的保持原日期不动让它们自然变旧清理一句话用途写不出的条目逐条读用途字段读不懂或者写的是空话直接删检查入口条看每个区的入口条是否还在前三到五条被新条目挤下去了就重新排这个表里最有杀伤力的是第四项。一条链接如果你连我在什么时刻会打开它都说不出来那它对你的价值就是零留着只会增加下次检索时的噪音。删掉它不需要犹豫因为你随时可以重新搜到——真正难找回的是那些你写清楚了用途、并且已经验证过的东西。6.2 有一种条目永远不要删哪怕它已经失效大部分失效条目该删但有一类例外记录了一次失败尝试的条目。比如你存了某个实现标了中可信度复现笔记里写着按文档装了三遍依赖都冲突最后放弃。这种条目看起来是负资产实际上非常值钱。因为半年后你很可能会再次遇到同一个资源那时候你已经忘了自己试过又会花两个小时重新试一遍。保留这条记录你打开就知道哦这个我试过卡在依赖上可以直接跳过去看下一个候选。所以我的淘汰标准不是还有没有用而是还有没有信息。地址死了、内容也找不到了、用途也说不清、也没有任何验证记录那才是真该删。只要它还携带着一条经验——不管是成功的还是失败的——它就值得留着而且应该把那条经验写得更清楚一点。7. 几个我实际踩过的坑7.1 存了最新最强却没记日期半年后拿它当现役方案这个问题我踩得最深。当年看到某个方法在某个基准上刷了新高觉得很有价值存了下来只记了标题和地址。半年后做技术选型翻到这条脑子里冒出的是这个是当时最好的于是直接拿去用了。实际上那半年里已经出了好几个改进版本原方法在同等成本下的表现已经不占优了。问题的根源在于当时最好这个判断是有时效的而链接本身不携带时间信息。现在的做法很简单凡是带有最好最新刷新纪录这类判断的条目版本锚点必须精确到月并且在备注里写清楚这个结论是在什么基准、什么规模、什么成本约束下得出的。这三个限定条件少一个那句话就会在未来变成误导。顺带说一个相关的习惯看到排行榜类的页面别只存首页地址把当时的排名截图或者文字记录下来。排行榜是会变的你今天看到的第一名三个月后可能掉到第五而你再也无法还原当时为什么选它。7.2 把别人的环境当成自己的环境复现时对着报错发呆这是新手最容易踩、老手也常犯的坑。一条教程写得清清楚楚十行代码跑通但它有个隐含前提作者的机器上装了某个版本的工具链某个依赖是全局装好的某条环境变量是默认配好的。这些东西作者不会写因为他自己都没意识到。我现在拿到任何一条教程类资源第一步不是照着敲而是先在复现笔记的开头写一行这条资源假设了哪些我可能没有的东西然后逐条确认。确认清单就三样运行时版本、核心依赖版本、硬件与驱动这一层。这三样对上了八成的问题就不会出现对不上先解决环境再谈复现别一边报错一边改代码那样你会同时怀疑两个变量最后什么都定位不出来。还有一个具体的技巧第一次跑通之后立刻把当时的完整依赖清单导出来存进复现笔记。这个东西是环境锚点的实证版本比你自己回忆的版本号靠谱得多。等哪天环境坏了对着这个清单重建比重装一遍再猜要快得多。7.3 给团队维护公共清单时字段标准比内容更重要如果你维护的不是个人清单而是团队共用的那有一件事比收集内容重要得多把字段标准定死并且写清楚每个字段的填写规范。我一个人维护的时候可以随手写因为只有我看得懂。但团队场景下如果每个人按自己的习惯填三周之后这份清单就没法用了——有人把用途写在标题里有人把版本写在备注里有人干脆不填。这时候搜索是搜不出来的因为关键信息散落在不同字段里。我的做法是给每个字段配一个反例说明用途字段不许写很有用值得一看必须写我要做某某事的时候会打开它环境锚点不许写较新版本必须写具体的数字。反例比正例更能约束填写行为因为正例大家会各自发挥反例大家会统一避开。清单刚开始建的时候多花半天把标准写清楚后面能省掉无数次的返工。