<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>2025 年文章 on 猜猜是谁的博客</title><link>https://caifengze.com/zh-cn/post/2025/</link><description>Recent content in 2025 年文章 on 猜猜是谁的博客</description><generator>Hugo -- gohugo.io</generator><language>zh-cn</language><lastBuildDate>Fri, 24 Oct 2025 21:40:11 -0400</lastBuildDate><atom:link href="https://caifengze.com/zh-cn/post/2025/index.xml" rel="self" type="application/rss+xml"/><item><title>写在2025生日</title><link>https://caifengze.com/zh-cn/blog/2025/%E5%86%99%E5%9C%A82025%E7%94%9F%E6%97%A5/</link><pubDate>Fri, 24 Oct 2025 21:40:11 -0400</pubDate><guid>https://caifengze.com/zh-cn/blog/2025/%E5%86%99%E5%9C%A82025%E7%94%9F%E6%97%A5/</guid><description>&lt;h2 id="写在前面">写在前面
&lt;/h2>&lt;p>我也不知道要在今天写一些什么东西，一个人在外面真的很不知道要怎么样，一个内向的人，连自己生日都不太愿意和大家说。&lt;/p>
&lt;p>infj 或者 说 我就是这样吧，会把自己藏起来，但又希望又惊喜，惊喜的是，并没有惊喜，不过这也是人生的常态吧。&lt;/p>
&lt;p>不过还是谢谢爸妈、几位朋友以及一位新认识的朋友，给我送了生日祝福！&lt;/p>
&lt;h2 id="罗岛生活">罗岛生活
&lt;/h2>&lt;p>来到了这里以后，整个人的精神状态都是比较好的，感觉最近也在放过自己，就是不强行给自己上压力，面试没有就没有吧，当务之急，是把自己在英语上的问题解决了。&lt;/p>
&lt;p>很高兴，今天和 Nadav 能够聊天聊一路！&lt;/p>
&lt;p>不过，还是很担心下周的 Presentation，希望自己能顺利吧，一站在台上就容易不会讲话哈哈哈。&lt;/p>
&lt;h2 id="我想要记录">我想要记录
&lt;/h2>&lt;p>前段时间，看到了一个视频，是自己做的长时间的记录。其实她也是模仿一个机构为一些人做每年的采访，虽然我不知道是不是有意义，但我还是想为自己录一段。&lt;/p>
&lt;h2 id="今年的话">今年的话
&lt;/h2>&lt;p>我想，去年立哥给我送了一句&lt;em>不妥协不犹疑不勉强不半推半就&lt;/em>，(刚刚捡查了一下 没想到是 前年，已经三年没有在生日发puq了)
今年的这句话是 wey-gu 老师的 &lt;em>每天的活力有很多，不必为了这种结果不在你控制范围内的事消耗掉它，你还能用它去创造很多东西！&lt;/em>（以及刚刚收到的&lt;em>努力、放松、专注、享受！&lt;/em>）&lt;/p>
&lt;hr>
&lt;p>2025年10月25日 2:00am&lt;/p></description></item><item><title>一些关于留学</title><link>https://caifengze.com/zh-cn/blog/2025/%E4%B8%80%E4%BA%9B%E5%85%B3%E4%BA%8E%E7%95%99%E5%AD%A6/</link><pubDate>Thu, 04 Sep 2025 03:17:27 +0800</pubDate><guid>https://caifengze.com/zh-cn/blog/2025/%E4%B8%80%E4%BA%9B%E5%85%B3%E4%BA%8E%E7%95%99%E5%AD%A6/</guid><description>&lt;h2 id="写在前面">写在前面
&lt;/h2>&lt;p>为什么会突然想写这一篇post？我在这一天内同时经历了被学妹问经验，并且看到了&lt;a class="link" href="https://hdu-cs.wiki/" target="_blank" rel="noopener"
>HDU-CS-WIKI&lt;/a>。&lt;/p>
&lt;p>说些题外话，其实真的很想 hdu 也有一个真正的指南，但这也需要很多的 hduer 去努力的维护他。&lt;/p>
&lt;p>第一次看到 &lt;a class="link" href="http://www.houxiaodi.com/assets/misc/manual.pdf" target="_blank" rel="noopener"
>上海交通大学学生生存手册&lt;/a> 的时候，为之震撼。能把大学活得这么通透或者说明白，
现在再去重新看这本指南，也会为自己在大学没能想明白一些事而感叹。&lt;/p>
&lt;p>那真正能写这一篇文章的原因，我想也是因为我开了两次关于申请的讲座，回头看，如果没有更多的文字记录，反而是一件很可惜的事，趁我还能记起这些内容，尽早将他们记录下来（大部分内容都是演讲的话，为了文本通畅，稍微做了一些调整，也有部分内容进行了删减）。&lt;/p>
&lt;h2 id="目录">目录
&lt;/h2>&lt;ul>
&lt;li>&lt;a class="link" href="#%e5%86%99%e5%9c%a8%e5%89%8d%e9%9d%a2" >写在前面&lt;/a>&lt;/li>
&lt;li>&lt;a class="link" href="#%e4%b8%ba%e4%bb%80%e4%b9%88%e9%80%89%e6%8b%a9%e7%95%99%e5%ad%a6" >为什么选择留学&lt;/a>
&lt;ul>
&lt;li>&lt;a class="link" href="#%e5%86%b2%e5%8a%a8" >冲动&lt;/a>&lt;/li>
&lt;li>&lt;a class="link" href="#%e6%80%9d%e8%80%83" >思考&lt;/a>&lt;/li>
&lt;li>&lt;a class="link" href="#%e5%86%8d%e5%8f%8d%e6%80%9d" >再反思&lt;/a>&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>&lt;a class="link" href="#%e9%9c%80%e8%a6%81%e5%87%86%e5%a4%87%e4%ba%9b%e4%bb%80%e4%b9%88" >需要准备些什么&lt;/a>
&lt;ul>
&lt;li>&lt;a class="link" href="#gpa" >GPA&lt;/a>&lt;/li>
&lt;li>&lt;a class="link" href="#%e8%af%ad%e8%a8%80" >语言&lt;/a>&lt;/li>
&lt;li>&lt;a class="link" href="#%e8%bd%af%e8%83%8c%e6%99%af" >软背景&lt;/a>
&lt;ul>
&lt;li>&lt;a class="link" href="#%e4%ba%a4%e6%8d%a2" >交换&lt;/a>&lt;/li>
&lt;li>&lt;a class="link" href="#%e7%a7%91%e7%a0%94" >科研&lt;/a>&lt;/li>
&lt;li>&lt;a class="link" href="#%e5%ae%9e%e4%b9%a0" >实习&lt;/a>&lt;/li>
&lt;li>&lt;a class="link" href="#%e7%ab%9e%e8%b5%9b" >竞赛&lt;/a>&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>&lt;a class="link" href="#%e7%94%b3%e8%af%b7%e4%bb%a5%e5%8f%8a%e4%b8%ad%e4%bb%8b" >申请以及中介&lt;/a>
&lt;ul>
&lt;li>&lt;a class="link" href="#%e8%a7%84%e5%88%92" >规划&lt;/a>&lt;/li>
&lt;li>&lt;a class="link" href="#%e9%80%89%e6%a0%a1%ef%bc%88%e9%80%89%e9%a1%b9%e7%9b%ae%ef%bc%89" >选校（选项目）&lt;/a>&lt;/li>
&lt;li>&lt;a class="link" href="#%e6%96%87%e4%b9%a6" >文书&lt;/a>&lt;/li>
&lt;li>&lt;a class="link" href="#%e9%82%a3%e9%9c%80%e4%b8%8d%e9%9c%80%e8%a6%81%e4%b8%ad%e4%bb%8b%e5%91%a2" >那需不需要中介呢&lt;/a>&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;h2 id="为什么选择留学">为什么选择留学
&lt;/h2>&lt;p>从高考开始讲起吧，我不太确定和大家是不是一样的，就是在高考前夕对高考已经是麻木了，能强烈的感受到自己就是一台机器，不停的机械重复。（很好笑的是，我老师后来和我说，我那段时间眼神里都失去了光）
至于最后的结果，也就是高考成绩不太好罢了。&lt;/p>
&lt;p>现在看来，当时的心态就是对考试这件事产生了极度的焦虑，觉得高考就是一辈子的事，决定了你一生的路（人生的容错其实很大，甚至高考失败本身就不是错）。
我的老师，家长都和我说，我在高三最后的时间极度阴郁
后来只要回忆起这件事情，内心都不断在加深一个观念——再也不想考试了，我想逃离这个体制，但发现自己（即使是现在）也没有完全摆脱。&lt;/p>
&lt;p>我的高中应该是当地最好的一所了，经历过高考这件事，Plus周围的人，都很厉害，可能导致了我的名校情节，（我确实还存在名校情节这个事情），
那么摆在我面前的就是我需要花四年去一个更好的学校，更好的地方，所以选择了留学
（我觉得这件事其实本身也是很冲动的，就是我花我的四年去做这样一件事，真的值得吗，我最后的目的到底是为了赚米，还是真的有一些学术追求）&lt;/p>
&lt;h3 id="冲动">冲动
&lt;/h3>&lt;p>（我现在去评判我的留学客观来说，肯定也不是很理智）&lt;/p>
&lt;p>我举一个身边的几个例子，iyear，不能说的太具体，但是他拿了大厂的SSP，他很明确，读hdu，只是保住了他的下限，在大部分情况下并不会被卡学历（当然排除杭州某些厂），上限则是靠自己的，对于他来说，不挂科就是满分，剩下的是，就是怎么提升自己在就业中的竞争力。&lt;/p>
&lt;p>为什么说我是冲动的，对于我来说，我上面的认知真的是很浅短的。因为我一直被世俗的认知绑架，传统观念上，大家都会觉得这一生就是 读个好大学，找个好工作，第一步都没做到，我就觉得很“不配”活着。&lt;/p>
&lt;h3 id="思考">思考
&lt;/h3>&lt;p>当然，留学这件事对于不同人的目的本身就不一样，eg.家里有公司，有资产，那就是酒桌上的社交手腕；&lt;/p>
&lt;p>那我后来的认知是什么样的呢？&lt;/p>
&lt;p>当我真正开始接触计算机了，你会发现美国/硅谷真的是很宝藏的地方。&lt;/p>
&lt;p>举一个最近的例子，在 deepseek 出来了以后，Nvidia 股票暴跌，我身边有些同学在和我唱衰美国科技行业了。不管怎么样，我始终持保留意见。
而当OpenAI发出4.5，O1，O3，google 的 Gimini 2.5 还有 grok 这些模型的时候，相比之下，他们才真的是在亮肌肉。&lt;/p>
&lt;p>第二个方面是教育质量上的。&lt;/p>
&lt;p>从国内的课程上来讲（目前还仅限于hdu），开始真正上相关 cs 的课以后，你会发现学校里讲的很多东西算很浅显的。
以线性代数为例，我们的线性代数除了行列式的计算，矩阵就讲了一丁点吧，为什么要用矩阵，矩阵的意义是什么，更深入的了解矩阵，你们有思考过嘛，或者老师带着你们思考过。我猜大部分情况下应该是没有的，大部分人也就是应付一下考试。&lt;/p>
&lt;p>这个时候就不得不引出 &lt;a class="link" href="https://csdiy.wiki/" target="_blank" rel="noopener"
>CS自学指南&lt;/a> 了，我相信有些人应该是听过的，不排除杭电确实又些好老师，但是我觉得学cs配合这个材料的话 食用更佳。再然后，你会发现，美国大学真的有很多高质量的课程（线性代数MIT 18.06 CS6.824）。（推荐一手nju蒋yy的os）&lt;/p>
&lt;h3 id="再反思">再反思
&lt;/h3>&lt;p>我给自己的目标很大也很小，大的是，我很想，能找到自己的路，自己真正喜欢做的事情，例如赚米，科研 or …… 之类的。&lt;/p>
&lt;p>小的是，现在的我允许自己失败，即使两年后的你，真的没找到工作，真的没能继续做科研，竟然都已经去做了，那就享受它吧！&lt;/p>
&lt;p>有目标，内心坚定，才能坚持下去，甚至我想在走上这条路后，也不会后悔&lt;/p>
&lt;h2 id="需要准备些什么">需要准备些什么
&lt;/h2>&lt;p>我认为在留学准备阶段（也就是开始下定决心要留学到申请前的时间），需要关注的只有这四个事情：GPA，语言，软背景和GRE。&lt;/p>
&lt;p>从大小上来看（在PPT上），我将 GPA 放的最大，显然，在我的认知里， GPA在这四者中是最重要的。如何保持一个比较高的 GPA，应该有很多方法，
包括但不限于，选课上的技巧，多和老师沟通，认真对待平时分以及有效的期末备考。&lt;/p>
&lt;p>语言，则是托福和雅思的选择，绝大部分情况下，美国托福，英联邦雅思即可。更详细的我会在后面提到。&lt;/p>
&lt;p>软背景，这一项我认为对不同地区，不同项目的策略重点是相当不一样的。从地区上来讲，美国会比注重英联邦更注重软背景；从项目角度来看商科和 MENG 硕士会更注重实习。&lt;/p>
&lt;p>GRE，我不做过多赘述，因为我根本没考哈哈哈。按我的理解是 高GPA+高GRE&amp;gt;高GPA&amp;gt;低GPA+高GRE&amp;gt;低GPA+低GRE，如果GRE低，建议不交。
为什么不用交呢，是因为我个人申请感受来看，我没有什么项目是因为缺少GRE被拒了的。&lt;/p>
&lt;p>不过还是要提一嘴，这个很看你申请具体的项目，比如 Gatech 的大部分项目就强制要求提交 GRE，而 CMU 也是一个很重标化的学校（但在我看来近年来有所减弱，因为今年很多项目也不强制递交GRE了）。&lt;/p>
&lt;h3 id="gpa">GPA
&lt;/h3>&lt;p>从我自己的经历来讲，我经历过一次转专业，导致我在大一下学期的时候自己的语言基础非常差，
开始学各种面向对象的知识，大规模化的继承（突然想起 C课设的老师说过，hdu学生，毕业前要写十万行代码，似乎我现在都没做到），
成绩非常的糟糕(这学期均分86-87左右)。&lt;/p>
&lt;p>我其实不是很适合上课听讲（每个人都有自己的学习模式），加上这个学期忙了很多社团活动，课业压力也因为转专业学分的原因非常大（我在大二大三几个学期的学分基本没有低于过33分）。
之后我就开始反思：应该怎么去学？我有尝试过cs自学指南一些课，不过说实话自己并不是很坚持的人，但是还是会找一些课外去弥补自己知识上的不足（大话数据结构，CSAPP）&lt;/p>
&lt;p>还有，特别是我们班同学真的很互帮互助，非常感谢。当有一群很努力的朋友一起围着的时候，你也会很有动力，并且因为我的基础薄弱，他们也经常指点我。
加上我们班在学期末都会组织一个分享会，就是每个科目都有同学上去过一遍整个科目的知识点，讲讲考试的重点，每门科目大约两三个小时，其实已经能概括完试卷上80%的知识点了。&lt;/p>
&lt;p>在往后的学期里也是很努力的补分，才把绩点拉到90以上。&lt;/p>
&lt;p>想多说一点的事，大家应该知道，GPA本身和你的努力程度并不成线性相关，如果从60-80可能需要一分努力，从80-90就需要十分，90以上的边际效应就更强了，请适时考虑性价比这个问题。&lt;/p>
&lt;h3 id="语言">语言
&lt;/h3>&lt;p>我选择的是托福，这个是一个很痛苦的事情，非常重听力的考试。不过现在网课上过来的感受也是，即使听力很高了，上课你还是听不懂。&lt;/p>
&lt;p>实在是不想回忆这一段内容，我决定将我演讲的outline贴在下面（偷懒）：&lt;/p>
&lt;blockquote>
&lt;p>托福真的是我考了四年的事情，非常的痛苦，甚至在去年十月份的时候，我都还只有80+的成绩，这也导致了我后面的申请策略上的一些问题&lt;/p>
&lt;p>71 是23年的成绩&lt;/p>
&lt;p>每次考完 我都有种 这辈子不想再考了感觉，然后就不想学，摆烂。一鼓作气，再而衰，三而竭加上畏考的心理，我甚至从去年的5月左右重新捡起托福到10月（我都不好意思说自己每天起码是8个小时以上的高强度学习）都没有什么特别大的提升&lt;/p>
&lt;p>其实真的学的很崩溃&lt;/p>
&lt;p>后面去反思这件事，其实我也算努力过的了，托福官方统计，要4次才能考到理想分数，但托福的平均分好像就80+吧，加上本来的英语基础就不好，anyway&lt;/p>
&lt;p>学习上，我觉得其实早期我的刷题量和词汇量已经是够了的，听力 环境 口语是我最大的问题，环境上（在考场里听别人点鼠标都会受不了） 后来就是心态上的调整，反正都考了这么多次了，已经无所谓了，大不了再多学一年。 听力 口语我是一起的，泛听我不确定对托福有没有用，我能感受到 看看美剧 或者 youtube会好很多，但是 托福还是不行。所以精听还是一定要做的。口语 我回家了以后，中间考了一次 duolingo 加上有几个学校要video essay，我每天就是 对着 摄像头练习一两个小时，坐累了就站起来，对着镜子瞎说，复盘，这是我的的确确感受到 听口写会一起进步的时候（写 也包括 对文书的调整，因为和中介老师只签了十篇文书，后续的文书都是自己重新写过的）最后 重新准备了三个星期左右（这次大概就学个半天，口语写作都是和GPT练），竟然就出分了，真的很amazing。&lt;/p>
&lt;p>Duolingo我觉得值得尝试（如果时间比较紧张，并且很多学校也认可这个成绩 UW UIUC JHU CU NYU） 也是老师推荐的，很明显的，duolingo 很吃大量练习，不过 duolingo 的练习并没有托福强度这么大。&lt;/p>
&lt;p>语言我也觉得自己给不了什么很好的建议，至于报班这件事，我自己确实花了很多money，我感觉过来，技巧性的东西 学一遍，你要反复运用就可以了（B站其实也有很多资源），剩下的确实还是能力的问题。我愿意报班可能也会有种 拿钱消灾的心态，虽然也很努力（可能是不在走路，是对着南墙狠狠的撞），但是赔了夫人又折兵的感觉真的很不好。&lt;/p>
&lt;p>要有什么其他建议的话，那确实就是早点准备，但是心态一定要放平，还是那句：人生的容错远远超过你的想象（谢谢Lulu老师）。&lt;/p>&lt;/blockquote>
&lt;h3 id="软背景">软背景
&lt;/h3>&lt;p>我把软背景分为了四个模块，分别是&lt;strong>交换&lt;/strong>，&lt;strong>科研&lt;/strong>，&lt;strong>实习&lt;/strong>和&lt;strong>竞赛&lt;/strong>。我会比较侧重讲科研和竞赛，因为我自己在这两个方面了解的比较多。&lt;/p>
&lt;h4 id="交换">交换
&lt;/h4>&lt;p>交换包括了 学分项目，暑研等等&lt;/p>
&lt;p>我看来，交换有两个很重要的点，认可度和可信度。&lt;/p>
&lt;p>以NU为例，这是一所很偏好海本学校，当然这个海包括了中外合办，你会发现有一些 GPA3.2，3.4的案例，但大部分陆本 GPA 再高也很少要（排除清北华五外）&lt;/p>
&lt;p>那在交换中，最直观的体现就是成绩单，你的成绩单能让他们产生这样的认知：你能够适应国外的教学体制，这是认可度；并且比较好的海外成绩单的成绩，是对成绩的可信度很大加分。&lt;/p>
&lt;p>甚至好一些的情况，你能拿到推荐信，这是我认为在申请中非常重要的东西。你要知道，国外教授的推荐信往往是拿自己的声誉做担保，来推荐学生去某个学校深造。
相比之下，国内的推荐信，大家都知道，已经被“好”，“最好”，“百里挑一”，“千载难逢”等等等等说烂了，所有教授的内容都如出一辙。因此，海外教授的推荐信更被 admission office 认可。&lt;/p>
&lt;p>额外提一嘴，我认识的一个同学，通过 CSC奖学金到 Canada 进行了交换。大家都知道 CSC奖学金去美国交换非常不易，因此可以选择一些加拿大，欧陆的项目尝试一下。&lt;/p>
&lt;h4 id="科研">科研
&lt;/h4>&lt;p>我也是很误打误撞型的，不过我开始就是对大学的老师有一种美好的幻想，觉得老师都是很好的，就很主动去约老师，希望能不能得到一些指导或者帮助。
在我选定导师的时候也是这样，希望老师能够了解自己的未来规划，自己也很能和老师有一个长期的良好关系。&lt;/p>
&lt;p>当然，科研这个事本身就是不能急于求成，老师对你的规划也是一步步的，也总是要有一定的编程基础才能做一些科研，而且课题也不能很难，通常都是学长带着指导的。
但也要有耐心，因为实验和写作都是一次次的反复，不断的调整，你才能慢慢变好。&lt;/p>
&lt;p>甚至你不能指望导师给你带来什么，最多是指明一个方向，
后续都是你自己去读文献，实验，慢慢完成的（这点在研究生上也是通用的，你要意识到，大部分的导师给你的是资源，机会和平台而不是 手把手的教你怎么发论文）&lt;/p>
&lt;p>最后产出了一篇论文，一篇在投论文（这一篇我做了已经一年半了，你要接受，即使你花了这么多时间，你做出来的东西也是依托答辩，update：已经给KDD一脚踹死了，也失去心力将这篇论文继续投出去了）和一篇专利。&lt;/p>
&lt;h4 id="实习">实习
&lt;/h4>&lt;p>我认为这个实习是相当重要的，虽然和交换一样，我并没有特别好的经历。&lt;/p>
&lt;p>我能提醒大家的点，大概有这几个。首先，big title 固然重要，但是你做的内容应该也是重要的，这是技术或者能力的体现，
很简单的在现实中的映射就是，你不是92毕业的，但你比92强，只是在平均水平上，92通常会大于其他学校，但到个人头上，是很 case by case 的。&lt;/p>
&lt;p>第二个点是，像CMU，Wisc（很好的学校 CSPMP）的一些项目，可能就会比较注重实习方面的经历，这个每个项目的特点，我后面会提及一些，但具体的还是需要大家自己花时间在上面，毕竟这么多项目我确实也讲不来。&lt;/p>
&lt;h4 id="竞赛">竞赛
&lt;/h4>&lt;p>我认为 hdu 是一个有很好竞赛氛围的学校（但不代表我支持学校这样在竞赛中的高投入，但这确实是对一个缺少经费的理工科学校最低成本提升学生素质的方法），
而我最大的感受就是，一定要不断的试错，磨合，组成一个好团队，好团队不仅仅是给你带来奖的团队，而是陪你一起成长的人，朋友。&lt;/p>
&lt;p>杭电的竞赛资源很多，这点无可质疑，ACM，数模，智能车，大挑小挑等等 成绩其实都不错而且你要是想惨与 并不是很难，组建一个好的团队 就很重要了。&lt;/p>
&lt;p>我竞赛经历是相当丰富的，但也没有什么大奖。我进来打过了大大小小差不多十次左右的数模吧，美赛H和国赛省二可能并不是很好。
插入一句，这个竞赛确实在经验上丰富了我很多，但在我意识到，再努力可能也就是奖项上的努力，并且当时我们有更重要的事情去做，我们团队也就放弃了数模这件事。后来我还参与了像服务外包，证投等一些项目。&lt;/p>
&lt;p>对于我来说，成果比较好的应该就是大创吧，我们团队是学校第一（大家真的都很努力，在后来的挑战杯，我们好像只有校二吧，所以不同竞赛的特性真的很不一样（为了拿奖，一定还是要按照特性来准备），挑战杯，你需要准备的可能就是积累很久的成果），
唯二重点领域支持，所以我在CV中强调的也就是这个项目，写上，我们做了什么事，（我们的系统是）给多少的婴幼儿带来了有效的治疗（这是我不知道在哪看到，美国大学可能会比较喜好，那些愿意为社会做贡献的学生，你的创新，点子怎么给社会，社区带来了怎样的贡献）&lt;/p>
&lt;p>这里产出了一篇专利，一篇软著。&lt;/p>
&lt;h2 id="申请以及中介">申请以及中介
&lt;/h2>&lt;p>先来谈谈中介，在整个申请流程上，中介帮你做的无非就这三件事：&lt;strong>规划&lt;/strong>，&lt;strong>选校&lt;/strong>，&lt;strong>文书&lt;/strong>。规划，应该是前面这一部分&lt;strong>需要准备些什么&lt;/strong>中提到的，
而后两者则是这个阶段比较重要的事情了，我会展开的更多。&lt;/p>
&lt;h3 id="规划">规划
&lt;/h3>&lt;p>规划简单点来说就是在合适的时间完成合适的事情，如果你是一个很有规划，自制能力，并且不喜欢被拘束的学生，这条完全可以由自己来进行掌控，
虽然我自己确实掌控出事了（托福没考出来），但我规划这件事本身就是自己要对自己负责，这应该是你在大学的一门必修课。&lt;/p>
&lt;h3 id="选校选项目">选校（选项目）
&lt;/h3>&lt;p>这可能是一件很累的事情，但是也是一个探索的过程。
在选校的过程中，会突然发现，原来有这么一个项目很适合我，会非常的开心。&lt;/p>
&lt;p>这个点上，其实我自己也不是很担心，甚至我觉得我对我需要申请的相关项目的了解会比我的中介老师还要丰富，
因为你要关注的包括学校，地理位置，项目质量（课程，COOP CPT OPT），项目大小（人数规模），课程设置，费用，回国认可度等等的各类问题，综合考量之下，选出最适合自己的。&lt;/p>
&lt;p>PS：美国真的有很多宝藏学校，只是在大陆知名度确实太低了，Vandy，圣母，Lehigh等等，这些需要自己去发现，但可能也是一个挖宝的过程，也需要承担一些风险。&lt;/p>
&lt;p>如果本身无所谓世俗喧嚣，并且希望去科研，我觉得一些小城市也不是很差的选择（ucsb）；但目的性很强的就业，那么地理位置就非常重要的（UW, UC）；
费用的高低（UFL，wisc，UW，Gatech）Vs（rank很高的私校）整体费用相差可能超过一倍，甚至贵的在某些方面不如便宜的。&lt;/p>
&lt;p>那么需要做的事，就是先选定自己大概申请的范围 DS，ECE，CS, CS+Urban + 一些宝藏项目，OpenCS 小红书，一亩三分地，Google，学校官网（学院级别的）&lt;/p>
&lt;p>看的差不多了，你也就知道自己的位置在哪里了，但请大胆一些，如果有两三个保底在，那可以尝试申的更激进一点。&lt;/p>
&lt;h3 id="文书">文书
&lt;/h3>&lt;p>这个我是相当不自信的，所以确实需要一个老师来带着我改（这也是我选择需要中介的主要原因），
大概就是头脑风暴一下，你要将你自己的故事讲出来（为什么做，怎么做和结果是什么）。&lt;/p>
&lt;p>你的大学应该是串了珠子的一条线，而不是离散的，或是散落的珍珠。
我第一次体会到这件事就是我看研究生毕业论文的时候，特别是博士毕业论文。他们的毕业论文就代表了他们的五年研究生生涯，是怎么开始这个课题，
把你这五年的研究都写在厚厚的毕业论文之中，你这五年做的大部分的内容都会在最后，写成这样一本书。&lt;/p>
&lt;p>这里，我和一个老师聊过（不是留学相关的老师），他很建议我把写文书也当作是自己的事情，自己来写，让文书老师知道如何改，相当于，文书老师也只是一个辅导作用，你要知道，留学这件事，本身就是你自己的事，而且他一点都不难，只是你没有这个看似需要非常老道的经验。
自己亲身经历一遍，反而才是对待留学比较正确的样子。&lt;/p>
&lt;p>不过身边也有很多同学，把材料通通丢给机构，让他们处理好即可，非常的省心省力。都是选择吧，没什么评判的，适合自己就好。&lt;/p>
&lt;h3 id="那需不需要中介呢">那需不需要中介呢
&lt;/h3>&lt;p>结合我上面提到的三点，你就会知道，到底需不需要中介，需要怎么样的中介。&lt;/p>
&lt;p>我自己大概在一年半前时间，就是聊了大概大大小小的十多家机构，每天都在地铁跑来跑去，我一定要线下见过，聊一聊才能看出是不是“情投意合”，最后选择了适合自己的。&lt;/p>
&lt;p>Tips：有学长学姐推荐是最好的，并且不要把自己局限在杭州这个城市。&lt;/p>
&lt;hr>
&lt;p>大概也就这些了，如果后续想起什么我还会补充的，我把当时Pre所用的PPT放在 &lt;a class="link" href="https://docs.google.com/presentation/d/1j1-bz-69JyCxoksLsKsWBY1kTzIhf3oz/edit?usp=sharing&amp;amp;ouid=113218177613811328824&amp;amp;rtpof=true&amp;amp;sd=true" target="_blank" rel="noopener"
>Googledoc&lt;/a> 上，方便大家更好食用。&lt;/p>
&lt;p>如果想和我聊一些留学的内容或者做一些咨询，也非常欢迎联系我！&lt;/p></description></item><item><title>NebulaGraph × PyG</title><link>https://caifengze.com/zh-cn/blog/2025/nebulagraph-pyg/</link><pubDate>Mon, 18 Aug 2025 03:58:00 +0800</pubDate><guid>https://caifengze.com/zh-cn/blog/2025/nebulagraph-pyg/</guid><description>&lt;img src="https://caifengze.com/zh-cn/blog/2025/nebulagraph-pyg/cover.png" alt="Featured image of post NebulaGraph × PyG" />&lt;p>这篇文章更像一个“反思录”，记录一下整个 &lt;a class="link" href="https://github.com/Fengzdadi/nebula-pyg" target="_blank" rel="noopener"
>nebula-pyg&lt;/a> 的开发过程。&lt;/p>
&lt;h2 id="初逢">初逢
&lt;/h2>&lt;p>还是要先感谢 &lt;a class="link" href="https://summer-ospp.ac.cn/" target="_blank" rel="noopener"
>OSPP&lt;/a> 这个平台，让我遇见了 NebulaGraph 社区和 wey-gu老师。&lt;/p>
&lt;p>当然，项目还是需要竞争的，记得最初钟意的项目有 Kwok 的 “为 KWOK 添加 模拟真实 Pod 行为的策略配置”，以及现在就在做的
“NebulaGraph PyG Integration”。&lt;/p>
&lt;p>我是那种非常害怕竞争的人，要面试，讲想法（其实就是太菜了，如果你够了解，对这些东西应该是侃侃而谈的）。
即使我非常想尝试云原生相关的内容，最后因为觉得自己不熟练，放弃了，转而投向我更熟悉的 PyG 。&lt;/p>
&lt;p>现在去查了一下 四月份和 wey-gu老师 交流的邮件，来回总共七封，我竟然写了五封哈哈，其中第一封被错过了，大概十天后进行了 follow-up。得到了回复。
客观点来说，我现在看当时的邮件，感觉我像是早早滚蛋的样子。&lt;/p>
&lt;p>后来加上了X，老师的交流一下子就轻松了很多，简单说明了一下我的想法后，就开始等待第一次的线上交流。&lt;/p>
&lt;p>这次交流也是很意外的一件事哈哈，好像我并没有被通知到具体在几点参加会议，然后立马找了个咖啡厅进去，一脸懵逼的进，一脸懵逼的出。&lt;/p>
&lt;p>交流的时候，发现和我一起参与这个项目的两位也都很厉害，并且其中一位，在后续开发过程中，在一些相关搜索的时候，Google到了。
能通过他的Blog，他在准备的时候也做了好多相关工作。&lt;/p>
&lt;p>那我也是很辛运的一位了!&lt;/p>
&lt;p>（突然想知道为什么是我入选哈哈哈）&lt;/p>
&lt;p>接着就是长时间的等待结果了。录取！&lt;/p>
&lt;h2 id="设计">设计
&lt;/h2>&lt;p>这个项目的设计，整体上是参考了 &lt;a class="link" href="https://blog.kuzudb.com/post/kuzu-pyg-remote-backend/" target="_blank" rel="noopener"
>KUZU&lt;/a> 所做的，给 PyG 做 remote 适配的工作。&lt;/p>
&lt;p>框架大体上是相同的，在细节上会因为 nebulagraph 的特性做一些特殊处理。&lt;/p>
&lt;h2 id="框架">框架
&lt;/h2>&lt;p>总的来说，比较核心的点是实现 PyG 中的 &lt;code>FeatureStore&lt;/code> 和 &lt;code>GraphStore&lt;/code> 这两个接口。&lt;/p>
&lt;p>在上层，会为实例化这两个接口做一个额外的类，来满足一行代码就能返回两个实例，也就是现在的 &lt;code>NebulaPyG&lt;/code> 这个类。
&lt;code>NebulaPyG&lt;/code> 这个类还写了一个方法 &lt;code>create_snapshot()&lt;/code> 专门解决 &lt;a class="link" href="#vid" >vid&lt;/a> 问题。&lt;/p>
&lt;p>将 &lt;code>FeatureStore&lt;/code> 和 &lt;code>GraphStore&lt;/code> 这两个接口中的工具类通用化，放在了 utils.py 和 type_helper.py 的包中。
其中包括对特征的维度判断工具 &lt;code>get_feature_dim()&lt;/code>，为产生全局 snapshot 的 &lt;code>scan_all_tag_vids()&lt;/code> 等等。&lt;/p>
&lt;p>同时引入了一个 &lt;code>base_store&lt;/code>，给 &lt;code>FeatureStore&lt;/code> 和 &lt;code>GraphStore&lt;/code> 来继承，来专门处理 PyG 中的 &lt;code>DataLoader&lt;/code> 中的 &lt;a class="link" href="#%e5%a4%9a%e8%bf%9b%e7%a8%8b%e5%a4%84%e7%90%86" >多进程问题&lt;/a>。&lt;/p>
&lt;p>以下是整体上的类关系图。&lt;/p>
&lt;p>&lt;img src="https://caifengze.com/zh-cn/blog/2025/nebulagraph-pyg/1_overview_of_nebula-pyg_class_relationships.png"
width="3840"
height="2592"
srcset="https://caifengze.com/zh-cn/blog/2025/nebulagraph-pyg/1_overview_of_nebula-pyg_class_relationships_hu_c5d9d653c32a2341.png 480w, https://caifengze.com/zh-cn/blog/2025/nebulagraph-pyg/1_overview_of_nebula-pyg_class_relationships_hu_75a3f6c60855495d.png 1024w"
loading="lazy"
alt="1_overview_of_nebula-pyg_class_relationships.png"
class="gallery-image"
data-flex-grow="148"
data-flex-basis="355px"
>&lt;/p>
&lt;h2 id="细节">细节
&lt;/h2>&lt;h3 id="环境">环境
&lt;/h3>&lt;p>这是在开发 nebula-pyg 前遇到的一个很重大的问题。第一次发现自己对环境这么不熟练。&lt;/p>
&lt;p>第一个是环境管理，nebula-python 选用的是 &lt;a class="link" href="https://pdm-project.org/en/latest/" target="_blank" rel="noopener"
>pdm&lt;/a>，一个相对不错的包管理工具。
为什么说相对不错呢？&lt;/p>
&lt;ol>
&lt;li>pdm 并没有让我体会到方便，里面还是有挺多坑的。其最主要的功能还是弥补了传统的 &lt;code>venv&lt;/code> 等等没有的，依赖包的版本一致性问题（比如 nebula-pyg 依赖 A 包，A 包依赖 B 包，传统的 &lt;code>venv&lt;/code> 能指定 A 包的版本，但不能指定 B 包的版本，就会容易出现 A1 依赖 B 的 &lt;code>X.1-X.2&lt;/code> 版本，A2 依赖 B 的 &lt;code>X.2-X.3&lt;/code> 版本，这个时候 pdm 就能发挥作用把的 B 指定为 &lt;code>x.2&lt;/code> 版本）。这个功能可能因为我并不是多端协作开发，暂时没有深刻体会到。&lt;/li>
&lt;li>pdm 对 torch 的支持我觉得很一般，要自己进行配置，而且像 &lt;code>torch-vision&lt;/code> 之类的包，确实出了很奇怪的安装意外。印象中这个问题可能普便存在，之前使用 &lt;code>miniconda&lt;/code> 也出现过类似的问题。&lt;/li>
&lt;li>经过调研，和 wey-gu 老师的讨论，现在 uv 差不多要一统天下了（哪天我也去试试）。&lt;/li>
&lt;/ol>
&lt;p>第二个便是 nebulagraph 的环境。目前社区版的 nebulagraph 的 storaged 只能被同一网络下的 python interpretation 访问，不能被外部网路访问。
这就导致使用 nebula-pyg 需要将两者 nebulagraph 和 nebula-pyg 所使用的 python interpretation 安装在同一网络下。
并且 nebulagraph 仅能在 &lt;a class="link" href="https://docs.nebula-graph.com.cn/3.8.0/4.deployment-and-installation/1.resource-preparations/#_4" target="_blank" rel="noopener"
>指定的 linux 环境下安装&lt;/a>。&lt;/p>
&lt;p>那用户使用 nebula-pyg就有两种情况：&lt;/p>
&lt;ol>
&lt;li>使用 特定的 linux 系统，并在该环境下安装了 nebulagraph，解释器也运行在本地。&lt;/li>
&lt;li>使用 docker-compose 来启动 nebula-graph，然后将 python解释器 安装在同一网络中，通过 ssh 进行开发或者使用。注意：并不是很推荐使用 WSL，因为 WSL 存在严重的IO问题（wey-gu老师提醒的，并且在后续实践中确实出现了这个导致的 storaged 崩坏问题，以及文件的读写问题）&lt;/li>
&lt;/ol>
&lt;p>当然，以上推荐方式1。&lt;/p>
&lt;h3 id="vid">vid
&lt;/h3>&lt;p>nebulagraph 的 &lt;a class="link" href="https://docs.nebula-graph.com.cn/3.8.0/1.introduction/3.vid/" target="_blank" rel="noopener"
>VID&lt;/a> 支持 &lt;code>FIXED_STRING(&amp;lt;N&amp;gt;)&lt;/code> 和 &lt;code>INT64&lt;/code> 两种类型。
而 PyG，对 edge_index 有 &lt;code>{0,……，num_nodes-1}&lt;/code> 的&lt;a class="link" href="https://pytorch-geometric.readthedocs.io/en/latest/notes/introduction.html?highlight=only&amp;#43;hold&amp;#43;indice&amp;#43;range#:~:text=Note%20that%20it%20is%20necessary%20that%20the%20elements%20in%20edge_index%20only%20hold%20indices%20in%20the%20range%20%7B%200%2C%20...%2C%20num_nodes%20%2D%201%7D." target="_blank" rel="noopener"
>要求&lt;/a>。&lt;/p>
&lt;p>那这个转换到底要不要做呢，在 KUZU 的实现中，这个问题被留给了用户，用户在导入数据的时候，要求 index 必须满足上面的要求。
现在反思过来看，这个问题交给用户，也是一个不错的方案。仅从科研角度来看，市面上大多数的数据集中，index 都被限制在了这个范围。&lt;/p>
&lt;p>不过对于工业级别的数据，大多数都是基于一定规则的 uuid，或者基于 snowflake 生成的 id。特别是在分布式数据库中，大部分情况不会是自增的int。这个时候，VID 的映射就特别有必要了。&lt;/p>
&lt;p>在设计映射方案的时候，曾考虑过 KV-Cache，经过 wey-gu 老师的建议，主要结合了两个点：&lt;/p>
&lt;ol>
&lt;li>考不考虑动态场景？这个的回答是不太需要，即使是工业级别，snapshot 做一个 subgraph，速度还是非常快的。&lt;/li>
&lt;li>删除 tag 的时候连续序号需要怎么处理？这个在 KV-Cache 中非常难处理。&lt;/li>
&lt;/ol>
&lt;p>综合以上，采用了 Snapshot这个方案（go snapshot！），并使用 python 原生的 pickle 进行持久化。&lt;/p>
&lt;p>snapshot 产生的 pickle 文件 会包含有一下几个内容：&lt;/p>
&lt;ul>
&lt;li>&lt;code>vid_to_idx&lt;/code>&lt;/li>
&lt;li>&lt;code>idx_to_vid&lt;/code>&lt;/li>
&lt;li>&lt;code>vid_to_tag&lt;/code>：节点分类信息&lt;/li>
&lt;li>&lt;code>edge_type_groups&lt;/code>：三元组信息&lt;/li>
&lt;/ul>
&lt;p>前面两个看似重复的反向设计并不是冗余，而是 &lt;code>dict&lt;/code> 里面的 KV 对正向的查询更快，时间复杂度应该是 O(1)，如果在想通过 idx 去找 vid 的时候仅仅用 &lt;code>vid_to_idx&lt;/code> ，时间复杂度就会到达 O(n)。&lt;/p>
&lt;h3 id="featurestore-的扫描策略">FeatureStore 的扫描策略
&lt;/h3>&lt;p>大概在8月初的时候，我用了 nebulagraph 文档中 &lt;a class="link" href="https://docs.nebula-graph.com.cn/3.8.0/nebula-studio/quick-start/st-ug-plan-schema/#schema" target="_blank" rel="noopener"
>规划 Schema&lt;/a> 部分的示例数据集 basketballplayer 做完了所有的测试。
当全部测试跑通了以后，非常开心，已经早早的做下一步规划了。&lt;/p>
&lt;p>噩梦出现在决定做一个大规模数据集的案例。&lt;/p>
&lt;p>当时选用的是 &lt;a class="link" href="https://ogb.stanford.edu/docs/nodeprop/#ogbn-products" target="_blank" rel="noopener"
>ogbn-products&lt;/a>，我认为一个非常经典的例子。当我挂起他的时候，过了约莫一小时，并没有什么动静。
在当时的我看来应该是性能问题，可能会考虑到 WSL I/O，以及自己电脑性能。&lt;/p>
&lt;p>出去玩完约莫七个小时回到家后，看到还是一成不变的进度，我惊呆了，2,449,029 个 NODE 在我印象中并不会出现这么严重的性能问题，七个小时都读不完。
但我仍对数据集大小保持怀疑态度，于是，使用了&lt;a class="link" href="https://ogb.stanford.edu/docs/nodeprop/#ogbn-arxiv" target="_blank" rel="noopener"
>ogbn-arxiv&lt;/a>。并进行断点打印，
发现在读取数据中进行了无数轮次的&lt;code>scan_vertex_async&lt;/code>。那这是怎回事？&lt;/p>
&lt;p>我最初对 &lt;code>get_tensor&lt;/code> 的设计是调用 storaged 的 &lt;code>scan_vertex_async&lt;/code>（这个接口也是我 PR 到 nebula-python 中的，好像暂时没有更新）（更新：在10月18号成功&lt;a class="link" href="https://github.com/vesoft-inc/nebula-python/pull/377" target="_blank" rel="noopener"
>merge&lt;/a>！）。
这个接口做的工作是对图进行全局扫描，获得全局数据中指定 tag 的指定 prop。但它少了一个功能，就是获取指定 index 中的点。我在设计中对这个点的处理是，通过比较所需的 index 和 scan 出来的全图的点，
再将所需要点的 prop 进行返回。(后面就知道这是一个非常糟糕的设计了)&lt;/p>
&lt;p>我们来重新理一下流程，就知道，到底是什么地方出问题了。PyG 在使用 &lt;code>Neighborloader&lt;/code> 会先获取点的列表，根据 batch_size 这个参数，加载周围的点。
例如 &lt;code>batch_size = 32&lt;/code>。那就会从点的 List 里面获取 32 个点，然后再获取这 32 个点的邻点，将这些点作为一个 index，调用 &lt;code>get_tensor&lt;/code>。&lt;/p>
&lt;p>在 ogbn-arxiv 中，这个数量大约为 600 多个。&lt;em>进行 &lt;code>get_tensor&lt;/code> 的次数一般由 feat 数量（这是我踩的另外一个坑 &lt;a class="link" href="#get_tensor-%e4%b8%ad%e7%9a%84-xy-%e5%a4%84%e7%90%86" >get_tensor 中的 x,y 处理&lt;/a>），和进行几轮 epoch，几次batch训练决定的。&lt;/em>
所以使用 &lt;code>scan_vertex_async&lt;/code> 这样的全局扫描接口，从数据集中获取数据，每次都会扫描出 169,343 Node，和实际仅需的 600 多个 Node 进行比较一下就会发现，这是性能上的极大浪费。&lt;/p>
&lt;p>这时，我们来比较一下 KUZU的处理方式 和 wey-gu 老师之前为 dgl 写的 &lt;a class="link" href="https://github.com/wey-gu/nebula-dgl" target="_blank" rel="noopener"
>nebula-dgl&lt;/a>（刚刚才仔细的看了一下，之前只知道有这个项目哈哈哈）：&lt;/p>
&lt;ol>
&lt;li>KUZU: KUZU 很干脆，他的 &lt;code>scan_vertex&lt;/code> 函数中，有 indices 这个参数，能直接根据 indices(index) 直接从 storage 中获取指定 indice 的 prop。&lt;/li>
&lt;li>nebula-dgl：一般在训练的时候，dgl 会 scan 全图，读取data，生成这个图对象，之后的操作都是默认从图对象 g.ndata/edata 里按需切片。所以并不是涉及和 PyG 类似的频繁的读写。(这里觉得要是早点看到，也可以知道有query这个方案去针对小图，子图了)&lt;/li>
&lt;/ol>
&lt;p>对于方案一，我是觉得非常方便，只需要在 nebulagraph 的 stroaged 中加入一个算子即可。但这个方案被直接否决了。
反思一下，我记得不太清楚，wey-gu老师和我说的是 storaged 只适合做全图扫描，并不适合做条件查询。&lt;/p>
&lt;p>经过一些资料查证，首先是，nebulagraph 的 storaged 是基于 RocksDB（PS：有空可以研究一下 RocksDB！），有天然的顺序读（iterator）方案，直接具有全图遍历的功能。
第二个是，如果想实现这个功能，至少要做谓词求值、联合条件、选择最佳索引、回表取属性、聚合/去重/排序这些事情，从职责上来讲，这些都是 query 优化器的工作，最终还是应该由 graphd 来做。&lt;/p>
&lt;p>那最后也是在 wey-gu 老师的建议下，选择了 ngql 进行相关操作，并且 wey-gu老师有说，nebulagraph 对我描述的操作做了进一步的优化。
通过后续的测试发现也是，在 100,000 个级别的点 fetch 中，能够在 1.2-1.5s 左右返回所有数据。&lt;/p>
&lt;p>最终的解决方案也很简单，使用 &lt;a class="link" href="https://docs.nebula-graph.com.cn/3.8.0/3.ngql-guide/7.general-query-statements/4.fetch/" target="_blank" rel="noopener"
>fetch&lt;/a> 语句查询即可。
当然，还有 &lt;a class="link" href="https://docs.nebula-graph.com.cn/3.8.0/3.ngql-guide/7.general-query-statements/2.match/" target="_blank" rel="noopener"
>match&lt;/a> 方法。
match 更强大，比如能处理多跳子图等功能，但在性能上弱于&lt;code>fetch&lt;/code>，并且没有其他功能的需求，只是根据 &lt;code>index&lt;/code> 获取点的属性值，因此还是选用了&lt;code>fetch&lt;/code>。&lt;/p>
&lt;h3 id="get_tensor-中的-xy-处理">get_tensor 中的 x,y 处理
&lt;/h3>&lt;p>这个也是最初没有考虑到的问题。&lt;/p>
&lt;p>上面说的：&lt;/p>
&lt;blockquote>
&lt;p>进行 &lt;code>get_tensor&lt;/code> 的数量一般由 feat 数量……决定的。&lt;/p>&lt;/blockquote>
&lt;p>是因为在训练过程中，PyG 都会根据 &lt;code>get_all_tensor_attrs&lt;/code> 来获取属性列表，根据这个列表，在每一组 epoch 的每一次 batch 中都要对每一个存在于属性列表中的属性进行 &lt;code>get_tensor&lt;/code> 操作。
比如在 ogbn-arxiv 中，有 feat0，feat1 …… feat128， 这样 128 个属性列 和 label 标签列。
PyG就会使用 128+1 次的 &lt;code>get_tensor(attr=TensorAttr(group_name=&amp;quot;paper&amp;quot;, attr_name=&amp;quot;feat0&amp;quot;, index=...))&lt;/code> 进行特征/属性的获取。&lt;/p>
&lt;p>在上个部分，我每次都能看到 大约100多次训练以后就报错，我就开始怀疑，是 attr 部分的问题。因为 PyG 的模型训练，会要求存在 &lt;code>data.x&lt;/code> 和 &lt;code>data.y&lt;/code>。
但我并没有，我只有 feat0-feat128 和 label 列。&lt;/p>
&lt;p>那现在的任务就变成了 需要将 feat0-feat128 变为 &lt;code>data.x&lt;/code>，label 列变为 &lt;code>data.y&lt;/code>。&lt;/p>
&lt;p>（看别人的处理方法真的能学到很多）&lt;/p>
&lt;p>我看了 KUZU 对这个问题的解决方法，其实就是没有方法哈哈哈。因为其要求用户导入的特征数据就为&lt;a class="link" href="https://blog.kuzudb.com/post/kuzu-pyg-remote-backend/#:~:text=x%3A%20128%2Ddimensional%20node%20features%20%28so%20128%2Dsize%20float%20tensors%29" target="_blank" rel="noopener"
>多维度的 tensor float 类型&lt;/a>（应该是 vector 了）。&lt;/p>
&lt;p>那么解决这个问题的方案，就只能我们自己来想。&lt;/p>
&lt;p>因为 nebulagraph 并不支持 vector，更糟糕的是，也不支持&lt;a class="link" href="https://docs.nebula-graph.com.cn/3.8.0/3.ngql-guide/3.data-types/6.list/#:~:text=%E5%A4%8D%E5%90%88%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B%EF%BC%88%E4%BE%8B%E5%A6%82%20List%E3%80%81Set%E3%80%81Map%EF%BC%89%E4%B8%8D%E8%83%BD%E5%AD%98%E5%82%A8%E4%B8%BA%E7%82%B9%E6%88%96%E8%BE%B9%E7%9A%84%E5%B1%9E%E6%80%A7%E3%80%82" target="_blank" rel="noopener"
>复合数据类型&lt;/a>（例如 List、Set、Map）。
所以在存数据的时候，和原来一样，只能存入 feat0-feat128 这样 128列 的特征向量。&lt;/p>
&lt;p>那第一个问题，就是这个 &lt;code>feature&lt;/code> 的合成以及 &lt;code>label&lt;/code> 的转换过程是由 nebula-pyg 来处理，还是用户自行处理。&lt;/p>
&lt;p>先来处理简单的，也就是 label。这个我认为在 nebula-pyg 中并不是很难解决的问题。&lt;/p>
&lt;p>为此，我引入了 &lt;code>Y_CANDIDATES&lt;/code> 这个常量，默认了 &lt;code>label&lt;/code>，&lt;code>y&lt;/code>，&lt;code>target&lt;/code>，&lt;code>category&lt;/code> 这几个标签为 &lt;code>data.y&lt;/code> 的标签。
在读取的过程中，能够直接将这个几个标签的特征量转换为 &lt;code>data.y&lt;/code>。&lt;/p>
&lt;p>接下来就是 &lt;code>feature&lt;/code> 的处理了。这里同样是交给用户还是 nebula-pyg 来解决的问题。主要考虑的点有以下几个：&lt;/p>
&lt;ol>
&lt;li>在我的经验，如果一些特征是经过特殊处理的，这些特殊处理的特征，很可能就是需要进行相当量的消融实验，而用户在拼接的过程中，只需要从 &lt;code>data.x = [data.feat0,……，data.feat128]&lt;/code> 中删除不需要的列即可。&lt;/li>
&lt;li>要用户自己进行拼接，即要用户多写两行代码，从使用体验上来说会非常的不佳。&lt;/li>
&lt;/ol>
&lt;p>既然两者都好，那就两者都要！&lt;/p>
&lt;p>那我们就需要进行一个模式区分，我引入了 &lt;code>expose&lt;/code> 这个参数，有两个 mode，&lt;code>x&lt;/code> 和 &lt;code>feats&lt;/code>，默认为 &lt;code>x&lt;/code>。当用户需要自行处理特征的时候，即可使用 &lt;code>feats&lt;/code>。&lt;/p>
&lt;p>&lt;code>x&lt;/code> 模式下的主要处理大致为，当调用 &lt;code>get_all_tensor_attrs&lt;/code> 会生成一个含有所有 &lt;code>feat&lt;/code> 的 &lt;code>dict&lt;/code>，并只返回 &lt;code>x&lt;/code>, &lt;code>y&lt;/code>。当 PyG 接收到 &lt;code>x&lt;/code> 后，会用这个 &lt;code>x&lt;/code> 作为调用 &lt;code>get_tensor&lt;/code> 的 &lt;code>attr.attr_name&lt;/code> 的参数，
&lt;code>get_tensor&lt;/code> 会自行进行识别，并读取之前所说的 &lt;code>dict&lt;/code>，然后一次返回含有所有 &lt;code>feat&lt;/code> 的 &lt;code>data.x&lt;/code>。&lt;/p>
&lt;p>（2:26am，作息真的很爆炸了，已经盖上电脑20min了，然后又把它打开，想一次性写完）&lt;/p>
&lt;h3 id="多进程处理">多进程处理
&lt;/h3>&lt;p>这一段内容其实也很长，我在完成这个事情的时候，觉得很值得，为此直接写了一篇doc，专门介绍这一部分内容，详细可以看 &lt;a class="link" href="https://github.com/Fengzdadi/nebula-pyg/blob/main/doc/Multi-process/Multi-process_zh-CN.md" target="_blank" rel="noopener"
>Multi-process description&lt;/a>
这里的 blog 也主要讲述的是心路历程，而不重在具体的解决细节。&lt;/p>
&lt;p>还记得 &lt;a class="link" href="#featurestore-%e7%9a%84%e6%89%ab%e6%8f%8f%e7%ad%96%e7%95%a5" >FeatureStore 的扫描策略&lt;/a> 这一部分引入了 &lt;code>query&lt;/code> 嘛。怎么说呢，这个工作真的给我带来了很大的麻烦。
一个问题的引入，引出了三个工程量都非常大的问题，&lt;a class="link" href="#featurestore-%e7%9a%84%e6%89%ab%e6%8f%8f%e7%ad%96%e7%95%a5" >FeatureStore 的扫描策略&lt;/a>，&lt;a class="link" href="#get_tensor-%e4%b8%ad%e7%9a%84-xy-%e5%a4%84%e7%90%86" >get_tensor 中的 x,y 处理&lt;/a> 和当下这个。&lt;/p>
&lt;p>印象中，引出这个问题的时候，是当我把 &lt;code>num_workers&lt;/code> 设置为非1，&lt;code>query&lt;/code> 的 &lt;code>resp&lt;/code> 就出现了各种串位。&lt;/p>
&lt;p>继续来讲问题的原因，在代码中，&lt;code>query&lt;/code> 是被 &lt;code>session&lt;/code>（&lt;code>graph client&lt;/code> or &lt;code>gclient&lt;/code>）执行的。而 PyG 的 &lt;code>DataLoader&lt;/code> 的 &lt;code>num_workers&lt;/code> 参数是可以开启多进程读数据的。此时，session 的独立性就尤为重要。&lt;/p>
&lt;p>nebulagraph 的 &lt;code>session&lt;/code> 并不安全，即使 nebula-python 还专门实现了 &lt;code>session_pool&lt;/code>，很可惜但也不可惜，可惜的是，wey-gu老师说这个&lt;code>session_pool&lt;/code>也不安全；不可惜的是，这是在我做完这部分工作以后才发现的，我也不想工作白费哈哈哈。&lt;/p>
&lt;p>最初的设计里，用户仅需初始化一个 gclient（连 graphd）和 sclient（连 storaged），后续所有的操作都是通过这两个对象。
这个问题前面不涉及频繁 &lt;code>query&lt;/code> 的时候并没有出现，因为之前的 &lt;code>scan&lt;/code> 全图，少说也要十几秒一次，并且每次的 &lt;code>resp&lt;/code> 都是相同的，即使串位了也无所谓。&lt;/p>
&lt;p>那问题解决的细节，我在此就不赘述，详细内容都在上面的 doc 中。我大概的提一下几个比较值得关注的点：&lt;/p>
&lt;ol>
&lt;li>PyTorch 中的 &lt;code>DataLoader&lt;/code> 是有 &lt;strong>Fork&lt;/strong> 和 &lt;strong>Spawn&lt;/strong> 两种模式的，如果是后者，可能都不需要我写这个算子来解决了。&lt;/li>
&lt;li>当前是通过工厂函数&amp;amp;懒加载的方案解决，我其实还在寻求更方便的模式，即使我已经写了一个工厂函数的utils，但还是没有commit，我觉得参数传递还是一个很大的问题，暂时没有找到很好的方案。&lt;/li>
&lt;li>并没有做内存占用的测试，这个应该如何进行？&lt;/li>
&lt;/ol>
&lt;hr>
&lt;p>至此，恭喜一下自己🎉，完成了一个鲁棒性不错，功能支持丰富的 nebula-pyg，至少我觉得比 KUZU 丰富一些。&lt;/p>
&lt;h2 id="余音">余音
&lt;/h2>&lt;p>写到这里，技术上的流水写完了。脑子里还有很多生活上以及后续的流水。&lt;/p>
&lt;p>非常感谢wey-gu老师，我还是想写写感谢在哪哈哈。&lt;/p>
&lt;p>就按时间线来讲吧，最开始我真的很害怕，因为我完全不知道 wey-gu老师 是怎么样的人，我的印象只有“怎么还不回我邮件”，“我真的要压上我全部家当在这个项目上吗？”。
这么焦虑的原因，可能也是因为我是很在意合作体验的人，我非常乐意请教合作，前提是，我内心要先认同，就是那种不能接受完全不熟的人来，如果这样，我会自己封闭自己，可能是 infj 的专属了。&lt;/p>
&lt;p>当加上了X进行简单交流以后，包括线上的一次见面会，我突然发现 WoW，好厉害，我真的能和这么厉害的人合作吗（直接怯战）。&lt;/p>
&lt;p>通过 iyear 的建议，努力给自己刷点存在感，做一些项目的前期调研，刷刷issue，有机会最好来几个PR，狠狠的补自己的项目书，也是不枉努力！&lt;/p>
&lt;p>直到下一件事发生前，我都会觉得，这个 mentor 非常的忙，但也很自由。自由的点在于我在想自己要不要做点日报，周报之类的，wey-gu老师 的反应，就是无所谓，这些都是冗余的。
忙在于，好像就是很忙哈哈。&lt;/p>
&lt;p>下一件事就是搭环境。其实这里心态已经崩溃了，我弄了一个多星期，竟然连环境都没搞定，我都不知道怎么开发。不过好消息是，wey-gu老师 直接就和我视频会议。
知道我还卡在这里了以后，先是给我解释了 nebulagraph 的框架，以及项目开发的大致方向，然后花了将近两小时，远程帮我配好了环境！并在过程中给我讲了很多我不知道的知识，技巧。&lt;/p>
&lt;p>打心底我对远程这个事情还是害怕的，一个是每次找 iyear 的时候，大部分情况的第一回答就是“远程解决不了”，而我在帮别人的时候，也会感受到远程的无力感。所以这次是小小的心灵感受到了充分的温暖哈哈。事后，我还狠狠的和 Hera 姐夸了。&lt;/p>
&lt;p>好像这件事之后，我们再也没有视频过了，一些问题也就是能很简单的通过电话以及文字解决（原来第一段视频远程是最后一段视频远程）。&lt;/p>
&lt;p>七月底，正好因为 VISA 的事，去了趟上海，（偷偷说Hera姐也很支持我去约饭）成功约上老师吃饭。当时也不是饭点，其实应该是我狠狠的在吃，老师我猜当时也不是很饿，陪我聊了两个小时。
对于我来说，真的收获了很多，见到了一些我曾经不知道的模式，更了解开源社区，之后，就会每天在X上闲逛，感觉这里面的人都好精彩。&lt;/p>
&lt;p>VISA的事真的很糟心，那几天的开发感觉就停滞了，后续也不见得进度快起来。老师也安慰了我挺多，但记住的就这样一句话，大概意思是，每天的活力有很多，不必为了这种结果不在你控制范围内的事消耗掉它，你还能用它去创造很多东西！&lt;/p>
&lt;p>突然觉得写到这也差不多，不必事无巨细，其他的，也就是会经常给我share一些开源的工作和工具，真的都很amazing。&lt;/p>
&lt;p>Hera姐也是人美心善的姐姐哈哈，因为（内心同意）这个问题，我就很想跑到余杭去看看 nebula 公司的情况，被Hera姐热情招待了！&lt;/p>
&lt;p>等我写完这个项目再回头看，项目真的不大，几千行的代码，甚至核心代码我感觉在2000行以内，剩下的都是 example，test和doc。但远远比之前写 CRUD 的成就感强多了。
包括但不限于学会以及更加了解 python，docker-compose，WSL，pdm等等，还有更强的独立思考，讨论，设计解决方案的能力（至少我现在是很骄傲的），探索各种工具的能力以及对开源社区充满了更多的好奇感，还给社区做出了1行代码的PR。&lt;/p>
&lt;p>戛然而止一下，再来换个话题哈哈。当这个项目真正步入尾声，内心还是些许沮丧的，当然也有开心的点！至少要结束了哈哈（不过不知道后续的维护压力大不大）。
我总是害怕自己从一个环境换到另一个环境，所以项目进入尾声的时候，就意味着，当下从非舒适圈到舒适圈的环境，又要变成了新的“非舒适圈”。&lt;/p>
&lt;p>此外，当再此听到需要将 repo 捐赠给社区的时候，兴奋带有少许难过。我记得 wey-gu老师 第一次和我说 repo 要捐给社区的的时候，真的非常愉悦，哇，我的 repo 也能被社区接受。
而现在的感觉是感觉像是自己养了两个月的，就要走了。BTW，其实开发中期的时候，一直觉得自己的代码很lese，也不会有人用，同类产品都有 KUZU了，为什么还会接受我的呢？
只能说被 wey-gu 老师鼓励了一下，nebulagraph 的客户都非常的大牌哈哈。突然觉得捐给社区这一个更大的平台，它的未来会更好！&lt;/p>
&lt;p>突然想到一件尴尬的事，每次和 wey-gu老师 聊天的时候，都会狠狠带上您，我想这应该是我从体制教育，传统文化培养下的，“典型的尊重长辈”。
然后就被点了——“不您的”，突然发现，您的疏远感确实好强，wey-gu老师 应该还是很乐意和我平等交流的。
再引申到 iyear 和我提过一次，在社区里，你身份地位是最不被care的，不论是地位，不论年龄，不论国籍，都能和进行你平等的交流。&lt;/p>
&lt;p>That‘s ALL！虽然我也不知道写完了没，但已经想睡觉了哈哈&lt;/p>
&lt;hr>
&lt;p>2025-08-18 03:58AM&lt;/p></description></item><item><title>Hello, Stack：本站搭建记录与一些写作碎碎念</title><link>https://caifengze.com/zh-cn/blog/2025/hello-stack%E6%9C%AC%E7%AB%99%E6%90%AD%E5%BB%BA%E8%AE%B0%E5%BD%95%E4%B8%8E%E4%B8%80%E4%BA%9B%E5%86%99%E4%BD%9C%E7%A2%8E%E7%A2%8E%E5%BF%B5/</link><pubDate>Fri, 15 Aug 2025 20:00:00 +0800</pubDate><guid>https://caifengze.com/zh-cn/blog/2025/hello-stack%E6%9C%AC%E7%AB%99%E6%90%AD%E5%BB%BA%E8%AE%B0%E5%BD%95%E4%B8%8E%E4%B8%80%E4%BA%9B%E5%86%99%E4%BD%9C%E7%A2%8E%E7%A2%8E%E5%BF%B5/</guid><description>&lt;img src="https://caifengze.com/zh-cn/blog/2025/hello-stack%E6%9C%AC%E7%AB%99%E6%90%AD%E5%BB%BA%E8%AE%B0%E5%BD%95%E4%B8%8E%E4%B8%80%E4%BA%9B%E5%86%99%E4%BD%9C%E7%A2%8E%E7%A2%8E%E5%BF%B5/cover.png" alt="Featured image of post Hello, Stack：本站搭建记录与一些写作碎碎念" />&lt;p>这是本站的第一篇文章，用来记录搭建过程与后续写作规划。&lt;/p>
&lt;p>虽然&lt;code>Hugo&lt;/code>还是比较方便的，但第一次使用，很多工作也是通过GPT-5了解的，并且这篇文章的大体框架也是GPT帮我定的。
一开始，总觉得要写一点什么不一样的给这个 Blog 。在GPT-5的建议下，我觉得我得到了统计学概率上的“大家都写什么”，那我就来写点大家都写的内容！&lt;/p>
&lt;p>如果你喜欢这个Blog风格，希望这篇文章能帮助到你。&lt;/p>
&lt;h2 id="为什么选-hugo--stack">为什么选 Hugo + Stack
&lt;/h2>&lt;p>先说一下主观上的原因，主流上的Blog方案有hexo，wordpress，Astro，hugo等等。方案真的非常多，但我听到比较多的，就是前两个和hugo了。
我对hugo有天然好感，一个是因为自己就是大量写go的人；第二个是有段时间在帮朋友维护一个项目的时候，他非常推荐我试试hugo；
加上我在最终选型的时候发现我最近所在的社区(nebulagraph)的Blog，也是用hugo来写的，好感度一下子就上来了。&lt;/p>
&lt;p>选择了hugo以后，那就是选择模板的问题了，我比较钟意的有两个，&lt;a class="link" href="https://hugoloveit.com/zh-cn/" target="_blank" rel="noopener"
>LoveIt&lt;/a>和&lt;a class="link" href="https://stack.jimmycai.com/" target="_blank" rel="noopener"
>Stack&lt;/a>
至于最后为什么选了Stack，可能是我更喜欢这样多层次的观感吧，这个就很缘分了哈哈。&lt;/p>
&lt;p>以下是GPT-5给我的这个回答：&lt;/p>
&lt;ul>
&lt;li>生成快、维护成本低（纯静态，托管到 GitHub Pages 就能跑）。&lt;/li>
&lt;li>主题 &lt;strong>Stack&lt;/strong> 外观清爽，支持暗色、目录、搜索、归档、Open Graph 等常用功能。&lt;/li>
&lt;li>可通过 &lt;code>layouts/partials/head/custom.html&lt;/code> / &lt;code>footer/custom.html&lt;/code> 做&lt;strong>安全的个性化扩展&lt;/strong>（不会改主题源码）。&lt;/li>
&lt;/ul>
&lt;p>第一点我还是要插入一嘴的，今天正好和wey-gu老师聊到hugo，他也非常喜欢，和我说他每次用hexo build都非常慢，看来选型做的非常正确。&lt;/p>
&lt;h2 id="本站关键配置备忘">本站关键配置（备忘）
&lt;/h2>&lt;ul>
&lt;li>配色：莫兰迪风（自定义顶部/底部渐变(我选择了彩色，我希望这是看到最后的一条彩虹🌈)、引用块样式）&lt;/li>
&lt;li>代码高亮：&lt;code>rose-pine-dawn&lt;/code>&lt;/li>
&lt;li>侧边栏挂件：搜索 / 分类 / 标签云 / 归档&lt;/li>
&lt;li>日期格式：&lt;code>2006-01-02&lt;/code>&lt;/li>
&lt;li>Open Graph：Twitter 卡片 &lt;code>summary_large_image&lt;/code>&lt;/li>
&lt;li>搜索：本地 JSON 索引（&lt;code>[outputs].home = [&amp;quot;HTML&amp;quot;,&amp;quot;RSS&amp;quot;,&amp;quot;JSON&amp;quot;]&lt;/code>）&lt;/li>
&lt;li>目录结构：
&lt;ul>
&lt;li>&lt;code>post&lt;/code>：长文 / 教程&lt;/li>
&lt;li>&lt;code>note&lt;/code>：短笔记 / 踩坑记录&lt;/li>
&lt;li>&lt;code>essay&lt;/code>：随笔 / 感想&lt;/li>
&lt;li>&lt;code>photos&lt;/code>：摄影集（每个相册一个页面包 + &lt;code>
&lt;div class="g c-3">
&lt;a class="photo" href="https://caifengze.com/zh-cn/blog/2025/hello-stack%E6%9C%AC%E7%AB%99%E6%90%AD%E5%BB%BA%E8%AE%B0%E5%BD%95%E4%B8%8E%E4%B8%80%E4%BA%9B%E5%86%99%E4%BD%9C%E7%A2%8E%E7%A2%8E%E5%BF%B5/cover.png" target="_blank" rel="noopener">
&lt;img src="https://caifengze.com/zh-cn/blog/2025/hello-stack%E6%9C%AC%E7%AB%99%E6%90%AD%E5%BB%BA%E8%AE%B0%E5%BD%95%E4%B8%8E%E4%B8%80%E4%BA%9B%E5%86%99%E4%BD%9C%E7%A2%8E%E7%A2%8E%E5%BF%B5/cover_hu_65c14d2329a5e477.webp" width="800" height="400"
alt="cover.png" loading="lazy" decoding="async">
&lt;/a>
&lt;/div>&lt;/code> 短代码）&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;h2 id="更具体的分类">更具体的分类
&lt;/h2>&lt;p>我是一个刚开始就喜欢想很多的人，也是某种程度上的长期规划吧，大致我会把写的内容分成一下四块：&lt;/p>
&lt;ul>
&lt;li>长文（post）：主要是技术长文，分享一些教程和实践经验，当然我觉得生活也可以出现在这一块，只是我脑中还没比较好的想法。&lt;/li>
&lt;li>短笔记（note）：这个更像随意的笔记，记录一些想随口说的事情，包括经验和解决方案，或者是一些小技巧，甚至说发发牢骚。&lt;/li>
&lt;li>随笔（essay）：这就更偏向生活，会记录一些书影音评，或者是一些随想，一些感悟。&lt;/li>
&lt;li>摄影集（photos）：这个没什么好说的了，只希望自己多拿拿用一次吃土三个月的相机。&lt;/li>
&lt;/ul></description></item></channel></rss>