2026-04-06 00:00:00
24年9月,刚结束秋招,去秦皇岛待了 2 天。
25年6月,毕业,去大连待了 3 天。
26年4月,又一个人去青岛待了 3 天,不过这次没有什么 milestone,就是单纯想看海了。


其实有了大交通 + 酒店,青岛剩下的景点就不用做什么提前预约和规划了,绝大多数海边的景点都是免费的,如果要去啤酒博物馆,海洋公园,或者崂山,可能需要提前规划/预约一下。
但实测,这三天下来,每天 3w 步,也差不多刚刚好把 栈桥 —— 石老人 这一条滨海线路走一遍。
附上我三天的线路:



青岛站下车以后,直接地铁 3 号线,汇泉广场站下车,步行 5min 就到酒店了。
来青岛以后看了一眼地铁线路图,第一感觉就是 —— 地铁修的真好,整个市南区的海岸线几乎都覆盖到了地铁 (2, 3 号线),所以这三天我也没有打过车,出行全地铁[1]就够了。

到酒店先吃了一顿 200 块的自助,在酒店 25 层的旋转餐厅 —— 这个餐厅居然真的会转,大概 90 分钟自转一圈,由于是附近最高(第二高?)的建筑,可以看到全部的海景和城景。

第一天很不巧,从中午开始以后,全是平流雾[2] + 霾的天气,海边的天气真是非常多变,即使我出行的前一天晚上看天气还是 3 天晴天,到了当天就变成 雾 + 霾 + 风 + 雨。

所以拍出来的照片 be like:


从第一浴场走到栈桥,然后到天主教堂,最后从小鱼山下来回到酒店,其实体验有点一般,市内的景观都是人造的,而老城区的红瓦绿树在这种阴天下又毫无美感。
许多年轻人聚集在「网红墙」前拍照,凑近了看不过是两个路牌,所以当我导航到这里的时候,我甚至直接走过去了才发现原来已经走过了。
—— 所以很多时候不想去那些人文景点,总感觉有些符号营造的太刻意。
晚上的时候,从五四广场随便吃了点东西就往奥帆中心走,因为那里可以看到青岛新城区的灯光秀。
新城区的夜景真的很华丽,全是几十层的高楼,把整个海边染的五光十色。



然后回来以后到酒店楼下的青岛啤酒店,搞了一点青岛啤酒一厂和四厂的原浆和鲜啤:



都很好喝,口感和之前喝过的「泰山7天/28天」非常像,总之比罐装的水啤要好喝很多。
第二天的天气非常的好,于是拿上了我的 xs20 开始暴走模式。
整个白天基本都是在滨海绿道上徒步,文字不足以描述晴天大海的美,放图即可——






上午从第一浴场一直走到了小麦岛,然后下午先坐地铁回来走了一圈八大关,之后又重返小鱼山俯瞰了一下青岛老城,“红瓦绿树,碧海蓝天”,晴天的青岛真的很浪漫。


第一浴场的酒店看不到日落,于是就等太阳落下山以后拍了几张蓝调:


晚上,去吃了「前海沿」的海肠捞饭,其实吃不太出来海肠的味道,更多像是一种吃口感的东西,饭虽然很好吃,但是更多的味道来自于酱油、韭菜、肉沫。

第三天的天气和第一天如出一辙,都是雾霾阴天,并且已经有点疲惫了,前两天都是暴走模式,脚已经有点跟不上了,退完房以后背着书包从海之恋公园漫步到石老人浴场,走一会歇一会。
中午吃了「粥全粥到」的蛤蜊炒鸡和鲅鱼饺子,还可以吧,不过感觉不如黄焖鸡和金谷园的饺子。。


中午就已经抵达青岛站了,出来以后去了一个叫「团岛山」的公园,公园上开满了淡紫色的花,人特别特别少,即使离栈桥很近很近。
在这里坐了很久,感觉旅行的时候,我就喜欢挑这种清净小众的地方多停留一会,即使风景没有那么极致。

从山上下来以后又去了一趟栈桥,给我吓出密集恐惧症了。

前几天做攻略的时候看别人说,青岛是一个镶着金边的破抹布,感觉说的确实很有道理,虽然没怎么深度体验市内的人文,但是趁吃饭的时候去市北区转了转,感受是确实挺脏乱差的。
市南区的交通便利又混乱,地铁直通大多数地方,但是陆地上的机动车道大多是单行道,很堵,然后人行道上挤满了送外卖的电动车——因为并没有非机动车道。
和大连一样的,这里看不到共享单车,不过骑自行车的人还挺多的,没有特别起伏的地形。
总的来说,因为天气的原因,可能只体会到了 1 天完全体的青岛,但是能感受到这座城市对于旅游来说还是非常不错的,海岸线超级长,可以走好几天,也许会挑一个暖和一点的天气过来,感受一下崂山和黄岛区。
路线总结:
2025-06-10 08:50:32
🖼️ 多图
坐上 K684,开启去往大连的旅途。
这趟卧铺有很多好处:


酒店定在了中山广场,
早上 7 点到了酒店,直接就可以办入住了(赞一波亚朵)。
然后包放下以后就直接坐地铁来到了东港。




这一天还是端午节的最后一天,并且天气一般,预想到体验可能不会很好,不过实际逛下来还是比想象中的好不少。
几个景点的感受:
回酒店吃了一个午饭歇了一会,下午直接打车到海之韵公园继续漫步。


海之韵公园从北门进,上来就是一段超级大上坡,差点没给人累死,在大太阳下走了快半小时才到山顶,不过从山上眺望大海的感觉还蛮好的。


往山下走,为了看一个网红景点「圣象天门」跟着一群大胆的游客翻了好几个护栏和挡板,到了以后发现不过如此,一大群人排队围着一个山洞拍照,虽然到达这里花了很大一番功夫,但是真正到了之后,我也懒得挤过去凑热闹了。
可能每个人对于旅行的理解都不一样,不过我是不太喜欢到了一个地方,就要打卡那些「出片」的网红景点,反倒是喜欢钻入无人的犄角旮旯去探索一下。

一路上发现了好多可爱小猫,最喜欢的是这只大橘和这俩狸花:


出了海之韵公园南门,就一直沿着滨海东路走啊走啊,一个下午走了快 30km,4 万步。自己走路有一个好处就是不必迁就他人,遇到想走的路和想看的东西,就直接走就完事了。
大连是丘陵地带,海边没有沙滩,只有断崖和礁石滩,这边整个滨海东路都是断崖,也是一种独特的风格。
随处可见这样的告示:


途中遇到可以拐下去的地方,无一例外都选择了下去看看,遇到了很多惊喜的景点。
许多地方就是沿着断崖修建的小路或者房子,左边是树林,右边就是一望无际的大海。



第二天一早就打车来到了老虎滩-菱角湾。
假期过了,天气晴了,大海的颜色变成深邃的蓝,拍照非常好看。


大连的海边有非常多的本地钓鱼佬,都是轻装出行,一根钓竿一把小椅子,一坐就是大半天,给人一种非常 chill 的感觉。

一路上都是这种非常舒适的步行木栈道,基本覆盖了从海之韵公园出来一直到星海广场这一条几十公里长长的海岸线。

走到付家庄公园,远看是一个沙滩,近看原来是石子组成的。



快黄昏时走到了大连的标志性建筑「星海湾大桥」,这个 6.8km 的跨海大桥从各个角度看过去都很壮观。


日落时桥上还会亮起不同颜色的灯光,不过当时有点冷,就没在山顶逗留了,不然俯视角下的夜景应该会很好看。

体验了一下大连的有轨电车,由于是工作日车上没什么人,车晃悠的不行、叮铃哐啷的很有意思。

大连城市的街道两旁见不到任何共享单车,不过倒是有一些共享的电动车,可能是因为城市规划的原因(没有非机动车道),并且丘陵地带很多陡峭的上下坡,确实不太适合骑单车。

晚上 8 点来到南山街,没有想象中热闹的街景,只有节日过后人们正在收拾残局。
而且大连的风真的很大,即使在城区里也能吹的人头秃,于是匆匆离开。


写这篇 Blog 的时候这次旅行已经过去快 2 周了,不过一切景物还是历历在目。
旅行这种事情确实能极大的减缓时间流逝的感觉,让人重拾起一种控制时间与生活的信心。
滨海城市的旅行体验真的极好,有时间会再去威海、青岛这些地方看看。
很喜欢的一句话:
只有一个人旅行时,才听得到自己的声音。它会告诉你,这世界比自己想象中更宽阔。
2025-05-29 19:35:05
毕业答辩结束,又因为还需要等着提交材料没法长途跋涉,想着天津离北京这么近又还没去过,索性去看看。
5月末,白天的天津,炎热难耐,走在大街上,似乎不存在斑马线和行人红绿灯。
好多好多的单行道和狭窄街道。下火车出了地铁左转,因为没有人行道,只能在逆行穿过一股酒味的涵洞。

第一顿当然尝一下天津菜,没想到分量巨大无比,一盆炒鸡估计炒了不止一只鸡。
两个饭量还不错的人吃了一个小时,最后菜和没动一样。



晚上去天津站码头坐了海河游船,也是此次天津之行感觉最值回票价的体验。
出了天津站就是码头,长长的海河沿线几乎包含了所有天津有名的景点。
如果天津没有这条海河,也许我给的评价还不如我老家。
周围高楼林立,每个楼都闪着金光,有种轻奢感。



平平无奇的周内工作日,海河周围散步的人也是熙熙攘攘。
到了晚上 10 点多才逐渐安静下来,这时沿着河边散步几乎只剩下一个个卖酒的小摊贩。
心情还不错的时候,吹着晚风这么喝一杯还挺惬意。


白天走马观花的看了世纪钟广场、津湾广场、西开教堂、北安桥、意式风情街、瓷房子、五大道等等一系列建筑。
如果天气凉快一点,也许还有心情停下来欣赏一番,然而 30 度的艳阳天只能让我像特种兵打卡一样匆匆拍个照就走人。
体验一般,不过即使是凉快下来,感觉白天的天津相比晚上也差了不少意思。




下午的时候实在逛不下去了,干脆花 2 小时去听下相声。
直到开场的时候才陆续来了其他两桌人,不然直接包场了,那样还挺尬的。


第一次线下花这么长时间完整的听完一场相声,感觉还不错,主要空调还很凉快。
最后又在夜风中搭观光车溜达了一圈,感觉天津城区真的好小,已经有点腻了。

还是更喜欢山川湖海。
2025-04-21 22:45:28
注意,本文不是翻译,只是针对自己觉得有用的一些地方的记录和总结;对于我自己觉得已经比较清楚的概念,就完全没有记录。其中最后的「最佳实践 Best Practice」部分个人感觉比较有用,强烈建议结合原版 PDF 的一些示例 demo 进行对比查看。
简单介绍:
「Prompt Engineering」是 Google 推出的提示词工程白皮书,一共 60 多页,原始版本可以在 https://www.kaggle.com/whitepaper-prompt-engineering 上获取到,或者直接 下载链接 (googledrive)。

主要三个可配置项:
作用的先后顺序: Top-K -> Top-P -> Temperature
假设我们有以下设置:
当模型预测下一个词时,可能给出了这样的概率分布:
应用步骤:
几种极端情况的 LLM 实现考虑:
| Use Case | Temperature | Top-P | Top-K | Description |
|---|---|---|---|---|
| 通用场景 General Purpose | 0.2 | 0.95 | 30 | Relatively coherent results with some creativity |
| 高创造力场景 High Creativity | 0.9 | 0.99 | 40 | Especially creative results |
| 比较精确的场景 (比如coding) Low Creativity |
0.1 | 0.9 | 20 | Less creative results |
| Single Correct Answer | 0 | - | - | For tasks with only one correct answer (e.g., math problems) |
系统提示(System Prompting)、上下文提示(Contextual Prompting)和角色提示(Role Prompting)都是用于指导大型语言模型(LLMs)生成文本的技术,但它们关注的重点不同。尽管这些提示类型之间存在相当大的重叠(例如,一个提示可能同时为系统分配角色并提供上下文),但每种提示的主要目的略有不同。
以下是三种提示类型的核心区别和作用:
| 提示类型 | 主要目的与功能 | 特点与作用 |
|---|---|---|
| System Prompt | 定义模型的基本能力和总体目的。 | 设定语言模型的“大局观”,例如翻译语言、分类评论等,指导模型的整体行为。 |
| Contextual Prompt | 提供与当前对话或任务相关的具体细节或背景信息,指导模型生成针对性的回应。 | 高度特定于当前任务或输入,具有动态性,帮助模型理解细微差别并调整回应。 |
| Role Prompt | 为模型分配特定的角色或身份,帮助模型生成与该角色一致的回应。 | 塑造模型的输出风格和语气,增加具体性和个性,使回应符合角色的知识和行为。 |
1 |
|
1 |
|
1 |
|
在为AI模型创建提示时,提供示例非常有帮助。示例可以帮助模型理解您的需求,尤其是在希望模型输出特定结构或模式时特别有用。
Step-back prompting 是一种通过提示 LLM 先考虑与具体任务相关的一般性问题,然后将该问题的答案输入到后续的具体任务提示中来提升性能的技术。这种“step back”方法使 LLM 在尝试解决具体问题之前激活相关的背景知识和推理过程。通过考虑更广泛和基本的原则,LLM 能够生成更准确和有洞察力的回应。
Step-back prompting 鼓励 LLM 批判性思考并以新的和创造性的方式应用知识,通过利用 LLM 参数中的更多知识来改变执行任务的最终提示,而这些知识在直接提示 LLM 时可能不会被激活。它还可以通过关注一般原则而非具体细节来帮助减轻 LLM 回应中的偏见。
传统 prompt:
1 |
|
step-back prompt:
1 |
|
1 |
|
编写提示(prompt)可能是一项复杂的任务。为了解决这个问题,可以采用Automatic Prompt Engineering (APE)方法。这种方法不仅减少了人工输入的需求,还能提升模型在各种任务中的表现。你可以让模型生成更多提示,对它们进行评估,可能的话修改好的提示,然后重复这个过程。
case:
1 |
|
这节没什么特别出彩的,就是列举了几个 coding 的用法,不过可以参考一下 Gemini 在 coding 时是如何推荐配置 topk, topp 和 temperature 的
Temperature:0.1
Token Limit:1024
Top-K:N/A
Top-P:1
writing code
1 |
|
1 |
|
1 |
|
1 |
|
这个很有价值,一些很容易想到和验证的概念,但是 Google 帮你总结出来了
最重要的原则是在提示中提供示例(one shot/few shot)。这是高效的方法,因为它能作为强大的教学工具。这些示例展示了期望的输出或类似的响应,让模型从中学习并相应地调整其生成内容,提高准确性、风格和语调。
提示应该简洁、清晰,易于你和模型理解。如果对你来说已经令人困惑,对模型来说也可能令人困惑。尽量不要使用复杂的语言,不要提供不必要的信息。
示例改进:
1 |
|
尝试使用描述动作的动词,例如: Act, Analyze, Categorize, Classify, Contrast, Compare, Create, Describe, Define, Evaluate, Extract, Find, Generate, Identify, List, Measure, Organize, Parse, Pick, Predict, Provide, Rank, Recommend, Return, Retrieve, Rewrite, Select, Show, Sort, Summarize, Translate, Write.
要明确期望的输出内容。简洁的指令可能不足以引导LLM或过于笼统。在提示中提供具体细节(通过系统或上下文提示)可以帮助模型专注于相关内容,提高整体准确性。
推荐做法:
1 |
|
不推荐的做法:
1 |
|
研究表明,在提示中专注于积极指令比过度依赖约束更有效。这与人类偏好积极指令而非列出不应做的事项的方式一致。
指令直接传达期望的结果,而约束可能让模型猜测什么是允许的。指令在定义的边界内提供灵活性并鼓励创造力,而约束可能限制模型的潜力。此外,约束列表可能相互冲突。
约束在某些情况下仍然有价值,例如防止模型生成有害或有偏见的内容,或当需要严格的输出格式或风格时。
如果可能,使用积极指令:不要告诉模型不要做什么,而是告诉它应该做什么。这可以避免混淆并提高输出的准确性。
示例:
1 |
|
要控制生成的LLM响应的长度,你可以在配置中设置最大token限制,或在提示中明确要求特定长度。例如:
1 |
|
在提示中使用变量,可以针对不同输入而改变。例如,提供关于城市的事实的提示。与其在提示中硬编码城市名称,不如使用变量。变量可以通过避免重复自己来节省时间和精力。如果需要在多个提示中使用相同的信息,可以将其存储在变量中,然后在每个提示中引用该变量。在将提示集成到自己的应用程序中时,这非常有意义。
示例:
1 |
|
不同的模型、模型配置、提示格式、词汇选择和提交方式可能产生不同的结果。因此,实验提示属性如风格、词汇选择和提示类型(零样本、少样本、系统提示)很重要。
例如,对于一个目标是 “生成关于革命性视频游戏机Sega Dreamcast的文本” 的 Prompt,其可以表述为问题、陈述或指令,产生不同的输出:
一般来说,few-shot (少样本)示例的顺序不太重要。然而,在进行分类任务时,确保在few-shot示例中混合可能的响应类别。这是因为否则你可能会过度拟合到示例的特定顺序。通过混合可能的响应类别,你可以确保模型正在学习识别每个类别的关键特征,而不是简单地记住示例的顺序。这将导致在未见数据上更强健和可泛化的性能。
一个好的经验法则是从6个few-shot 示例开始,并从那里开始测试准确性。
跟踪模型架构变化、添加的数据和功能很重要。尝试更新的模型版本,并调整提示以更好地利用新的模型特性。
例如,对于非创造性任务,如提取、选择、解析、排序、排名或分类数据,尝试让输出以结构化格式如JSON或XML返回。
从提取数据的提示中返回JSON对象有一些好处。在真实应用中,我不需要手动创建JSON格式,可以直接以排序顺序返回数据(处理日期时间对象时非常方便),但最重要的是,通过提示要求JSON格式,它迫使模型创建结构并限制产生幻觉。
使用JSON输出的好处总结:
对于CoT Prompt,将答案放在推理之后是必需的,因为推理的生成会改变模型在预测最终答案时获得的tokens。
使用CoT和自我一致性时,你需要能够从提示中提取最终答案,与推理分开。
对于CoT Prompt,将temperature设置为0。
思维链提示基于贪婪解码,根据语言模型分配的最高概率预测序列中的下一个词。一般来说,使用推理来得出最终答案时,可能只有一个正确答案。因此,temperature始终应设置为0。
前面已经提到过,但我们再次强调:详细记录你的提示尝试,这样你可以随时了解哪些方法行之有效,哪些不行。
提示输出可能在不同模型、不同采样设置,甚至同一模型的不同版本之间有所不同。此外,即使对同一模型的相同提示,输出句子格式和词汇选择也可能存在细微差异。(例如,如前所述,如果两个tokens具有相同的预测概率,则可能随机打破平局。这可能影响后续预测的tokens。)
建议创建一个Google表格,使用模板记录:
还建议跟踪提示的版本(迭代),记录结果是否OK/NOT OK/SOMETIMES OK,以及反馈。如果有幸使用Vertex AI Studio,保存提示(使用与文档中相同的名称和版本),并在表格中跟踪保存的提示超链接。这样,你只需一次点击就可以重新运行提示。
在使用检索增强生成系统时,还应捕获影响插入到提示中的内容的RAG系统的特定方面,包括查询、块设置、块输出和其他信息。
一旦你觉得提示接近完美,将其带入项目代码库。在代码库中,将提示保存在与代码分开的文件中,这样更容易维护。最后,理想情况下,你的提示是一个可操作系统的一部分,作为提示工程师,你应该依靠自动化测试和评估程序来了解你的提示如何针对任务泛化。
提示工程是一个迭代过程。制作并测试不同的提示,分析并记录结果。根据模型的表现改进你的提示。继续实验直到达到期望的输出。当更改模型或模型配置时,回去继续实验先前使用的提示。
2025-03-02 17:08:43
最近在看 vllm 的代码,cpu offloading 这部分它的实现还是比较简单的,这里简单记录一下。
由于大模型的参数量实在很大,所以如果想在单机上运行一般都需要跑量化蒸馏后的模型,但是有时又不想牺牲模型质量,于是CPU/SSD 卸载成为一种折衷方案,通过增加推理时间来降低内存需求。
vllm 也实现了一个简单的 cpu offload 的机制,可以通过 --cpu-offload-gb 启用。
这里发现他的实现还是比较简单的,主要就是通过这个 PR ,添加了一个 func 叫 maybe_offload_to_gpu:
1 |
|
这个函数只有一个地方调用了:
1 |
|
cpu offload 的整个流程可以概括为:
cpu_offload_gb 读取为 _CPU_OFFLOAD_MAX_BYTES。_CPU_OFFLOAD_BYTES += p.data.numel() * p.data.element_size(), 即参数数量 x 字节大小) 到 _CPU_OFFLOAD_BYTES,直到超过用户配置的可 offload 大小。forward 函数,新的 forward 函数和原来的区别就是:在每次 forward 的时候,将 CPU 上的参数复制到 GPU 上,计算完后再释放
1 |
|
这里的 forward 替换设计挺有意思:
(original_forward = module.forward):保存模块原始的前向传播函数到变量 original_forward,为后续恢复原始实现做准备。
(在 forward 函数内的 module.forward = original_forward):在自定义的 forward 函数内部首行,当函数被调用时,立即将模块的前向传播方法恢复为原始方法。这一步确保 functional_call 能够使用原始的前向传播逻辑,避免递归调用。
(在 forward 函数内末尾的 module.forward = forward):前向传播完成后,再次将模块的前向传播方法设置回自定义的 forward 函数,确保下次调用时仍能触发这个包含参数加载逻辑的自定义函数。
(函数末尾的 module.forward = forward):为了确保每次都能 hook 到 cpu -> gpu 这部分的逻辑 (参考原 PR 的解释:https://github.com/vllm-project/vllm/pull/6496/files#r1682069375)
这里的核心是使用 functional_call 配合临时的 device_state,实现参数从 CPU 到 GPU 的动态加载。初看可能会疑惑为什么没有将参数从 GPU 释放回 CPU 的逻辑,其实这是因为 device_state 是个局部变量,函数执行完毕后其引用的 GPU 张量会自动被 Python 的垃圾回收机制释放。而原始参数依然保存在 CPU 内存中,从而实现了内存优化的目的。
同时还有一个小知识点:
nn.Module, .cuda(), .cpu() 和 .to(device) 方法都是就地操作,因此可以直接 model.cuda()
torch.Tensor , nn.Parameter 这些,.to(device), .cpu(), .gpu() 方法本质都是创建一个新的 Tensor,原始 Tensor 不变,因此也必须使用 a = b.cuda()
2025-01-30 18:31:18
在试用了一众 “稍后读” 和 “剪藏” 软件后, 仍然找不到满意的软件。
总结了一下针对当前的「网页剪藏」软件,现在自己不满意的几个点:
1 - 快照使用「服务器采集」: cubox, pocket 等
这种方式的缺点就在于,很多内容平台,特别是国内的平台,都需要登录才能访问完整内容。
那么这样的采集方式受限就很大,服务器端采集无法携带用户的认证信息,因此往往只能获取到部分内容或者直接无法访问。
2 - 自带的「网页解析」或者「解析为 Markdown」: obsidian / upnote 等笔记软件的 clipper
网页结构和样式的多样性使得通用解析器很难完美处理所有情况,特别是对于代码块、表格、数学公式等特殊格式,解析质量往往不尽如人意。
3 - 仅能保存 URL 的「稍后读」: raindrop 等
内容的持久性在互联网上并不能得到保证,特别是:
对于一些时刻可能下架的敏感内容,或者经常变动的网站,url 可能过一阵子就看不了了。
于是我搭建了一个联动 SingleFile, dropbox, notion, 和 telegram bot 的 workflow 来满足我的需求。
之所以说是工作流 Workflow,实际上就是将一大堆 API 串起来。
整体实现起来不难,把所有 API 写好,作为一个 notepad 喂给 cursor,基本上 10 分钟就完成了,然后接下来用了几个小时来完善整个流程。
以下是 Demo (youtube):
PS:demo 实际展示了 Telegram 的提示过程 + 服务端日志,实际上对于我而言只需要按一下「
cmd + shift + s」 快捷键之后,剩下的一切都是服务端处理了。PPS:演示的时候 DeepSeek 又卡了,还好加了一个备用的 API。。
简单来说这个工作流如下:
总体来说个人还是挺满意的,最近搞了不少自动化,这个算是折腾比较久的和比较好玩的,于是写出来分享下。