返回站点目录

范叶亮的博客

https://leovan.me/cn/

该站点暂未提供站点简介,可继续查看文章聚合、状态检测与相关资源入口。

综合

状态

状态正常

确定性和掌控欲

2026/05/23 00:00 · 中文博客 on 范叶亮 | Leo Van

最近观察自己和团队在使用 AI 上遇到了一些情况,比如生成的东西(代码、报告、网页等)“虾”味儿比较重,交付质量上也良莠不齐(准确性和深度等方面)。甚至在一些没有必要的场景(至少我认为没有必要)非要把 AI 用上,我想 FOMO 和组织压力是两个重要的“罪魁祸首”。彼时大家考虑更多的是如何“用上” AI,而不是如何“用好” AI。以任何一个角度去切入去尝试 AI 都是对的,欠妥的是当遇到“为什么一会儿行一会不行”,“为什么他那行我这不行”的时候,又会去质疑 AI 不行而不是自己用得不好。 思辨的意义在于过程中的反复,而不是最后的 。在评判 AI 是否应该介入一个工作的时候我会关注两个点: ROI:一切抛开成本的使用都是耍流氓。典型的例子就是一个事儿一年都干不了几次,不确定性还很高,想要 AI 帮你一步到位纯纯就是幻想(至少现在是)。 角色:它在这件事儿中扮演什么样的角色。以画图为例(这里说的是思维导图、架构图之类,而非数据图),我可以和 AI 探讨思路,然后把结果按照想要的样子放上去。而不是一句话:帮我把 XXX 画一个架构图出来。图的意义从来不是这张图本身,而是拼拼凑凑形成过程中的思考,当你想一句话画出来的时候,你不想干的一定不是“画”而是“思考”。 一篇 让“技术平权”再次沸腾,但我希望在团队拥抱 AI 的过程中成为一个仁慈的独裁者 ,确定性和掌控欲不是阻碍 AI 落地的绊脚石,当个“甩手掌柜”才是加速被淘汰的慢性毒药。 技术视角 在之前的 中提过 LLM 本身是一个无状态的服务,你给他什么样的输入,它就会预测什么样的输出。产生不确定性的核心在于当今 AI 的背后是一个概率预测模型: 图片来源: 排除网络架构的不同 ,即使最朴素的全连接神经网络,在给到足够的训练数据时,其仍可以拟合任意函数: 图片来源: 在以 Transformer 为基础的 LLM 中,还有着多个用于控制模型输出不确定性的参数。 参数 图示 描述 最大 Token 数 控制生成的最大 Token 数, 取值范围 $\left[1, \infty\right]$ 温度 控制模型输出的随机性,值越大越随机, 取值范围 $\left[0, 2\right]$ $\text{Top}_p$ 控制 Token 采样时的累计概率, 取值范围 $\left[0, 1\right]$ $\text{Top}_k$ 控制 Token 采样时当候选数量, 取值范围 $\left[1, \infty\right]$ 频率惩罚 减少重复内容的生成,正值减少重复 取值范围 $\left[-2, 2\right]$ 存在惩罚 鼓励生成新的内容,正值鼓励新内容 取值范围 $\left[-2, 2\right]$ 停止词 自定义的停止词列表 通过调整如上参数,你可以一定程度上控制 AI 输出的不确定性,当写代码时可以让其更确定些,当做内容创作时可以让其更随机些。用好 AI,而不是当 AI 彻底放飞自我的时候只会吐槽它又变“傻”了。Harness Engineering 也在尝试从应用层解决产出可靠性的问题。 图片作者: 在写 Skill 的时候,根据 , SKILL.md 文件应该在 500 行以下,更详细的参考资料应该转移到单独的文件中去。确定性的事情应该放在 scripts 中用代码实现,当下用 AI 写 Skill 的时候虽然它知道利用脚本实现一些确定性的事情,但脚本自身是否正确是否鲁棒你心里还需有个谱。知其然,知其所以然,AI 时代没有要求大家都需要搞明白模型中的各种数学公式,但用好 AI 的人也绝不仅限于知道几个 AI 名词而已。 管理视角 现在面向代码春暖花开的我曾经学了 7 年的管理,记得管理学老师开堂的第一句话是:管理学既是一门科学,又是一门艺术。科学性在于我们有经典的 和 ,艺术性在于人与社会的复杂和管理实践中“度”的拿捏,例如放权。网上有这样一篇文章: 。我个人的观点是五五开,当前技术发展之迅猛前所未有,不懂代码就不会陷入固有的行为模式中去,确实更容易拥抱变化,但控制欲强并不代表不放权,随着 ,放权的艺术也需要与时俱进。 文章中提到“以结果为导向”,这点我很赞同,商业体系中生存之本就是拿结果。“拿结果”这三个字说起来容易,但拿什么、怎么拿、谁来拿这都是问题。组织的层级设置,从战略到战术的层层拆解,这些都是复杂的工程。以一线管理者为例(我理解和当前大家使用和管理自己的智能体场景类似),如果你只一味的抓结果不抓过程,那么等 Deadline 到了却没有合格的产出时,一切终究都是徒劳。因为这里的结果不是你三两句指令做出来的 MVP,而是需要在线上稳定高效运行的系统。 最近出差在飞机上听了《面基》播客中一期: ,里面提到在 AI Coding 的当下人人都可以在自己的电脑上手搓“小板凳”,那在这样的时代如何定义“好”呢?“小板凳”说的是很多人在家做小板凳,但客户真正需要的是沙发。也就是说你费劲做出来的那点东西,离真正被市场需要、愿意付钱的成熟产品,往往还差得很远。但为什么明明很多人知道自己做的就是小板凳,却还是忍不住一张接一张地做呢?原因可能会有很多:一条新赛道的好奇感,一个新时代的压迫感,抑或是?做小板凳本身并没有什么不好,板凳和沙发之间也不是说相差十万八千里,做沙发的老师傅也是从做小板凳开始的。我希望团队里的人可以在做完十个小板凳之后去尝试做一个沙发,或者停下来了解下更底层的榫卯结构。 战略的制定者一定是从战术的执行者到战术的制定者再一步一步走过来的,掌控欲并非是要事必躬亲(Sometimes maybe),而是需要了解更多可以支持战略制定的信息。战略性的失误会比战术性的失误可怕的多,如果可以我也想对 AI 说你自己看着办吧,然后我就在旁悠闲的喝茶,甚至连监督都不想做。在此推荐一下宝玉的一篇文章: ,权当是一个新的视角,任凭弱水三千,我只取一瓢饮。 伦理视角 我个人现在从事安全相关工作,日常处理的工作内容中包括很多“坏”事儿,这里的“坏”并不是代表我要去做坏事,而是事情的背景中充斥的一些敏感的内容。基于这种情况,在我使用 AI 的过程中会存在两类问题: AI 触发审查机制,尽管我的要求合法合规,但由于给定的上下文背景中存在敏感信息,AI 最终会拒绝我的要求。 AI 在授权的场景下,为了实现要求会“不择手段”的尝试尽可能多的路径,但对于路径在物理世界的风险评估不够,有时会造成一些不好的结果。例如:因为现有系统存在 BUG,AI 执行了本不该执行的操作,最后导致原有系统发生崩溃。这锅你说是让 AI 背,还是你来背,还是现有系统背,还是各打五十大板? 两个问题存在一定的冲突,有时候我们需要更多的“自由”,有时候我们又不太想让它太过“自由”。这里我们有很多的技术方式可以去尝试解决,但除此之外我们更需要从伦理视角去重新审视 AI 之于我们的关系。 摆正思想,善(善良)用 AI :不为恶(Don’t be Evil)是 Google 提出的企业座右铭,真的很难做到,但我们又必须去做。我的底线可以低些,但不能没有。 摆正角色,善(善于)用 AI :当下我们需要为 AI 犯下的错误承当全部责任,不要以为你说的三两句指令无关痛痒,一切的后果及其引发的一连串问题你都难以想象。 你的 AI 不是你的 AI,这里回应多年前看的一部剧 ,对于 AI 的培养可以像培养孩子一样,两者是有很多共通之处的。 卷积神经网络,CNN: 循环神经网络,RNN:

LLM Token 消耗节省计划

2026/04/25 00:00 · 中文博客 on 范叶亮 | Leo Van

模型价格 我在之前的文章「 」中曾抛出过一个问题:如果由你自己承担龙虾的费用,你是否还会像当前这样使用龙虾?虽然之前的文章「 」介绍了如何通过本地部署实现 Token 自由,但想要你的智能体更聪明,往往还是需要一个参数规模远超你本地机器所能承受的模型才更靠谱些。当然也可以祭出你的多卡服务器,但无论以何种方式实现 Token 自由,终究都不免落入 ROI 计算的俗套,因为这背后的背后都是实打实的真金白银。统计了当前流行的部分国内外模型的价格,如下表所示: 模型 发布日期 参数 上下文长度 能力 输入价格 输出价格 缓存命中价格 Claude Opus 4.6 2026-02 未知 1M \$5 \$25 \$0.5 GPT-5.4 2026-03 未知 1.05M ≤272K \$2.5 >272K \$5 ≤272K \$15 >272K \$22.5 ≤272K \$0.25 >272K \$0.5 Grok 4.20 2026-03 未知 2M ≤200K \$2 >200K \$4 ≤200K \$6 >200K \$12 ≤200K \$0.2 >200K \$0.4 Gemma 4 31B 2026-04 31B 262.1K \$0.14 \$0.4 \$0.07 Gemma 4 26B A4B 2026-04 26B 262.1K \$0.13 \$0.4 \$0.05 Kimi K2.5 2026-02 1000B 262.1K \$0.6 \$3 \$0.1 MiniMax M2.7 2026-03 230B 204.8K \$0.3 \$1.2 \$0.06 GLM 5 Turbo 2026-04 744B 202.8K \$1.2 \$4 \$0.24 Qwen 3.5 27B 2026-02 27B 262.1K \$0.3 \$2.4 \$0.15 Qwen 3.5 35B A3B 2026-02 35B 262.1K \$0.25 \$2 \$0.12 上述模型在 OpenClaw 上的成功率和输入价格对比图如下所示: 大小表示模型参数规模(对数处理) 参考: 模型成功率 v.s. 输入价格 从上述图表中不难看出:模型越大、能力越丰富、支持的上下文越长价格也就越贵。同时部分模型针对超长的输入输出还会加价计费,这是因为随着输入输出的增加,模型的计算量并不是以线性的方式增长的,而是指数增长。 费用构成 那么除了选择一个高性价比的模型之外,可还有其他的省钱之道?接下来我们来聊聊你的钱都花在了哪些地方,从定价表来看包括三个部分: 输入 、 输出 和 缓存命中 ,为了更好的理解三者价格的差异,我们需要先回答如下两个问题。 为什么输出比输入要贵? 大模型的推理分为两个阶段:预填充(Prefill)和解码(Decode),过程如下图所示: 模型在获取到用户的提示词后,会将提示词中的所有 Token 一次性读入到模型中,这个阶段是高度并行的。例如当提示词中包含 100 个 Token 时,模型可以同时处理这 100 个 Token,GPU 最擅长的就是此类并行计算。此时 GPU 的利用率很高,因此分摊到每个 Token 上的成本就比较小。 预填充结束后模型开始输出,输出的 Token 只能一个一个的计算。这是因为每生成一个 Token,模型都需要将其拼接到之前的序列中,用作输入来生成下一个 Token。这是自回归解码模型的运行原理,无法并行,此时 GPU 的利用率较低,性能瓶颈在于显存中的数据传输而非计算。假设模型的参数量为 $P$,提示词的 Token 长度为 $M$,已经输出的 Token 长度为 $n$,那么在计算输出第 $n + 1$ 个 Token 时,模型的计算量为 $\left(M + n\right) \times P$。假设输出的 Token 总长度为 $N$,则总计算量为 $\sum_{i=1}^{N} \left(M + i\right) \times P$。可以看出,计算量和 Token 输出数量之间并非线性关系,这就是为什么有些模型针对超长的输出会加价计费。 什么是缓存命中? 模型的输入除了用户的提示词以外,往往还会包含系统提示词等内容,这部分在每次模型运行的过程中都是相同的。通过提示词缓存技术可以将这段前缀提示词计算的结果保存在高速缓存中,在下次预填充的时候,如果前缀一样则直接可以把这部分结果从高速缓存中读取出来,而不需要重复计算。此时的成本仅包含缓存的存储和加载开销,对 GPU 算力几乎没有占用,因此这部分价格会很低。 需要注意的是,缓存是前缀匹配的,哪怕修改了一个字,后面的部分也都需要重新计算。缓存通常具有一定的有效期,一般几分钟到几小时就会失效。智能体往往会将系统提示词等不变的内容放在前面,将用户提示词等变化的内容放在后面,从而提升缓存命中率。 节省计划 你需要知道 LLM 本身是一个无状态的服务,也就是说当模型确定后,你给它什么样的输入,它就针对性地给到你什么样的输出。当你在和智能体对话的时候,每一次智能体接收的输入并不仅仅是你这轮与其对话的内容,而是整个会话中的全部。 所以想要节省 Token,核心就是做好上下文管理,管得太紧(缺少必要的信息)效果就会大打折扣,管得太松(无用的信息太多)不单单是费钱效果也可能会受到影响。结合上下文管理,如下给到不同视角的一些节省 Token 的技巧和建议: 记忆管理 OpenClaw 采用 Markdown 文件的方式 。除了定期和手动( /compact )的记忆压缩外,最新版本的 OpenClaw 还 了 记忆引擎。个人理解 QMD 本质上属于 RAG,通过 QMD 可以将相关的记忆放入上下文,而非全部,此时此刻 和 RAG 不就又胜利会师了吗。 平台已经把心替你操了,你无须再做什么操作 🥳 明确需求 写 Prompt 和沟通一样,是一门艺术。有些场景需要模糊些,例如探索性分析,模型可能会给到你意想不到的结果。但当需求明确的时候,准确的需求描述可以让智能体少很多弯路。需求一次性说完整,比一轮一轮的挤牙膏式会少消耗不少 Token。 别学某些芯片厂,总是挤牙膏 😂 控制输出 输出比输入贵上个 5-10 倍,告诉 AI 你要什么,不要让它自由发挥。以及最后那一句“我真的太棒了!”的情绪价值属实大可不必。❌:帮我分析一下这篇文章。✅:分析一下这篇文章,用一百个字总结核心内容。 严重怀疑服务商在 LLM 里写死了一条指令:多说些,我好多赚点儿 🤑 以上是几点通用的技巧和建议。在更多细分的场景(例如:编码)会有更多的实用技巧,在此不再一一展开,可以参考如下文章:

智能体的角色定位和身份演化

2026/04/19 00:00 · 中文博客 on 范叶亮 | Leo Van

随着 OpenClaw 的爆火,智能体(Agent)一词已经成了大家每天都挂在嘴边儿上的话。从“智能体”成为 2025 年度科技热词以来,说这个词被滥用或许略显激进,但当一个词进入寻常百姓家时,或许我们应该重新审视一下到底什么是智能体,这个硅基生物之于我们碳基生物又是什么角色,“它”又是如何在改变着我们的生活呢? 智能体 我搜集了互联网上对于智能体的定义: 智能体(Agent) 智能体指一个可以观察周遭环境并作出行动以达到目标并且可以通过机器学习以及获取知识来提升自身性能的自主实体。 —— 维基百科 智能体是一种接收输入、解读输入,然后代表用户(无论是人类还是其他智能体)规划和执行操作的系统。 —— web.dev AI 智能体是使用 AI 来实现目标并代表用户完成任务的软件系统。其表现出了推理、规划和记忆能力,并且具有一定的自主性,能够自主学习、适应和做出决定。 —— Google Cloud 智能体是一个系统,它利用人工智能模型与环境交互,以实现用户定义的目标。它结合推理、规划和动作执行(通常通过外部工具)来完成任务。 —— Hugging Face 如 ReAct 框架 所述,智能体的主要特点如下: 推理 :此核心认知过程涉及使用逻辑和可用信息来得出结论、进行推断及解决问题。具有强大推理能力的 AI 智能体可以分析数据、识别模式,并根据证据和上下文做出明智的决策。 行动 :根据决策、计划或外部输入采取行动或执行任务的能力对于 AI 智能体与其环境进行互动和实现目标至关重要。这可能包括具身 AI 的物理动作,或发送消息、更新数据或触发其他流程等数字操作。 观察 :通过感知或感应收集有关环境或情况的信息,对于 AI 智能体了解上下文并做出明智的决策至关重要。这可能涉及多种感知形式,例如计算机视觉、自然语言处理或传感器数据分析。 规划 :制定战略计划以实现目标,是智能行为的一个关键方面。具有规划能力的 AI 智能体可以确定必要的步骤、评估潜在行动,并根据可用信息和预期结果选择最佳行动方案。这通常需要预见未来的状态,并考量可能遇到的障碍。 协作 :在复杂且动态的环境中,与他人(无论是人类还是其他 AI 智能体)有效协作来实现共同目标变得越来越重要。协作离不开沟通、协调,以及理解并尊重他人观点的能力。 自我完善 :自我改进和自适应能力是高级 AI 系统的标志。具有自我完善能力的 AI 智能体可以从经验中学习,根据反馈调整行为,并随着时间的推移不断提升性能和能力。这可能涉及机器学习技术、优化算法或其他形式的自行修改。 角色定位 以 OpenClaw 为例的智能体,其能力足够丰富,在企业实践中不同场景需要不同类型的智能体以便更好(例如:更快速、更安全等)地服务其目标客户。从业务视角出发在此将智能体划分为个人助理、数字员工和数字分身三类,这三类的差异对比如下: 角色 个人助理 数字员工 数字分身 服务对象 个人 他人 个人 所有权 个人 多种 个人 身份 智能体自己 智能体自己 所有权人 定位 帮助所有权人处理个人需求 帮助所有权人处理他人需求 帮助所有权人以所有权人身份处理需求 示例 帮自己搜集信息 帮服务对象查询天气 帮自己去参加在线会议 结合 OpenClaw 的定义(OpenClaw is a self-hosted gateway …, and it becomes the bridge between your messaging apps and an always-available AI assistant . ),其更符合 个人助理 的角色定位。数字分身相比另外两个角色最大的特点是其身份代表的是所有权人,除了技术实现难度外,更重要的是伦理问题。当数字员工出现问题时,是应该所有权人为其负责还是技术服务提供者为其负责呢?这个问题类似智能驾驶,当出现交通事故时,是应该由驾驶员承担责任还是自动驾驶服务提供商承担责任呢?目前来看,几乎全部责任仍是由驾驶人员承担。 从技术视角出发,个人助理和数字员工两个重要角色差异对比如下: 角色 个人助理 数字员工 知识 私有 + 共有 共有 + 权限管控 数据 私有 + 共有 共有 + 权限管控 技能 私有 + 共有 共有 + 权限管控 渠道 私有 共有 + 权限管控 定制化 程度高 程度低 核心目的 节省自己的资源(时间等) 节省组织的资源(人力等) 不难看出,个人助理和数字员工的一个核心差异在于 权限 。个人助理的权限管控并不在智能体内部实现,也就是说当你有某个权限的时候,只要你想个人助理就可以有,权限的边界在智能体之外。但数字员工的权限管控需要在智能体内部实现,数字员工使用同一个渠道对外提供服务,我们必须根据服务对象的不同采取不同的操作。个人助理是可以高度化定制的,只要你想怎么搞都是你自己的事。但数字员工受限就会很多,因为要面向多人服务,我们需要考虑响应的时效性、服务的稳定性、数据的安全性等等。 个人助理解决的是个人的长尾事务,只有将自己从重复繁琐的任务解放出来,我们才能够有更多的时间去思考更重要的事情。而数字员工解决更多的是通用类型的事务,这样才能够服务更多的用户,从而提高组织效能。 身份演化 其实我们也无需将个人助理和数字员工割裂来看,在个人助理上做一些适当的加减法就可以让其变成数字员工,同时数字员工之于个人助理也可以看作是一项技能而为其所用。我个人认为从个人助理进化到数字员工是一个 先做减法再做加法 的过程。 当前的个人助理已经是一个可以高度定制同时具有一定自主能力的智能体。在企业应用过程中,基于安全等因素的考虑我们必须在一定程度上限制其灵活性,才能够一方面高效的满足用户需求另一方面避免其成为一匹脱缰的野马。换句话说就是从个人助理的 执行优先 转变到数字员工的 治理优先 。这里感觉和当下的 Harness Engineering 有些许呼应,Harness 给到了系统运转的最佳范式,但同时也指定了相应的约束机制。约束的方式(代码层、Prompt 层、Skill 层)和约束的强度影响着任务执行的灵活程度。 图片来源: 正如员工在进入组织前期,他首先要学习的就是组织的规章制度,什么可以做,什么不可以做。当员工对组织的要求清晰之后,才会被允许从事更加复杂的工作,才会被赋予更多的自主权。在这个过程中组织仍会定期观测,同时对必要的问题做出反馈并要求员工进行修正。在此也收集了智能体 、数字员工 和自动驾驶 的分级对比: 级别 自动驾驶 智能体 数字员工 L1 辅助驾驶 车辆对方向盘和加减速中的一项操作提供驾驶,人类驾驶员负责其余的驾驶动作。 规则符号智能 意图 + 行动 功能级-辅助工具 作为工具被调用,人类执行并闭环任务。 L2 部分自动驾驶 车辆对方向盘和加减速中的多项操作提供驾驶,人类驾驶员负责其余的驾驶动作。 推理决策智能 意图 + 行动 + 推理和决策 任务级-任务执行 执行被分解的任务,人类拆解分配任务。 L3 条件自动驾驶 由车辆完成绝大部分驾驶操作,人类驾驶员需保持注意力集中以备不时之需。 记忆反思智能 意图 + 行动 + 推理和决策 + 记忆和反思 协作级-协作自治 自主拆解及分配任务、闭环执行,人和数字员工协作,人类监督。 L4 高度自动驾驶 由车辆完成所有驾驶操作,人类驾驶员无需保持注意力集中,但限定道路和环境条件。 自主学习智能 意图 + 行动 + 推理和决策 + 记忆和反思 + 自主学习 + 泛化 指导级-专业指导 提供达到人类专家水平的定制化服务,人类参与。 L5 完全自动驾驶 由车辆完成所有驾驶操作,人类驾驶员无需保持注意力集中。 个性群体智能 意图 + 行动 + 推理和决策 + 记忆和反思 + 自主学习 + 泛化 + 人格 + 协作 智慧级-自主智慧 超越人类专家水平的能力,全面自主,人类授权。 我认为我们目前正处于 L3 至 L4 之间的一个地带,我相信在不久的将来我们可以突破 L4 迈入 L5。我希望 AI 会一直是为人所用,而不希望如 所描述的人类成为 AI 的奴隶。引用一下 的 ,希望在生产力高速发展的同时我们也可以更多的关注一下 AI 可能引起的一系列社会和伦理问题。 机器人三定律 机器人不得伤害人类,或坐视人类受到伤害。 除非违背第一法则,机器人必须服从人类的命令。 在不违背第一及第二法则下,机器人必须保护自己。 Yao, Shunyu, et al. “React: Synergizing reasoning and acting in language models.” The eleventh international conference on learning representations. 2022. 在企业中往往所有权归属于一个组织而非个人。

本地部署智能体

2026/04/18 00:00 · 中文博客 on 范叶亮 | Leo Van

环境信息 本教程将介绍在 macOS 环境下部署 OpenClaw,QwenPaw 和 Hermes Agent。如无特殊说明,macOS 系统下需在终端中执行命令,Windows 系统下需要在 PowerShell 中执行命令。本教程涉及到的软件信息如下: 软件 版本 Podman 5.8.2 OpenClaw 2026.4.16 QwenPaw 1.1.2 Hermes Agent 0.10.0 虚拟环境 为了更好的进行环境隔离,后续我们使用 Podman 安装不同的智能体框架。 提示 在 Windows 系统下,单击开始按钮,搜索 启用或关闭 Windows 功能 ,在打开的窗口中将 Hyper-V 和 适用于 Linux 的 Windows 子系统 及其子项全部勾选,单击确定,待系统启用功能后重启电脑。 运行如下命令安装 Podman: macOS brew install podman brew 安装请参见: Windows scoop install podman scoop 安装请参见: 为了方便观察 Podman 的运行情况,可选的运行如下命令安装 Podman Desktop: macOS brew install podman-desktop Windows scoop install podman-desktop 安装完毕后,运行如下命令初始化并启动 Podman: macOS podman machine init podman machine start Windows podman machine init podman machine start 运行如下命令查看 Podman 的安装和运行情况: macOS podman info Windows podman info 更多 Podman 使用方法请参考 。有关 Podman Desktop 的使用方法请参考 。 OpenClaw 安装 克隆 OpenClaw 的源代码至本地: macOS git clone git@github.com:openclaw/openclaw.git Windows git clone git @github . com : openclaw / openclaw . git macOS 运行如下命令安装 OpenClaw CLI: curl -fsSL https://openclaw.ai/install-cli.sh | bash 命令会在 ~/.openclaw 目录下安装 Node 环境和相关依赖。进入 OpenClaw 源代码目录下,运行如下命令构建 Gateway 容器: export OPENCLAW_DOCKER_APT_PACKAGES = "chromium" ./scripts/podman/setup.sh 其中 OPENCLAW_DOCKER_APT_PACKAGES 表示构建 Gateway 容器时使用 apt 命令额外安装的软件包。运行如下命令启动 Gateway 容器: ./scripts/run-openclaw-podman.sh launch 运行如下命令进行配置: ./scripts/run-openclaw-podman.sh launch setup 在配置过程中根据实际情况对模型提供商等选项进行配置。配置如下环境变量来使用宿主机中的 OpenClaw CLI 管理 OpenClaw 容器: export PATH = " $PATH :/Users/leo/.openclaw/bin" export OPENCLAW_CONTAINER = openclaw Windows 在合适的目录创建如下文件夹: mkdir / path / to / openclaw mkdir / path / to / openclaw / workspace 进入 OpenClaw 源代码目录下,运行如下命令构建 Gateway 容器: podman build -t openclaw : local -f Dockerfile . - -build-arg OPENCLAW_DOCKER_APT_PACKAGES = "chromium" 其中 OPENCLAW_DOCKER_APT_PACKAGES 表示构建 Gateway 容器时使用 apt 命令额外安装的软件包。运行如下命令配置并启动 Gateway 容器: $env:OPENCLAW_CONFIG_DIR = "/path/to/openclaw" $env:OPENCLAW_WORKSPACE_DIR = "/path/to/openclaw/workspace" podman compose run - -rm - -no-deps - -entrypoint node openclaw-gateway ` dist / index . js onboard - -mode local - -no-install-daemon podman compose run - -rm - -no-deps - -entrypoint node openclaw-gateway ` dist / index . js config set - -batch-json '[{"path":"gateway.mode","value":"local"},{"path":"gateway.bind","value":"lan"},{"path":"gateway.controlUi.allowedOrigins","value":["http://localhost:18789","http://127.0.0.1:18789"]}]' podman compose up -d openclaw-gateway 在配置中过程中根据实际情况对模型提供商等选项进行配置。 使用 Podman 安装 OpenClaw 后,重启 Gateway 的命令如下: macOS podman restart openclaw Windows podman restart openclaw-openclaw -gateway - 1 使用浏览器打开 即可进入 OpenClaw 管理页面。更多细节请参考 。 警告 OpenClaw 管理页面虽然支持权限校验,但为了安全起见,请勿将其暴露在公网。 消息频道 提示 在 Windows 系统下, podman compose 命令需要在 OpenClaw 源代码目录下运行。 飞书 运行如下命令配置飞书消息频道: macOS openclaw channels login --channel feishu Windows podman compose exec openclaw-gateway node dist / index . js channels login - -channel feishu 使用飞书 APP 扫描生成的二维码进行后续配置即可。 Discord 首先在 Discord 中创建一个服务器,进入 ,单击 按钮创建新的应用,并填写应用名称。 进入 概况 - 机器人 选项卡,启用 Presence Intent , Server Members Intent 和 Message Content Intent 。 进入 概况 - 机器人 选项卡,单击 生成令牌,注意令牌仅显示一次,请妥善保管以便后续使用。 进入 概况 - OAuth2 选项卡,在 OAuth2 URL 生成器的 范围 中选中 bot 和 applications.commands 。 在 机器人权限 中选中 查看频道 , 发送消息 , 阅读消息历史记录 , 嵌入链接 , 添加文件 和 添加反应 。 将 已生成的 URL 中的 URL 复制到浏览器打开,按照提示安装应用并授权。 打开 Discord 应用,进入 用户设置 页面,在 开发者 菜单中启用 开发者模式 。在频道图标上右键,单击 复制服务器 ID ,在个人头像上左键,单击 复制用户 ID 。 运行如下命令配置 Discord 消息频道: macOS openclaw config set channels.discord.token "你的 TOKEN" openclaw config set channels.discord.enabled true --strict-json Windows podman compose exec openclaw-gateway node dist / index . js config set channels . discord . token "你的 TOKEN" podman compose exec openclaw-gateway node dist / index . js config set channels . discord . enabled true - -strict-json 向机器人发送任意消息,根据机器人回复的消息运行如下命令进行授权: macOS openclaw pairing approve discord <CODE> Windows podman compose exec openclaw-gateway node dist / index . js pairing approve discord < CODE > 此时就可以通过 Discord 私信和机器人对话了。在配置文件中添加如下内容来支持在服务器中同机器人对话: { "channels" : { "discord" : { "groupPolicy" : "allowlist" , "guilds" : { "服务器 ID" : { "requireMention" : true , "users" : [ "用户 ID" ] } } } } } 默认情况下,机器人只有在被 @ 时才会响应,如果需要对每条消息都进行响应,可以将 requireMention 设置为 false 。 QwenPaw 安装 在合适的目录创建如下文件夹: macOS mkdir -p /path/to/qwenpaw/data mkdir -p /path/to/qwenpaw/secrets Windows mkdir / path / to / qwenpaw / data mkdir / path / to / qwenpaw / secrets 运行如下命令使用 Podman 安装 QwenPaw: macOS podman pull agentscope/qwenpaw:latest podman run -d \ --name qwenpaw \ --restart always \ -v /path/to/qwenpaw/data:/app/working \ -v /path/to/qwenpaw/secrets:/app/working.secret \ -p 8088:8088 \ agentscope/qwenpaw:latest Windows podman pull agentscope / qwenpaw : latest podman run -d ` - -name qwenpaw ` - -restart always ` -v / path / to / qwenpaw / data : / app / working ` -v / path / to / qwenpaw / secrets : / app / working . secret ` -p 8088 : 8088 ` agentscope / qwenpaw : latest 使用浏览器打开 即可进入 QwenPaw 管理页面。 警告 QwenPaw 管理页面暂无权限校验,请勿将其暴露在公网。 注意 在 QwenPaw 中需要进入 智能体管理 中新建一个智能体, 默认智能体 无法进行修改。 消息频道 飞书 参见: Discord 参见: Hermes Agent 安装 在合适的目录创建如下文件夹: macOS mkdir -p /path/to/hermes-agent Windows mkdir / path / to / hermes-agent 运行如下命令使用 Podman 配置 Hermes Agent: macOS podman pull nousresearch/hermes-agent:latest podman run -it --rm \ -v /path/to/hermes-agent:/opt/data \ nousresearch/hermes-agent:latest setup Windows podman pull nousresearch / hermes-agent : latest podman run -it - -rm ` -v / path / to / hermes-agent : / opt / data ` nousresearch / hermes-agent : latest setup 在配置过程中根据实际情况对模型提供商等选项进行配置。运行如下代码启动 Gateway 容器: macOS podman run -d \ --name hermes-agent-gateway \ --restart unless-stopped \ -v /path/to/hermes-agent:/opt/data \ -p 8642:8642 \ nousresearch/hermes-agent:latest gateway run Windows podman run -d ` - -name hermes-agent -gateway ` - -restart unless-stopped ` -v / path / to / hermes-agent : / opt / data ` -p 8642 : 8642 ` nousresearch / hermes-agent : latest gateway run 运行如下代码启动 Dashboard 容器: macOS podman run -d \ --name hermes-agent-dashboard \ --restart unless-stopped \ -v /path/to/hermes-agent:/opt/data \ -p 9119:9119 \ -e GATEWAY_HEALTH_URL = http:// $HOST_IP :8642 \ nousresearch/hermes-agent:latest dashboard --host 0.0.0.0 --insecure Windows podman run -d ` - -name hermes-agent -dashboard ` - -restart unless-stopped ` -v / path / to / hermes-agent : / opt / data ` -p 9119 : 9119 ` -e GATEWAY_HEALTH_URL = http : // $HOST_IP : 8642 ` nousresearch / hermes-agent : latest dashboard - -host 0.0 . 0 . 0 - -insecure 将 $HOST_IP 替换为运行 Gateway 容器机器的 IP 地址(注意:需使用宿主机的 IP 地址,而不是 127.0.0.1 )。使用浏览器打开 即可进入 Hermes Agent 管理页面。 警告 Hermes Agent 管理页面暂无权限校验,请勿将其暴露在公网。 消息频道 飞书 参见: Discord 参见:

本地部署 OpenClaw,QwenPaw 和 Hermes Agent

2026/04/18 00:00 · 中文博客 on 范叶亮 | Leo Van

环境信息 本教程将介绍在 macOS 环境下部署 OpenClaw,QwenPaw 和 Hermes Agent。如无特殊说明,macOS 系统下需在终端中执行命令,Windows 系统下需要在 PowerShell 中执行命令。本教程涉及到的软件信息如下: 软件 版本 Podman 5.8.2 OpenClaw 2026.4.16 QwenPaw 1.1.2 Hermes Agent 0.10.0 虚拟环境 为了更好的进行环境隔离,后续我们使用 Podman 安装不同的智能体框架。 提示 在 Windows 系统下,单击开始按钮,搜索 启用或关闭 Windows 功能 ,在打开的窗口中将 Hyper-V 和 适用于 Linux 的 Windows 子系统 及其子项全部勾选,单击确定,待系统启用功能后重启电脑。 运行如下命令安装 Podman: macOS brew install podman brew 安装请参见: Windows scoop install podman scoop 安装请参见: 为了方便观察 Podman 的运行情况,可选的运行如下命令安装 Podman Desktop: macOS brew install podman-desktop Windows scoop install podman-desktop 安装完毕后,运行如下命令初始化并启动 Podman: macOS podman machine init podman machine start Windows podman machine init podman machine start 运行如下命令查看 Podman 的安装和运行情况: macOS podman info Windows podman info 更多 Podman 使用方法请参考 。有关 Podman Desktop 的使用方法请参考 。 OpenClaw 安装 克隆 OpenClaw 的源代码至本地: macOS git clone git@github.com:openclaw/openclaw.git Windows git clone git @github . com : openclaw / openclaw . git macOS 运行如下命令安装 OpenClaw CLI: curl -fsSL https://openclaw.ai/install-cli.sh | bash 命令会在 ~/.openclaw 目录下安装 Node 环境和相关依赖。进入 OpenClaw 源代码目录下,运行如下命令构建 Gateway 容器: export OPENCLAW_DOCKER_APT_PACKAGES = "chromium" ./scripts/podman/setup.sh 其中 OPENCLAW_DOCKER_APT_PACKAGES 表示构建 Gateway 容器时使用 apt 命令额外安装的软件包。运行如下命令启动 Gateway 容器: ./scripts/run-openclaw-podman.sh launch 运行如下命令进行配置: ./scripts/run-openclaw-podman.sh launch setup 在配置过程中根据实际情况对模型提供商等选项进行配置。配置如下环境变量来使用宿主机中的 OpenClaw CLI 管理 OpenClaw 容器: export PATH = " $PATH :/Users/leo/.openclaw/bin" export OPENCLAW_CONTAINER = openclaw Windows 在合适的目录创建如下文件夹: mkdir / path / to / openclaw mkdir / path / to / openclaw / workspace 进入 OpenClaw 源代码目录下,运行如下命令构建 Gateway 容器: podman build -t openclaw : local -f Dockerfile . - -build-arg OPENCLAW_DOCKER_APT_PACKAGES = "chromium" 其中 OPENCLAW_DOCKER_APT_PACKAGES 表示构建 Gateway 容器时使用 apt 命令额外安装的软件包。运行如下命令配置并启动 Gateway 容器: $env:OPENCLAW_CONFIG_DIR = "/path/to/openclaw" $env:OPENCLAW_WORKSPACE_DIR = "/path/to/openclaw/workspace" podman compose run - -rm - -no-deps - -entrypoint node openclaw-gateway ` dist / index . js onboard - -mode local - -no-install-daemon podman compose run - -rm - -no-deps - -entrypoint node openclaw-gateway ` dist / index . js config set - -batch-json '[{"path":"gateway.mode","value":"local"},{"path":"gateway.bind","value":"lan"},{"path":"gateway.controlUi.allowedOrigins","value":["http://localhost:18789","http://127.0.0.1:18789"]}]' podman compose up -d openclaw-gateway 在配置中过程中根据实际情况对模型提供商等选项进行配置。 使用 Podman 安装 OpenClaw 后,重启 Gateway 的命令如下: macOS podman restart openclaw Windows podman restart openclaw-openclaw -gateway - 1 使用浏览器打开 即可进入 OpenClaw 管理页面。更多细节请参考 。 警告 OpenClaw 管理页面虽然支持权限校验,但为了安全起见,请勿将其暴露在公网。 消息频道 提示 在 Windows 系统下, podman compose 命令需要在 OpenClaw 源代码目录下运行。 飞书 运行如下命令配置飞书消息频道: macOS openclaw channels login --channel feishu Windows podman compose exec openclaw-gateway node dist / index . js channels login - -channel feishu 使用飞书 APP 扫描生成的二维码进行后续配置即可。 Discord 首先在 Discord 中创建一个服务器,进入 ,单击 按钮创建新的应用,并填写应用名称。 进入 概况 - 机器人 选项卡,启用 Presence Intent , Server Members Intent 和 Message Content Intent 。 进入 概况 - 机器人 选项卡,单击 生成令牌,注意令牌仅显示一次,请妥善保管以便后续使用。 进入 概况 - OAuth2 选项卡,在 OAuth2 URL 生成器的 范围 中选中 bot 和 applications.commands 。 在 机器人权限 中选中 查看频道 , 发送消息 , 阅读消息历史记录 , 嵌入链接 , 添加文件 和 添加反应 。 将 已生成的 URL 中的 URL 复制到浏览器打开,按照提示安装应用并授权。 打开 Discord 应用,进入 用户设置 页面,在 开发者 菜单中启用 开发者模式 。在频道图标上右键,单击 复制服务器 ID ,在个人头像上左键,单击 复制用户 ID 。 运行如下命令配置 Discord 消息频道: macOS openclaw config set channels.discord.token "你的 TOKEN" openclaw config set channels.discord.enabled true --strict-json Windows podman compose exec openclaw-gateway node dist / index . js config set channels . discord . token "你的 TOKEN" podman compose exec openclaw-gateway node dist / index . js config set channels . discord . enabled true - -strict-json 向机器人发送任意消息,根据机器人回复的消息运行如下命令进行授权: macOS openclaw pairing approve discord <CODE> Windows podman compose exec openclaw-gateway node dist / index . js pairing approve discord < CODE > 此时就可以通过 Discord 私信和机器人对话了。在配置文件中添加如下内容来支持在服务器中同机器人对话: { "channels" : { "discord" : { "groupPolicy" : "allowlist" , "guilds" : { "服务器 ID" : { "requireMention" : true , "users" : [ "用户 ID" ] } } } } } 默认情况下,机器人只有在被 @ 时才会响应,如果需要对每条消息都进行响应,可以将 requireMention 设置为 false 。 QwenPaw 安装 在合适的目录创建如下文件夹: macOS mkdir -p /path/to/qwenpaw/data mkdir -p /path/to/qwenpaw/secrets Windows mkdir / path / to / qwenpaw / data mkdir / path / to / qwenpaw / secrets 运行如下命令使用 Podman 安装 QwenPaw: macOS podman pull agentscope/qwenpaw:latest podman run -d \ --name qwenpaw \ --restart always \ -v /path/to/qwenpaw/data:/app/working \ -v /path/to/qwenpaw/secrets:/app/working.secret \ -p 8088:8088 \ agentscope/qwenpaw:latest Windows podman pull agentscope / qwenpaw : latest podman run -d ` - -name qwenpaw ` - -restart always ` -v / path / to / qwenpaw / data : / app / working ` -v / path / to / qwenpaw / secrets : / app / working . secret ` -p 8088 : 8088 ` agentscope / qwenpaw : latest 使用浏览器打开 即可进入 QwenPaw 管理页面。 警告 QwenPaw 管理页面暂无权限校验,请勿将其暴露在公网。 注意 在 QwenPaw 中需要进入 智能体管理 中新建一个智能体, 默认智能体 无法进行修改。 消息频道 飞书 参见: Discord 参见: Hermes Agent 安装 在合适的目录创建如下文件夹: macOS mkdir -p /path/to/hermes-agent Windows mkdir / path / to / hermes-agent 运行如下命令使用 Podman 配置 Hermes Agent: macOS podman pull nousresearch/hermes-agent:latest podman run -it --rm \ -v /path/to/hermes-agent:/opt/data \ nousresearch/hermes-agent:latest setup Windows podman pull nousresearch / hermes-agent : latest podman run -it - -rm ` -v / path / to / hermes-agent : / opt / data ` nousresearch / hermes-agent : latest setup 在配置过程中根据实际情况对模型提供商等选项进行配置。运行如下代码启动 Gateway 容器: macOS podman run -d \ --name hermes-agent-gateway \ --restart unless-stopped \ -v /path/to/hermes-agent:/opt/data \ -p 8642:8642 \ nousresearch/hermes-agent:latest gateway run Windows podman run -d ` - -name hermes-agent -gateway ` - -restart unless-stopped ` -v / path / to / hermes-agent : / opt / data ` -p 8642 : 8642 ` nousresearch / hermes-agent : latest gateway run 运行如下代码启动 Dashboard 容器: macOS podman run -d \ --name hermes-agent-dashboard \ --restart unless-stopped \ -v /path/to/hermes-agent:/opt/data \ -p 9119:9119 \ -e GATEWAY_HEALTH_URL = http:// $HOST_IP :8642 \ nousresearch/hermes-agent:latest dashboard --host 0.0.0.0 --insecure Windows podman run -d ` - -name hermes-agent -dashboard ` - -restart unless-stopped ` -v / path / to / hermes-agent : / opt / data ` -p 9119 : 9119 ` -e GATEWAY_HEALTH_URL = http : // $HOST_IP : 8642 ` nousresearch / hermes-agent : latest dashboard - -host 0.0 . 0 . 0 - -insecure 将 $HOST_IP 替换为运行 Gateway 容器机器的 IP 地址(注意:需使用宿主机的 IP 地址,而不是 127.0.0.1 )。使用浏览器打开 即可进入 Hermes Agent 管理页面。 警告 Hermes Agent 管理页面暂无权限校验,请勿将其暴露在公网。 消息频道 飞书 参见: Discord 参见:

部署 Matrix 服务器 Synapse

2026/04/11 00:00 · 中文博客 on 范叶亮 | Leo Van

环境信息 是一种用于实时通讯的开放、去中心化协议,专注于安全、加密的文字、语音和视频聊天。它允许不同服务器上的用户互通,类似于邮件系统,并支持端到端加密,使用户能完全控制数据,不受单一实体限制。 Matrix 联邦服务器之间连接的客户端 是一个使用 Python/Twisted 和 Rust 编写的开源 Matrix 服务器实现。本教程将介绍使用 Docker 容器部署 Matrix 服务器 Synapse。本教程涉及到的软件信息如下: 软件 Docker 镜像 版本 PostgreSQL mixdeve/postgres-zhparser:18 18 Redis redis:8 8 Synapse matrixdotorg/synapse:latest 1.151.0 注意 将后续命令中的 example.com 替换为实际域名。 准备工作 数据库 为了支持中文搜索,在此选择内置 zhparser 分词功能的 PostgreSQL 镜像。在适当位置创建 PostgreSQL 的存储目录,例如 postgresql 。运行如下命令生成配置: docker run -d \ --name postgresql \ --restart always \ -v $( pwd ) /postgresql:/var/lib/postgresql \ -e POSTGRES_USER = postgres \ -e POSTGRES_PASSWORD = <密码> \ -e ALLOW_IP_RANGE = 0.0.0.0/0 \ -p 5432:5432 \ mixdeve/postgres-zhparser:18 相关参数说明如下: 参数 说明 POSTGRES_USER 数据库用户名,默认 postgres POSTGRES_PASSWORD 数据库密码 POSTGRES_DB 默认数据库名,默认 postgres ALLOW_IP_RANGE 允许访问的 IP 范围 进入数据库执行如下 SQL 进行配置: -- 创建用户 CREATE USER synapse WITH PASSWORD '<密码>' ; -- 创建数据库 CREATE DATABASE synapse WITH OWNER = synapse ENCODING = 'UTF8' LC_COLLATE = 'C' LC_CTYPE = 'C' TEMPLATE = template0 ; -- 授权 GRANT ALL PRIVILEGES ON DATABASE synapse TO synapse ; 缓存 为了提升服务性能,在此开启 Redis 缓存。在适当位置创建 Redis 的存储目录,例如 redis 。运行如下命令启动 Redis 容器: docker run -d \ --name redis \ --restart always \ -v $( pwd ) /redis:/data \ -p 6379:6379 \ redis:8 \ redis-server --save 60 1 --appendonly yes 配置文件 进入服务器在适当位置创建 Synapse 的存储目录,例如 synapse 。运行如下命令生成配置: docker run -it --rm \ -v $( pwd ) /synapse:/data \ -e SYNAPSE_SERVER_NAME = example.com \ -e SYNAPSE_REPORT_STATS = no \ -e SYNAPSE_HTTP_PORT = 8008 \ -e UID = 1000 \ -e GID = 1000 \ matrixdotorg/synapse:latest generate 相关参数说明如下: 参数 说明 SYNAPSE_SERVER_NAME 服务器域名 SYNAPSE_REPORT_STATS 是否上报统计信息,默认 yes SYNAPSE_HTTP_PORT HTTP 端口,默认 8008 SYNAPSE_CONFIG_DIR 配置目录,默认 /data SYNAPSE_CONFIG_PATH 配置文件路径,默认 <SYNAPSE_CONFIG_DIR>/homeserver.yaml SYNAPSE_DATA_DIR 数据目录,默认 /data UID 用户 ID,默认 991 GID 组 ID,默认 991 修改配置文件服务部分如下: public_baseurl : https://matrix-homeserver.example.com serve_server_wellknown : true 修改配置文件数据库部分如下: database : name : psycopg2 txn_limit : 10000 args : user : synapse password : <密码> dbname : synapse host : <数据库地址> port : 5432 cp_min : 5 cp_max : 10 修改配置文件缓存部分如下: redis : enabled : true host : <数据库地址> port : 6379 dbid : 0 启动服务 运行如下命令启动服务: docker run -d \ --name synapse \ --restart always \ -v $( pwd ) /synapse:/data \ -u 1000:1000 \ -p 8008:8008 \ matrixdotorg/synapse:latest 在服务商中配置 DNS 将 matrix-homeserver.example.com 解析至 Docker 服务器的 IP 地址。通过浏览器访问 即可查看 Synapse 服务是否启动成功。 中文搜索 提示 如果不需要中文搜索服务,可跳过本节。 在 PostgreSQL 数据中运行如下 SQL 安装 zhparser 扩展并配置中文搜索: -- 创建 zhparser 扩展 CREATE EXTENSION IF NOT EXISTS zhparser ; -- 创建中文搜索配置 CREATE TEXT SEARCH CONFIGURATION chinese ( PARSER = zhparser ); ALTER TEXT SEARCH CONFIGURATION chinese ADD MAPPING FOR n , v , a , i , e , l WITH simple ; -- 添加中文向量列 ALTER TABLE event_search ADD COLUMN IF NOT EXISTS chinese_vector tsvector ; -- 对已有数据进行中文分词处理 UPDATE event_search SET chinese_vector = CASE WHEN event_search . key = 'content.body' AND TRIM ( event_json . json :: jsonb -> 'content' ->> 'body' ) != '' THEN to_tsvector ( 'chinese' , event_json . json :: jsonb -> 'content' ->> 'body' ) WHEN event_search . key = 'content.name' AND TRIM ( event_json . json :: jsonb -> 'content' ->> 'name' ) != '' THEN to_tsvector ( 'chinese' , event_json . json :: jsonb -> 'content' ->> 'name' ) WHEN event_search . key = 'content.topic' AND TRIM ( event_json . json :: jsonb -> 'content' ->> 'topic' ) != '' THEN to_tsvector ( 'chinese' , event_json . json :: jsonb -> 'content' ->> 'topic' ) ELSE NULL END FROM event_json WHERE event_search . event_id = event_json . event_id AND ( event_search . chinese_vector IS NULL OR event_search . chinese_vector :: text = '' ); -- 创建中文索引 CREATE INDEX CONCURRENTLY event_search_chinese_vector_idx ON event_search USING GIN ( chinese_vector ); 将修改后的 文件映射至 Synapse 容器,删除之前的容器,运行如下命令重新创建容器: docker run -d \ --name synapse \ --restart always \ -v $( pwd ) /synapse:/data \ -v $( pwd ) /synapse/search.py:/usr/local/lib/python3.13/site-packages/synapse/storage/databases/main/search.py \ -u 1000:1000 \ -p 8008:8008 \ matrixdotorg/synapse:latest 注意 更新 Synapse 版本后,请注意原始 是否发生变化,如有则需要重新修改支持中文的 search.py 。同时请注意 中镜像基于的系统环境和 Python 版本是否发生变化,如有则需要对应调整将修改后 search.py 文件的映射路径。 发现服务 提示 如果希望使用主域名 example.com 成为 Matrix 服务域名(例如: @user:example.com ),则需要配置发现服务。如果希望使用子域名 matrix-homeserver.example.com 成为 Matrix 服务域名(例如: @user:matrix-homeserver.example.com ),则可以跳过本节。 发现服务是 Matrix 网络发现服务器位置的一种方式。因为实际服务运行在子域名 matrix-homeserver.example.com 上,需要让其他服务器和客户端知道我们使用主域名,因此需要提供 /.well-known/matrix 信息。因此需要将 https://example.com/.well-known/matrix 映射到 https://matrix-homeserver.example.com/.well-known/matrix ,相关细节请参考 。 注册用户 Synapse 服务默认是禁止自助注册用户的,运行如下命令进入 Synapse 容器: docker exec -it synapse /bin/bash 运行如下命令创建用户: register_new_matrix_user http://localhost:8008 \ -c /data/homeserver.yaml -a \ -u "<用户名>" \ -p "<密码>" 开始使用 在浏览器上打开 ,单击 切换 Homeserver 到 example.com ,输入用户名和密码即可登录。

部署 frp 内网穿透服务

2026/04/10 00:00 · 中文博客 on 范叶亮 | Leo Van

环境信息 frp 是一款高性能的反向代理应用,专注于内网穿透。它支持多种协议,包括 TCP、UDP、HTTP、HTTPS 等,并且具备 P2P 通信功能。使用 frp,您可以安全、便捷地将内网服务暴露到公网,通过拥有公网 IP 的节点进行中转 。 frp 架构图 本教程将介绍在具有公网 IP 的服务器和内网路由器上部署 frp 内网穿透服务。本教程涉及到的环境信息如下: 环境 系统 服务端 外网服务器系统 Ubuntu 24.04 客户端 内网路由器系统 OpenWRT 24.10 注意 将后续命令中的 example.com 替换为实际域名。 证书申请 frp 证书 在本地创建 cert 目录,将 OpenSSL 配置文件复制到该目录。通常情况下 Linux 系统位于 /etc/pki/tls/openssl.cnf ,macOS 系统位于 /System/Library/OpenSSL/openssl.cnf 。 运行如下命令生成 ca 证书: openssl genrsa -out ca.key 2048 openssl req -x509 -new -nodes -key ca.key -subj "/CN=example.com" -days 36500 -out ca.crt 运行如下命令生成服务端证书: openssl genrsa -out server.key 2048 openssl req -new -sha256 -key server.key \ -subj "/C=XX/ST=DEFAULT/L=DEFAULT/O=DEFAULT/CN=example.com" \ -reqexts SAN \ -config < ( cat openssl.cnf < ( printf "\n[SAN]\nsubjectAltName=DNS:localhost,IP:127.0.0.1,DNS:*.example.com" )) \ -out server.csr openssl x509 -req -days 36500 -sha256 \ -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial \ -extfile < ( printf "subjectAltName=DNS:localhost,IP:127.0.0.1,DNS:example.com" ) \ -out server.crt 运行如下命令生成客户端证书: openssl genrsa -out client.key 2048 openssl req -new -sha256 -key client.key \ -subj "/C=XX/ST=DEFAULT/L=DEFAULT/O=DEFAULT/CN=example.com" \ -reqexts SAN \ -config < ( cat openssl.cnf < ( printf "\n[SAN]\nsubjectAltName=DNS:localhost,IP:127.0.0.1,DNS:*.example.com" )) \ -out client.csr openssl x509 -req -days 36500 -sha256 \ -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial \ -extfile < ( printf "subjectAltName=DNS:localhost,IP:127.0.0.1,DNS:example.com" ) \ -out client.crt 由于 server.crt 和 client.crt 都是由 ca 签发的,因此他们对于 ca 来说都是合法的。 Nginx 证书 在服务器上运行如下命令安装 acme.sh: curl https://get.acme.sh | sh -s email = my@example.com 安装脚本将执行如下动作: 在 $HOME 目录创建 .acme.sh 目录并安装 acme.sh。 创建别名 acme.sh 指向 $HOME/.acme.sh/acme.sh 。 创建每日定时任务以便更新证书。 以阿里云域名管理为例,在 页面创建用户,并为用户赋予 DNS 相关管理权限。为用户创建 AccessKey,并设置如下环境变量: export Ali_Key = "xxx" export Ali_Secret = "xxx" 运行如下命令申请证书: acme.sh --issue --dns dns_ali -d example.com -d *.example.com frp 配置 注意 将后续命令中的 /path/to 替换为对应文件的实际路径,将 xxx 替换为实际内容。 服务端 在服务端创建 frp 目录,配置 frps.toml 文件参数如下,更多参数设置请参阅 : bindAddr = "0.0.0.0" bindPort = 7000 quicBindPort = 7000 vhostHTTPPort = 8080 vhostHTTPSPort = 8443 tcpmuxHTTPConnectPort = 5002 auth . method = "token" auth . token = "xxx" transport . tls . certFile = "/path/to/server.crt" transport . tls . keyFile = "/path/to/server.key" transport . tls . trustedCaFile = "/path/to/ca.crt" webServer . addr = "0.0.0.0" webServer . port = 7500 webServer . user = "xxx" webServer . password = "xxx" log . to = "/path/to/frps.log" log . level = "info" log . maxDays = 3 注意 请确保将上述配置中的端口针对 0.0.0.0/0 关闭防火墙拦截。 在 /etc/systemd/system 路径创建 frps.service 服务,配置内容如下: [Unit] Description = frp server After = network.target syslog.target Wants = network.target [Service] Type = simple ExecStart = /path/to/frps -c /path/to/frps.toml [Install] WantedBy = multi-user.target 运行如下命令管理 frps 服务: # 自启动 frps sudo systemctl enable frps # 启动 frps sudo systemctl start frps # 停止 frps sudo systemctl stop frps # 重启 frps sudo systemctl restart frps # 查看 frps 状态 sudo systemctl status frps 添加如下内容至 Nginx 配置文件中: server { listen 80 ; listen [::]:80 ; server_name *.example.com ; return 301 https:// $host$request_uri ; } server { listen 443 ssl http2 ; listen [::]:443 ssl http2 ; server_name *.example.com ; ssl_certificate /path/to/example.com.cer ; ssl_certificate_key /path/to/example.com.key ; location / { proxy_pass http://127.0.0.1:8080 ; proxy_redirect off ; proxy_ssl_server_name on ; proxy_set_header Host $host:80 ; proxy_set_header Referer $http_referer ; proxy_set_header Cookie $http_cookie ; proxy_set_header X-Real-IP $remote_addr ; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for ; proxy_set_header X-Forwarded-Proto $scheme ; } } 运行如下命令重启 Nginx: sudo systemctl restart nginx 客户端 注意 将后续命令中的 x.x.x.x 替换为本地服务对应的 IP 地址。 在客户端创建 frp 目录,配置 frpc.toml 文件参数如下,更多参数设置请参阅 : auth . method = "token" auth . token = "xxx" user = "xxx" serverAddr = "frps.example.com" serverPort = 7000 transport . protocol = "quic" transport . proxyProtocolVersion = "v2" transport . tls . certFile = "/path/to/client.crt" transport . tls . keyFile = "/path/to/client.key" transport . tls . trustedCaFile = "/path/to/ca.crt" webServer . addr = "0.0.0.0" webServer . port = 7400 webServer . user = "xxx" webServer . password = "xxx" log . to = "/path/to/frpc.log" log . level = "info" log . maxDays = 3 [[ proxies ]] name = "example-http" type = "http" localIP = "x.x.x.x" localPort = 80 customDomains = [ "example-http.example.com" ] [[ proxies ]] name = "example-ssh" type = "tcpmux" multiplexer = "httpconnect" localIP = "x.x.x.x" localPort = 22 customDomains = [ "example-ssh.example.com" ] 其中, example-http 采用了通过自定义域名的方式访问内网 Web 服务,更多示例请参考 ; example-ssh 采用了多个 SSH 服务复用同一端口的方式连接内网 SSH 服务,更多示例请参考 。 在 /etc/init.d 路径下创建 frpc 服务,配置内容如下: #!/bin/sh /etc/rc.common # 使用 procd USE_PROCD = 1 # 启动顺序 START = 95 # 停止顺序 STOP = 15 # frpc FRPC = /path/to/frpc CONF = /path/to/frpc.toml start_service () { procd_open_instance "frpc" procd_set_param command $FRPC -c $CONF procd_set_param respawn procd_set_param stdout 1 procd_set_param stderr 1 procd_set_param pidfile /var/run/frpc.pid procd_close_instance } service_triggers () { procd_add_reload_mount_trigger $CONF } 运行如下命令管理 frpc 服务: # 赋予执行权限 chmod +x /etc/init.d/frpc # 自启动 frpc /etc/init.d/frpc enable # 启动 frpc /etc/init.d/frpc start # 停止 frpc /etc/init.d/frpc stop # 重启 frpc /etc/init.d/frpc restart # 查看 frpc 状态 /etc/init.d/frpc status 在服务商中配置 DNS 将 example-http.example.com 和 example-ssh.example.com 解析至 frp 服务器的 IP 地址。 连接 Web 此时,通过浏览器访问 即可实现访问内网 IP 地址 x.x.x.x 在端口 80 上的 Web 服务。 SSH 提示 请先在本地机器上安装 socat 工具。 此时,通过如下命令即可实现访问内网 IP 地址 x.x.x.x 在端口 22 上的 SSH 服务: ssh -o 'proxycommand socat - PROXY:frps.example.com:%h:%p,proxyport=5002' test@example-ssh.example.com

本地部署大模型服务

2026/04/05 00:00 · 中文博客 on 范叶亮 | Leo Van

环境信息 本教程将介绍在 macOS 和 Windows 环境下部署本地大模型服务。如无特殊说明,macOS 系统下需在终端中执行命令,Windows 系统下需要在 PowerShell 中执行命令。本教程涉及到的软件和模型信息如下: 软件 版本 ollama 0.20.2 LM Studio 0.4.9+1 vllm 0.19.0 vllm-metal v0.1.0-20260404-164341 vllm-mlx 0.2.7 oMLX 0.3.4 名称 架构 量化 内存 / 显存 能力 链接 gemma-4-31B-it 稠密 4bit 32 GB 及以上 : / / : / / gemma-4-26B-A4B-it MoE 4bit 32 GB 及以上 : / / : / / Qwen3.5-27B 稠密 4bit 32 GB 及以上 : / / : / / Qwen3.5-35B-A3B MoE 4bit 32 GB 及以上 : / / : / / CoPaw-Flash-9B 稠密 4bit 16 GB 及以上 : : 为了加速从 Hugging Face 模型仓库下载模型,可以运行如下命令配置相关环境变量: macOS echo "HF_ENDPOINT=https://hf-mirror.com" >> ~/.bash_profile Windows [ Environment ]:: SetEnvironmentVariable ( "HF_ENDPOINT" , "https://hf-mirror.com" , "User" ) 更多使用方式可参考 官方网站。 ollama 推荐在终端运行如下命令安装 ollama: macOS curl -fsSL https://ollama.com/install.sh | sh Windows irm https : // ollama . com / install . ps1 | iex 运行如下命令可以显示当前安装的版本号: ollama --version # ollama version is 0.20.2 ollama 当前采用 ollama pull MODEL 命令下载模型,除了使用 中的模型名称外(例如: qwen3.5:27b-nvfp4 ),还可以使用 Hugging Face 的模型链接(例如: https://huggingface.co/lmstudio-community/Qwen3.5-27B-GGUF ),运行如下命令下载模型: ollama pull qwen3.5:27b-nvfp4 ollama pull https://huggingface.co/lmstudio-community/Qwen3.5-27B-GGUF ollama 当前仅支持通过环境变量配置监听地址和端口,运行如下命令进行配置: macOS echo "OLLAMA_HOST=0.0.0.0:11434" >> ~/.bash_profile Windows [ Environment ]:: SetEnvironmentVariable ( "OLLAMA_HOST" , "0.0.0.0:11434" , "User" ) 运行如下命令启动模型服务: macOS ollama run <模型名称> Windows ollama run < 模型名称 > 提示 ollama 默认会选择最适合的运行库,如果需要切换可以手动指定 LLM 运行库,运行如下命令表示使用 CPU 进行推理: OLLAMA_LLM_LIBRARY="cpu_avx2" ollama serve <模型名称> 注意 在 Settings 中将 Context length 设置为最大值,以确保在后续使用过程中不会因上下文长度不足而导致效果下降。 macOS Windows 打开 ollama 主页面,选择对应的模型,即可开始对话: macOS Windows 模型服务运行在 http://127.0.0.1:11434 ,API 文档详见: 。运行如下命令以 OpenAI 兼容的接口测试服务: macOS curl http://127.0.0.1:11434/v1/chat/completions \ -H "Content-Type: application/json" \ -d '{ "model": "<模型名称>", "messages": [ { "role": "user", "content": "你好" } ] }' Windows iwr -Uri http : // 127.0 . 0 . 1 : 11434 / v1 / chat / completions ` -Method Post ` -ContentType "application/json" ` -Body '{ "model": "<模型名称>", "messages": [ { "role": "user", "content": "你好" } ] }' LM Studio 建议 Windows 系统测试使用 推荐从 官网下载安装包,并运行安装 LM Studio。如果只需要安装 LM Studio 核心,不需要 GUI 界面,则可以在终端运行如下命令: macOS curl -fsSL https://lmstudio.ai/install.sh | bash Windows irm https : // lmstudio . ai / install . ps1 | iex 下载并安装所需的 Runtime,macOS 系统支持 GGUF 和 MLX 两种格式,Windows 系统仅支持 GGUF 格式。 macOS Windows 注意 在 Settings - Model Defaults 中将 Default Context Length 设置为 Model Maximum,以确保在后续使用过程中不会因上下文长度不足而导致效果下降。 打开 LM Studio 主页面,选择对应的模型,即可开始对话: macOS Windows 单击左侧的 按钮,单击 Local Server,将 Status 滑动至 Running 状态。模型服务运行在 http://127.0.0.1:1234 ,API 文档详见: 。运行如下命令以 OpenAI 兼容的接口测试服务: macOS curl http://127.0.0.1:1234/v1/chat/completions \ -H "Content-Type: application/json" \ -d '{ "model": "<模型名称>", "messages": [ { "role": "user", "content": "你好" } ] }' Windows iwr -Uri http : // 127.0 . 0 . 1 : 1234 / v1 / chat / completions ` -Method Post ` -ContentType "application/json" ` -Body '{ "model": "<模型名称>", "messages": [ { "role": "user", "content": "你好" } ] }' oMLX 建议 macOS 系统测试使用 推荐从 官网下载安装包,并运行安装 oMLX。安装完毕后启动,并从 macOS 菜单栏或 Windows 系统托盘单击 oMLX 图标,选择 Start Server 启动服务。待服务启动后,单击 Admin Panel 从浏览器打开管理面板,初次登录需要设置 API Key。在 Models - Downloader 中可以直接从 Hugging Face 和 ModelScope 模型仓库下载模型。 提示 建议国内用户切换至 ModelScope 标签,复制上文 ModelScope 模型连接的尾部(例如: mlx-community/gemma-4-31b-it-nvfp4 )至 REPOSITORY ID 中下载模型。 在 Settings - Model Settings 中单击对应模型 STATUS 中的按钮载入模型。 注意 在 Settings - Global Settings 中将 Max Context Window 和 Max Tokens 设置为合适的值,以确保在后续使用过程中不会因上下文长度不足而导致效果下降。 单击 Chat 进入对话页面,选择对应的模型,即可开始对话: 模型服务运行在 http://127.0.0.1:8000 。运行如下命令以 OpenAI 兼容的接口测试服务: curl http://127.0.0.1:8000/v1/chat/completions \ -H "Authorization: Bearer <API_KEY>" \ -H "Content-Type: application/json" \ -d '{ "model": "<模型名称>", "messages": [ { "role": "user", "content": "你好" } ] }' vllm 建议 macOS 系统生产使用 提示 vllm 官方仅支持 macOS 和 Linux 系统,暂无 GUI 界面。在此以 macOS 系统为例进行安装。 在 macOS 系统上,使用 vllm-metal 库安装 vllm 服务,运行如下命令: curl -fsSL https://raw.githubusercontent.com/vllm-project/vllm-metal/main/install.sh | bash 这会在 ~/.venv-vllm-metal 路径下创建一个 Python 虚拟环境,并安装 vllm 服务。运行如下命令即可删除安装: rm -rf ~/.venv-vllm-metal 运行如下命令激活 Python 虚拟环境: source ~/.venv-vllm-metal/bin/activate 运行如下命令启动 vllm 服务: vllm serve <模型名称 | 模型路径> 模型服务运行在 http://127.0.0.1:8000 ,更多环境变量设置请参考: ,更多命令行参数设置请参考: 。运行如下命令以 OpenAI 兼容的接口测试服务: curl http://127.0.0.1:8000/v1/chat/completions \ -H "Content-Type: application/json" \ -d '{ "model": "<模型名称>", "messages": [ { "role": "user", "content": "你好" } ] }'

AI 时代的生产力和生产关系

2026/03/29 00:00 · 中文博客 on 范叶亮 | Leo Van

那只🦞 AI 的发展想必不用多说,速度之快远超我们的想象。将 AI 大事记和标普 500 整合绘制折线图如下: AI 大事记 vs. 标普 500 从图中可以看出,自 2015 年 OpenAI 成立以来,随着标普 500 指数的不断增高,AI 也在以倍速迅猛发展。毋庸置疑在这个时代,如果你不了解 AI,不紧跟 AI,那么你可能会很快就会被社会淘汰。随着一股“龙虾热”的到来,更是把 AI 的关注度推到了风口浪尖。积极的去拥抱新的技术,亲自下场去体验,这都是很好的事,但也大可不必因为 FOMO(Fear of Missing Out,错失恐惧症)而太过盲从。即使你全身心 100% 的投入,在 AI 的浪潮中依然会有你错失的,停下来根据自身的实际情况多一些思考,才是争取不被拍死在沙滩上的最好选择。Anyway,一人开发者的周末项目,在短短不到 5 个月的时间内登顶 GitHub,这里面所预示的变革也绝不是我这些许思考所能妄言定论的,让我们且行且悟吧。 前不久在组织内部(大部分成员并非技术背景)讨论 AI 应用的时候(彼时公司已经提供了内部免费版的龙虾供大家试用),我抛出了如下两个问题: 有多少人尝试过私有化部署龙虾? 如果由你自己承担龙虾的费用,你是否还会像当前这样使用龙虾? 第一个问题要从前不久如火如荼的排队装龙虾开始说起,从安装龙虾,再到卸载龙虾,每个时代都有每个时代的鸡蛋要领。晚点有篇文章 不错,提到网上流传着的一个悖论:“如果你需要托人帮你安装龙虾,那么你可能就不太需要龙虾。”这句话多少有些偏激了,但意思就是那么个意思,如果连这部分技术都不了解,那么在使用龙虾的过程中一旦遇到一些复杂情况,你就会陷入“问虾你为什么不行”-“虾说因为 XXX”-“你说你自己不能解决码?”-“虾说 balabalabalabala”的死循环当中。或者换个角度,如果龙虾真的无论是从可用还是易用角度做到了极致,那么此时此刻是否还需要你这个人去用它呢?这时最重要的问题或许是我们这些碳基生物应该如何避免被硅基生物消灭吧? 第二个问题会比较实在些,天天在谈 ROI,公司出于更长远的战略考虑给到一定的免费额度,但如果需要实打实的花自己钱的时候你真的还会随便用吗?只能说当下很多人还没有被 AI 替代是因为 AI 的成本比我们这些牛马的工资还是要高的。我相信随着技术的不断发展,AI 的成本也会越来越低,此时我们更需要思考些更适合 AI 去做,哪些更适合我们去做,那些 AI 暂时还替代不了我们去做的才是我们的核心竞争力,再用 AI 把自己加持下才是最妙的。 生产力 生产力 生产力是改造和影响自然并使之适应社会需要的客观物质力量。一定的生产力决定了一定的生产关系,二者组成特定的生产方式。 AI 是一种先进的生产力,这个应该不太会有人否认吧。我个人总结其主要先进在两个方面: 效率。AI 在效率提升上面的效果是有目共睹的,无论你的工作类型是什么样的,哪怕你是体力劳动者。只能说对脑力工作者的提效会更多些,尤其是那些流程化、重复性的工作,以运营类工作尤为明显。对我而言更好的代码补全也着实提高了我的开发效率。 创新。对于一些复杂的不确定性工作,AI 可以给到我很多新奇的点子,启发我把复杂的任务成功解决。很难说这是真的“创新”,也许在 AI 的脑子中这并非新鲜事物,但之于我自己而言,确实给到我眼前一亮的惊喜。前不久 Anthropic 团队使用 16 个智能体从零开始构建了一个基于 Rust 的 C 语言编译器 。我很惊讶这么底层的能力就这样被自动实现了(我并没有去体验,单纯的惊讶),但也有人质疑这只是“临摹”而非“创作”。毕竟 AI 吃过的盐比我吃过的饭都要多得多得多。因此无须太纠结这是不是真的创新,之于你是,之于你在做的事儿是,那就是。 在谈及 AI 作为一种先进的生产力时,它与瓦特的蒸汽机、爱迪生的电灯泡、亦或是宾夕法尼亚大学的埃尼阿克并无差异,本质上都是社会生产环节中的一个辅助工具。 生产关系 生产关系 生产关系是人们在社会生产中形成的一种一定的、必然的、不以他们的意志为转移的关系。生产关系基于一定生产力,反过来又会限制生产力。 根据定义来看,AI 确实“不是”生产关系,生产关系探讨的主要是“人”与“物”以及“人”与“人”的关系,例如:生产资料所有制,生产中的地位和相互关系,产品的分配方式等。但 AI 作为生产力却可以影响生产关系,我认为此时用“重塑”会更适合些,因为这波 AI 带来的冲击确实过于迅猛。 之前听过付鹏的几期演讲和相关的播客,他将套利 的核心归纳为价差、利差、汇差,而在这些之前,还会有信息差、认知差、执行差、竞争差、资源差等等。我个人不是很懂投资,买过的股票基金啥的大多也是赔的,听的这些投资内容更多是出于对经济和风险的进一步理解。AI 在帮助我们缩小信息差、认知差、执行差、竞争差、资源差这些方面比之前变得更有可能,尤其是对于我们这些屁民而言。试想一下,之前在一个未知领域遇到了一个问题,Google 一下,搜索引擎玩儿的溜的能多获取一些有用的信息,玩儿不转的就只能凭人品看看有没有靠谱的朋友帮你解惑一二了。如果你有钱那就另说了,此时你又营造了资源差,但 AI 在帮助大家提升认知上貌似是公平的,是容易的。那么当答案获取变得便宜之后,什么又变得昂贵了呢?勇气,执行力,还是? 前不久比较火的一个词应该是“一人公司”(OPC,One Person Company),一个由 AI 技术驱动产生的全新组织范式。如果把一人公司做到极致,貌似你只需要同你的 AI 进行直接交流,AI 可以帮你去对接客户,AI 可以帮你去做产品,AI 可以帮你去销售。此时“人”-“人”的关系就转变成了“人”-“AI”-“人”的关系,甚至是“人”-“AI”-“AI”-“人”的关系,谁知道你的 AI 对接的客户是不是也是一个 AI 呢?从内部视角来看也是一样,从养一只虾到养多只虾,从管多只虾到管一只管多只虾的虾。 flowchart TD A[你] --> B(🦞#1) flowchart TD A[你] --> B(🦞#1) A[你] --> C(🦞#2) A[你] --> D(🦞#3) flowchart TD A[你] --> B(🦞#01) B --> C(🦞#11) B --> D(🦞#12) B --> E(🦞#13) 你时不时的 PUA 下你的虾,你的虾时不时的摸会儿鱼。作为基层管理者的监管虾忙着分配任务和验收结果,而作为大头兵的牛马虾快乐小狗般地研究是巧克力味儿的屎好还是屎味儿的巧克力好,最后把监管虾看得着急的不要不要的,还不敢和你真实汇报。等你下场去检查的时候,屎山已经高的望不到顶了。这不就是一个活脱脱的赛博职场吗?此时我只想说对你的虾好一点儿,交代任务时加个“请”字,可能比你说他笨更有用些,真的。 旧世界的神(各种差)力量正在减弱,新世界的神(AI)已然崛起 。生产力的跃升总是先行的,随后才是生产关系的重构,当生产力的“安装期”接近尾声时, 生产关系的变革将成为主线 ,此时你的信仰又该何去何从? 技术平权 最后我想再谈一点儿技术平权,感觉“龙虾热”把技术平权又双叒叕一次拿到了台面上。有两个问题,我的观点分别如下: 技术平权好吗?我认为技术平权整体来看是 好的 ,如果技术平权存在的话。技术平权可以让更先进的技术平等的惠及每一个人,整体上会极大的提高生产力。但这也会引发一定的焦虑,当技术稀缺时,焦虑只发生在少数人之间,当它开始民主化后,焦虑会迅速扩散,这在组织推进 AI 落地时需要格外关注。 技术平权存在吗?我认为技术平权 不存在 。上个世纪还在用打孔卡进行编程,高性能计算机的普及依旧没有让编程变成普惠技术。也许你会说技术进步的还不够,看看现在的 Vibe Coding,那我会说 Vibe Coding 真的不错,你真的用了吗?你用它写出来的东西应用在生产环境了吗?厉害的人在 Vibe Coding 中更上层楼,不行的人只是换了一种方式堆屎山。 在这里我并没有为我们这些所谓的“工程师”粉饰门面,也没有打消大家探索新世界积极性的意思。想表达的是在科技洪流中,我们更需要思辨,去伪存真,鸿沟永远存在,找到一条更好提升自己的路,平权不平权不重要,干得过别人才重要。周末读到一篇文章,在此分享出来: ,观点因人而异,但希望可以缓解部分人的焦虑。 最后的最后 最后的最后,改编一下我比较喜欢的胡适先生的话「大胆假设,小心求证」,AI 时代的我们可以「积极拥抱(这是态度),审慎思考(这是行为)」。AI 作为生产力终究不能自发地改变现有的生产关系,仍需要人的主观能动性。如果未来有一天硅基生命崛起,彼时的人类又是否会变成如当下的 AI 一样,成为一种“工具”,只不过是一种作为被奴役的稀有的资源般存在的“工具”。我不想这天的到来,至少在我有生之年。 数据来源: 此处有梗,点明一下,来自美国众神:

业余无线电入门

2025/10/25 00:00 · 中文博客 on 范叶亮 | Leo Van

缘起 从军事领域中的通信,到末世题材影视中的通联,再到越野中的车队通话,都让我对「无线电」这项技术感到高级和炫酷。可能在更多人的眼中无线电或是《永不消逝的电波》中发报机,亦或是保安大哥手中的对讲机。当你深入去了解的时候会发现,这东西不会那么遥不可及,当然也没有想象中那么简单,差评君的一期视频可以带你更好的了解什么是无线电。 Bilibili YouTube 那么什么又是业余无线电?莫非我们只配玩儿些不专业的东西?这里所说的“业余”并非技术角度的专业和不专业,而是指业余业务。业余无线电可以简单的理解为提供给我们这些业余爱好者使用的无线电。业余无线电的英文为 Amateur Radio,业余无线电爱好者称为 Radio Amateur,世界上也普遍称之为 HAM,所以“火腿”也就成为了业余无线电爱好者的代名词。 考试 想要合法合规的进行业余无线电操作,首先需要通过业余无线电台操作技术能力验证,类似开车一样你需要先考一个驾照。业务无线电台操作技术能力验证有不同等级,A 类、B 类和 C 类的区别如下: 操作类型 适用范围 A 类 可以申请设置、使用工作在 30-3000MHz 频段且最大发射功率不大于 25 瓦的业余无线电台。 B 类 可以申请设置、使用工作在 30MHz 以下频段且最大发射功率小于 15 瓦, 或者工作在 30MHz 以上频段且最大发射功率不大于 25 瓦的业余无线电台。 C 类 可以申请设置、使用工作在 30MHz 以下频段且最大发射功率小于 1000 瓦, 或者工作在 30MHz 以上频段且最大发射功率不大于 25 瓦的业余无线电台。 申请人初次申请业余无线电台操作技术能力考核,须首先参加 A 类业余无线电台操作技术能力考试。取得 A 类操作证书六个月后可以申请参加 B 类操作技术能力考试。取得 B 类操作证书并且设置 B 类业余无线电台二年后,可以申请参加 C 类操作技术能力考试。 不同于考驾照,业务无线电台操作技术能力验证仅有理论考试,各地的考试报名方式不尽相同,更多的考试细节和题库可以参考 。通过考试后,就可以收到业务无线电台操作技术能力验证证书了。 设备 拿到操作证书后,你就可以选择一台心怡的设备了,买完设备后你还需要去验机。这里最重要的一点就是你购买的设备型号必须有国家颁发的核准代码,没有核准代码的设备是无法通过验机的。 针对新手小白的对讲机选购可以参考下面这个视频,只能说没有最好的,从价格、性能、颜值等角度选择适合自己的就好。 Bilibili 我最终选择的是「如意通 6900 DMR」双模对讲机。之所以选择它是早些时间有了解到有 MMDVM 盒子这么一个东西,也想着入坑玩一下,所以就选择了一款有数字模式的对讲机。验机完毕后,就会收到一张中华人民共和国无线电台执照。 相比操作证书,无线电台执照简陋了不少,就是一张纸,所以可以去淘宝买一个保护套装上。此时你就得到了正式的呼号,现在就可以打开对讲机,开始你的第一次联通了: CQ, CQ, CQ, this is BD1CZP. BRAVO, DELTA, ONE, CHARLIE, ZULU, PAPA. BRAVO, DELTA, ONE, CHARLIE, ZULU, PAPA. Calling CQ and standing by. CQ,CQ,CQ,这里是 BD1CZP。BRAVO,DELTA,ONE,CHARLIE,ZULU,PAPA。BRAVO,DELTA,ONE,CHARLIE,ZULU,PAPA。呼叫 CQ 并等待回答。 我的呼号是 BD1CZP 。翻阅了下资料,我国的呼号由 4 部分构成: 第一位的 B 代表中国。 第二位表示电台种类,A、D、G、H、I 代表业余电台,J 代表业余信标台和卫星业余电台,R 代表业余中继台。 第三位表示地区: 1:北京、卫星业余业务 2:黑龙江、辽宁、吉林 3: 天津、河北、内蒙古、山西 4: 上海、山东、江苏 5: 浙江、江西、福建 6: 安徽、河南、湖北 7: 湖南、广东、广西、海南 8: 四川、重庆、贵州、云南 9: 陕西、甘肃、宁夏、青海 0:新疆、西藏 后续几位则为分配的后缀。 报完呼号后为啥又来了 BRAVO, DELTA, ONE, CHARLIE, ZULU, PAPA 这么一段?这是因为为了避免在信号传播过程受到干扰导致失真或衰减,使得对一些字母的听辨产生困难,在通信中会使用 字母解释法 复述呼号。 字母解释法 除了标准解释以外,有时候也会使用其他单词替代: 字母 标准解释 其他解释 A ALFA AMERICA B BRAVO BOSTON C CHARLIE CANADA D DELTA DENMARK E ECHO ENGLAND F FOXTROT FLORIDA G GOLF GERMANY H HOTEL HONOLULU I INDIA ITALY J JULIETT JAPAN K KILO KILOWATT L LIMA LONDON M MIKE MEXICO N NOVEMBER NORWAY O OSCAR ONTARIO P PAPA PETER Q QUEBEC QUEEN R ROMEO RADIO S SIERRA SUGAR T TANGO TOKYO U UNIFORM UNITED V VICTOR VIRGINIA W WHISKEY WASHINGTON X X-RAY Y YANKEE YOKOHAMA Z ZULU ZANZIBAR QSL QSL 在通信用的 Q 简语中是“收妥了”“给收据”的意思。QSL 卡片是业余电台特有的一种确认联络或收听的凭证,每个电台都应该有自己的 QSL 卡片。QSL 卡片一般长为 14-15 厘米,宽为 9-10 厘米,除了必须印有醒目的本台呼号外,还应该包含如下内容: 接收方的呼号。 确认是通联还是收听。 联络的日期和时间。 联络时所用的频率。 联络时所用的模式。 对方的信号情况。 设备情况:型号、功率、天线等。 操作者签名。 设计了一个自己的 QSL 卡片,如有需要源文件可单击下载: & 。 QSL 卡片正面 QSL 卡片反面

重构

2025/10/19 00:00 · 中文博客 on 范叶亮 | Leo Van

十一之前看了 UP 主的 ,最开始只是有感于当前工作中的代码开发,后来又有感于工作和生活,想着记录下来,又担心酸腐味太重就没写。十一回来,玩儿了两天,出了趟差,愈发感觉还是应该记录下,待回头看时至少可供自嘲。 之于代码 视频中讲到了一个“鸿沟理论”,高科技产品在市场营销过程中遭遇的最大障碍就是早期市场和主流市场之间存在的鸿沟,能否顺利的跨越鸿沟进入主流市场成功赢得实用主义者的支持决定了一个产品的成败。还有个“巴斯扩散模型”和这个理论很类似,原来还基于它做过一些预测模型。 鸿沟理论 早期市场中的产品就是我们通常说的 MVP。MVP 最重要的是速度,需要快速在市场中得到验证。所以从风险和收益的角度出发,在 MVP 开发的时候大家会快速地实现产品功能,一些细节(例如代码质量)往往就没那么重要。 这一点我很认同 ,但是这里有个前提是面向市场的产品,在我的工作中,会有不少“就是要做”的事情,一定程度上是“刚需”,做得好做的差都得用。那这个时候大家又会怎么选择呢?我观察到的情况是大部分人还是会选择快速上线,因为要“拿结果”,虽没有市场去评价你,但你的老板会去评价你。 视频中给到的结论是: 任何时候都不适合重构 。经过早期市场的验证,当多个玩家都在拼命渡河赢得主流市场时,如果你慢了就很容易被赢家通吃,所以此时此刻你仍需要同时间赛跑。当终于在主流市场站稳脚跟后是不是真的就可以重构了,答案是依旧不行,因为这个时候已经积累了足够的技术债,重构的成本已经远远高于 MVP 时期。此时在风险和收益之间的人们往往不会为了一个收益不明朗的价值回报去承担一个不小的成本。尤其是在当前的环境下,没有铁饭碗的人不会想着为别人做嫁衣,有铁饭碗的人不会没事儿给自己找麻烦。 我给到的观点是: 任何时候都适合重构 ,而且我认为这并不偏激。重构不一定代表需要大刀阔斧,有些时候你的改动甚至可以其他人都无感,只要对你的后续开发和维护有益,你认同这一点,就有动力去做。如果你没打算在团队长待,或者你就想当个甩手掌柜,亦或是你并非正编,那权当我没说(这三种情况我认为存在且普遍)。当真的需要启动治理需要推翻重来时,我们就需要现实些,此时可能需要更量化的风险披露,更好的上价值,更好的汇报,拉更多的人下水,事情才更容易如你所愿。 重构是有意义的 ,好一句废话,但我还是会时不时的想一想,不想连去做的勇气都不再会有。做多少,何时做,如何做,这里面的“度”每个人的想法就千差万别了,别因为此太过影响自己的绩效,那就尝试做一些,如果你超会上价值,也全当我多虑了。还有一点我认为需要多践行工程师文化,多一些思考,多一些规范,多 Review 一下自己的代码,这些不会太影响和时间赛跑的。我不图未来接手我代码的人夸我写的漂亮,只求不会骂我的代码是屎山。 之于工作 在 中有聊到自己的第二次职业焦虑,一年过去了,焦虑缓解了,但新的问题或者说想法变多了。谈及自己我都会说我是一个风险厌恶的人,这点到现在也没有太变(所以说改变一个人的一些想法真的挺难的),但我对 风险 有了新的认知。一次出差飞机上三个小时听了关于塔勒布的一个播客,还没来得及更深入的去了解,但让我记住了一个词“勇气”。对于工作而言,重构往小了说可以是内部职责的一次调整,往大了说可以是寻求一个新的外部机会,我能找出促使我要去这么做的千万个理由,但确没有太多去这么做的“勇气”。 我会更在意失去的,好比上面说的,风险是确定的(失去的),但收益是不明朗的(确定不会是一个更深的坑)。相比一年前,我最大的改变在于动起来了,确实缓解焦虑最好的方式就是行动起来。我们需要更加 深入 地剖析要不要做出变动,但不应持续地陷入剖析而不自拔。动起来,担心失去就先“小”动起来,不用让人看见(让人看见可能对你也没好处),自我发起的改变也不应是一蹴而就的,多些准备会让你少些担忧。 这段时间刷到短视频上的一句话:听说过上班累死的,没听说过不上班饿死的。我希望可以更加阳光的理解这句话,拼搏奋斗仍应是我们要去追求的,只是说哪怕做错了什么,你又能失去多少呢,相信只要能远离黄赌毒,就不至于把自己玩儿死。 之于生活 最近一年的感觉自己有些腐朽味,四年前的我还能 ,今年的我连近郊都没怎么去,貌似生活也进入了急需重构的阶段。但还不如工作,都还谈不上有没有动力去改变,连想要的生活的样子似乎都有些模糊了。最近看到豆瓣上也可以听播客了,之前都是在苹果自带的 APP 上听(简洁又没广告),但豆瓣推给我的一个播单甚得我意,有点豆瓣书籍和影视年度榜单的味道。随即发了个朋友圈分享了下,一个朋友回复到“这岂不是会天天蹿到你出去玩”,我回复到“出去玩就不听了,出不去才只能听听人家的过过瘾”。这一刻,我有在想是没了出去的勇气,还是连出去的想法都没了? 昨晚在短视频上刷到一个在澳大利亚的华人,记录了一些和当地人的生活日常,去过一次澳大利亚,那种地广人稀的氛围自己还是比较喜欢的。无论是播客还是短视频,难道真的是 ,或许可以从减少些刷短视频开始,立马走出去不现实,但把这两年没怎么读的书补一补还是可以试一试的。 前几天和部门里面年轻的同事聊到大学的专业(怎么就聊到这想不起来了,上了年纪确实记性不好),还能记得管理学老师的一句话:读万卷书不如行万里路,行万里路不如交万名友,交万名友不如名师之路。名师指路可遇不可求,庆幸求学期和工作期间能遇到几位带我的好师傅,行万里路真的可以体验更多(人生百态皆在其中),不过经济性不如读书。真的有好久没有好好的读几本书了,之前可以挑灯夜读,很想搞清楚为什么现在不行了,想了想也没太想明白,也许没那么重要搞清楚,有这时间去读更好些。那天我还说他们这些年轻人正值好时候(回头想想这话有点儿爹味儿),自己已经有些老了,感觉在重构生活的路上,借口多了太多,虽然每个人的情况各不相同,所以到底在害怕失去什么呢?这个答案就留在我完成重构那天再补上吧,希望有这一天,希望这一天不要太晚。

大语言模型微调

2025/08/09 00:00 · 中文博客 on 范叶亮 | Leo Van

什么是微调 微调(Fine-tuning)是深度学习中迁移学习的一种方法,其将现有模型已经学到的知识作为学习新任务的起点。虽然微调表面上是模型训练中使用的一种技术,但它与传统意义上的“训练”截然不同。为了消除歧义,在这种情况下通常将传统意义上的“训练”称为预训练(Pre-training)。 与微调类似的另一个概念称之为后训练(Post-training),两者均发生在预训练之后,其目的也都是为了进一步提升模型的效果,通常两者可以理解为相同的概念。从优化的发起人角度出发:当终端用户希望模型可以更好的适配自己的领域知识,则需要进行的操作称之为微调;当模型开发者希望可以更好的将模型与人类的价值、道德和预期保持一致,则需要进行的操作称之为后训练。 为什么微调 从本质上讲,磨练一个预训练基础模型的能力要比从头开始训练一个新模型更容易,也更省钱,因为预训练已经获得了与当前任务相关的广泛知识。对于具有数百万甚至数十亿个参数的深度学习模型尤其如此,例如在自然语言处理(NLP)领域的大语言模型(LLM)或卷积神经网络(CNN)和视觉转换器(ViT)(用于计算机视觉任务,例如图像分类、对象检测或图像分割等)。 通过迁移学习利用先前的模型训练,微调可以减少获得适合特定用例和业务需求的大模型所需的昂贵算力和标记数据量。例如,微调可用于调整预训练大语言模型的对话语气或预训练图像生成模型的图片样式,还可用于使用专有数据或领域特定的专业知识来补充模型的原始训练数据集。 如何去微调 微调是需要进一步训练模型的技术,模型的权重已经通过先前的预训练得到了更新。使用基础模型的先前知识作为起点,通过在任务特定的较小数据集上进行训练来对模型进行微调。 虽然从理论上讲,任务特定的数据集都可以用于初始训练,但在小数据集上从头开始训练一个大模型可能会存在过拟合的风险:模型可能会在训练示例中学习得到良好的表现,但对新数据的泛化能力却很差。这会导致模型不适合给定的任务,也违背了模型训练的初衷。 因此,微调可以兼具两者的优势:利用对大量数据进行预训练所获得的广泛知识和稳定性,并训练模型对更详细、更具体概念的理解。 微调方法分类 参数角度 从参数角度,我们可以将微调分为全参数微调(Full Fine-tuning)和部分参数微调(Repurposing): 全参数微调 :即对模型的所有参数进行微调。这种微调方法通常适用于任务与预训练模型之间存在较大差异的情况。全参数微调需要耗费较大的计算资源和时间,通常可以获得更好的性能,但在数据不足时容易出现过拟合问题。 部分参数微调 :即仅对模型的部分参数或额外的模型参数进行微调。相比于全参数微调,部分参数微调可以在较少的计算资源和时间的情况下,在一些特定任务上提高模型的性能。 数据角度 从数据角度,我们可以将微调分为监督微调(Supervised Fine-tuning)和无监督微调(Unsupervised Fine-tuning): 监督微调 :在进行微调时使用 有标签 的训练数据集。通过使用这些标签来指导模型的微调,可以使模型更好地适应特定任务。 无监督微调 :在进行微调时使用 无标签 的训练数据集。通过学习数据的内在结构或生成数据来进行微调,以提取有用的特征或改进模型的表示能力。 方式角度 从方式角度,我们可以将微调划分为指令微调(Instruction Fine-tuning)和对齐微调(Alignment Fine-tuning): 指令微调 :利用格式化的实例以有监督的方式微调大语言模型。通过指令微调不仅可以改善模型的性能,同时也可以增强模型的泛化能力。 对齐微调 :为了避免大语言模型的幻觉问题,以及同人类的价值观和偏好对齐,提高伦理表现,将人类整合到模型的训练过程中。例如基于人类对结果的反馈,模型通过强化学习从而与人类对齐。 显存消耗 在进行模型微调时我们需要关注显存的消耗,以确保在当前的硬件环境中可以正常进行微调。在进行模型微调时,显存消耗主要同如下因素有关: 参数精度 :决定了每个参数占用的实际显存大小,例如 FP32(单精度)占用 4 字节,FP16(半精度)占用 2 字节,INT8 占用 1 字节等。 模型参数 :微调所需显存的基础决定因素,例如微调一个 1B 模型,其参数总量则为 10 亿。 梯度 :在微调过程中需要存储反向传播计算得到的梯度信息,这部分大小同模型参数相同,精度同训练精度一致。 优化器状态 :优化器所需的额外信息,例如动量、方差等,不同的优化器占用的显存大小也不尽相同,保守估计为模型参数所需显存的 4 倍。 激活值 :用于储存前向传播过程中的中间结果,所需显存大小主要受到批大小和序列长度的影响,量级相比前面可以忽略不计。 以全参数微调一个 1B 模型为例,所需的显存大致为 12GB(模型参数:2GB,梯度:2GB,优化器状态:8GB)。在使用部分参数微调时,模型参数本身不变,需要微调的参数会大幅度减少,因此梯度和优化器状态所需的显存也会大幅度减少。在应用一些量化技术后,例如使用 INT8 精度进行微调,则所有部分的显存占用均会相应的减少。 参数高效微调 参数高效微调部分主要参考了 项目。 参数高效微调(Parameter-Efficient Fine-Tuning)是指固定大部分预训练模型的参数,仅微调少量或额外的模型参数的微调方法,从而可以极大的降低计算成本。参数高效微调可以从方法的角度可以分为三类 :引入新参数(Addition-based),微调部分参数(Selection-based)和重参数化(Reparametrization-based),其中引入新参数又可以划分为适配器方法和软提示方法两种。 参数高效微调方法分类 在实战过程中我们可以使用 Huggingface 开源的 扩展库进行参数高效微调,作为 Huggingface 开源项目其可以与 , 和 等多个开源库无缝衔接使用。在官方文档中我们可以查看支持的 和 。 Prefix Tuning Prefix Tuning 是在输入的 token 前构造与任务相关的 virtual token 作为前缀,在微调的时候仅更新前缀部分的参数。 针对不同的模型结构,构造的前缀也有所不同: 自回归结构 :添加前缀后,得到 $z = \left[\text{PREFIX}; x; y\right]$。 编码器-解码器结构 :在编码器和解码器前均添加前缀,得到 $z = \left[\text{PREFIX}; x; \text{PREFIX}’; y\right]$。 作者发现直接更新前缀的参数会导致训练不稳定,因此在前缀之前添加了 MLP 结构,在训练完成后 MLP 部分的参数无需保留,仅保留前缀的参数即可。同时作者也针对前缀使用多少个 virtual token 以及前缀放置的位置对于微调的性能影响进行了相关实验,细节请参考论文原文。 Prompt Tuning Prompt Tuning 可以看作是 Prefix Tuning 的简化版本,其为每个任务定义不同的 Prompt,然后拼接到数据上作为输入。 Prompt Tuning 仅在输入层添加 token,不需要像 Prefix Tuning 那样添加 MLP 结构解决训练问题。通过实验发现,随着模型参数的增加,Prompt Tuning 的效果会逼近全参数微调的效果。 实验还发现,与随机和使用样本词汇表的初始化相比,采用类标签初始化的微调效果更好,但随着模型参数的增加,效果差异会消失。同时 Prompt 的 token 长度在 20 左右可以获得不错的效果,同样随着模型参数的增加,token 长度带来的增益会消失。 P-Tuning P-Tuning 将 Prompt 转换为可学习的 Embedding 层,再通过 MLP+LSTM 结构对 Prompt Embedding 进行处理。 对比 Prefix Tuning,P-Tuning 增加了可微的 virtual token,但仅作用于输入层,没有在每一层都添加。同时,virtual token 的位置也不一定是前缀,其插入的位置是可选的,目的是将传统人工设计的 Prompt 模板中的真实 token 替换为可微的 virtual token。 实验发现随机初始化 virtual token 容易陷入局部最优,因此通过一个 Prompt Encoder(即 MLP+LSTM 结构)对其进行编码可以获得更好的效果。 P-Tuning v2 Prompt Tuning 和 P-Tuning 存在如下问题: 缺乏规模通用性 :Prompt Tuning 在模型超过 100 亿时可以与全量微调媲美,但对于较小参数的模型与全量微调的效果有很大的差距。 缺乏任务普遍性 :Prompt Tuning 和 P-Tuning 在一些 NLU 基准测试中表现出优势,但对序列标注任务的有效性尚未得到验证。 缺少深度提示优化 :在 Prompt Tuning 和 P-Tuning 中,提示仅被插入到输入中,后续插入提示位置的嵌入是通过之前层计算得到。这可能导致插入提示对模型最终效果的影响有限,同时由于序列长度限制可调参数的数量也是有限的。 考虑到上述问题,P-Tuning v2 利用深度提示优化(例如:Prefix Tuning)对 Prompt Tuning 和 P-Tuning 进行改进,类似 Prefix Tuning,其在每一层都加入了 Prompt token 作为输入。 P-Tuning v2 还通过移除重参数化编码器、针对不同任务采用不同提示词长度、引入多任务学习、使用传统分类标签范式等方法进行模型改进。实验表明 P-Tuning v2 可以在不同规模和不同任务中实现与全量微调相媲美的效果。 Adapter Tuning Adapter Tuning 设计了一个 Adapter 模块,并在每个 Transformer 层中插入两个 Adapter 模块,在微调时仅更新增加的 Adapter 模块和 Layer Norm 层中的参数。 Adapter 模块由两个前馈层和一个非线性层组成。第一个前馈层将 Transformer 的输入从 $d$ 维(高维)映射到 $m$ 维(低维),其中 $m \ll d$。通过控制 $m$ 的大小可以限制 Adapter 模块的参数量。中间通过非线性层后,第二个前馈层再将 $m$ 维映射回 $d$ 维作为 Adapter 模块的输出。同时通过 Skip Connection 将 Adapter 的输入也添加到 Adapter 的输出中,这样可以保证即便 Adapter 最开始的参数值接近 0,通过 Skip Connection 的设置也可以保证训练的有效性。 LoRA 神经网络包含很多全连接层,其通过矩阵乘法实现。很多全连接层的权重矩阵是满秩的,针对特定任务微调后,模型的权重矩阵其实具有很低的本征秩(intrinsic rank),因此将参数矩阵投影到更小的空间仍可以得到有效的学习。LoRA 的核心思想就是通过低秩分解降低特征矩阵的参数量,从而以较小的参数量来实现大模型的间接训练。 在涉及到矩阵相乘的模块中,在其旁边增加一个新的通路,通过第一个矩阵 $A$ 将维度从 $d$ 降至 $r$,在通过一个矩阵 $B$ 将维度从 $r$ 升回 $d$,其中 $r \ll d$。 在微调时,仅更新上述两个矩阵的参数,再将两条通路的结果相加作为最终的结果,即 $h = W_0 x + B A x$。训练时矩阵 $A$ 通过高斯函数初始化,矩阵 $B$ 初始化为零矩阵,这样训练开始时 $B A = 0$,从而可以确保新的通路对模型的结果没有影响。 在 Attention 模块中,权重矩阵包括用于计算 Q,K,V 的 $W_q$,$W_k$,$W_v$ 以及多头注意力的 $W_o$,实验表明保证权重矩阵的种类数量比增加秩 $r$ 的大小更为重要,通常情况下 $r$ 选择 4,8,16 即可。 IA3 IA3 不同于 LoRA 学习低秩权重,而是通过学习向量($l_k$,$l_v$,$l_{ff}$)对模型的部分参数进行加权实现对一些激活层的抑制或放大,同时优化损失函数以适应少样本学习。 Huyen, Chip. AI Engineering: Building Applications with Foundation Models. O’Reilly Media, Incorporated, 2024. Lialin, Vladislav, Vijeta Deshpande, and Anna Rumshisky. “Scaling down to scale up: A guide to parameter-efficient fine-tuning.” arXiv preprint arXiv:2303.15647 (2023). Li, Xiang Lisa, and Percy Liang. “Prefix-tuning: Optimizing continuous prompts for generation.” arXiv preprint arXiv:2101.00190 (2021). Lester, Brian, Rami Al-Rfou, and Noah Constant. “The power of scale for parameter-efficient prompt tuning.” arXiv preprint arXiv:2104.08691 (2021). Liu, Xiao, et al. “GPT Understands, Too.” arXiv preprint arXiv:2103.10385 (2021). Liu, Xiao, et al. “P-tuning v2: Prompt tuning can be comparable to fine-tuning universally across scales and tasks.” arXiv preprint arXiv:2110.07602 (2021). Houlsby, Neil, et al. “Parameter-efficient transfer learning for NLP.” International conference on machine learning . PMLR, 2019. Hu, Edward J., et al. “Lora: Low-rank adaptation of large language models.” ICLR 1.2 (2022): 3. Liu, Haokun, et al. “Few-shot parameter-efficient fine-tuning is better and cheaper than in-context learning.” Advances in Neural Information Processing Systems 35 (2022): 1950-1965.

提升图片分辨率和质量

2025/07/05 00:00 · 中文博客 on 范叶亮 | Leo Van

本节将介绍如何将一张低分辨率的图片转换成一张高分辨率高质量的图片。 Bilibili YouTube 为了对比提升分辨率后的图片质量,我们先下载一张原始的高清图片 ,通过 ImageMagick 命令将其转换为一个低分辨率低质量的图片,未来基于这张转换后的图片进行分辨率和质量的提升,再与原始图片进行对比验证提升的效果。 magick toucan-raw.jpg -resize 512x -quality 10 toucan-low-res.jpg 原始图片 低分辨率图片 基础操作 单击左侧 按钮进入 Upscaling 界面,将上面生成的低分辨率图片拖入 Assets 中,之后再拖入到 Upscale 面板的图片区域。 基础操作 安装的 SDXL 模型包中包含一个 SwinIR 分辨率提升模型。选择该模型并添加如下的正向和负向提示词: 正向提示词 a vibrant bird, detailed, a high contrast, inviting warmth, sunlit elements, dynamic composition, 35mm lens, 1/2.8, environmental context, detailed har photography 负向提示词 blurry, out of focus, over saturated, text+++ 将 Creativity 和 Structure 保持默认值 0 ,单击 按钮生成图片。生成完毕后在 Assets 中的低分辨图片上右键,单击 按钮选择进行对比,单击 Images 选项卡回到新生成的图片页面查看对比效果。 对比图片 从如下的对比中可以看出,生成的图片具有更多的细节,这样我们就可以在更高的分辨率下获得更加清晰锐利的图像。 单击画布上方的 Exit Compare 退出对比,在生成的图片上右键,单击 按钮可以在新窗口中打开图片,之后则可以使用鼠标进行放大来观察图片细节。 进阶操作 除了基础的分辨率提升以外,还有一些高级选项可以用来控制分辨率提升后的图片与原始图片的相似程度以及在提升分辨率过程中的创意性。 Creativity 参数用于设置提示词控制图像生成的创意性,从而控制与原始图像的差异程度,值越大表示越具有创意性。 Structure 参数用于确保分辨率提升过程中图像中的元素与原始图像中的元素的形状和位置匹配,值越大表示越会严格遵守原始图片的结构。 Upscale 同时也可以调整生成的模型及其相关参数,例如: Scheduler 和 CFG Scale 等。 风格调整 如果在提升分辨率的过程中还希望调整图片的风格,你可以尝试使用不同的提示词,例如下面是一个绘画风格的提示词: a painting of a vibrant bird, oil painting, deep impasto, glazed brushstrokes 我们适当增加 Creativity 的值到 8 ,减少 Structure 的值到 -4 ,这样可以给到模型更多的自由度重新构思一些细节。最后我们来综合对比原始图片、低分辨率图片、提升分辨率后的图片以及调整风格的图片: 至此,我们 Invoke AI 101 系列的 6 节课程就全部结束了,希望大家能够通过这 6 节课程对 Invoke AI 的功能有一个基础的认知。也期待大家能够进一步探索 Invoke AI 的高级功能,去创造更多自己喜欢的图片。 原始图片 低分辨率图片 提升分辨率图片 提升分辨率图片(风格调整) 图片来源:

使用画布创建和组合生成新的图片

2025/06/28 00:00 · 中文博客 on 范叶亮 | Leo Van

本节将介绍在使用画布进行创建和组合生成新的图片的过程中使用到的核心工具。 Bilibili YouTube 首先,我们使用 Juggernaut XL v9 模型和如下提示词生成一张基础图片留作备用: 基础图片 提示词模板 : Environment Art 正向提示词 : futuristic terraced structure built into a mountain at dusk, twilight hues, lush greenery illuminated by soft glowing lights, multiple levels, pathways, vast mountain range, distant winding roads, glowing city lights below, towering otherworldly rock formations 为了保证可复现性,在生成这张图片时可以将随机数种子 Seed 固定,此处设置为 42 。 边界框 将生成的图片拖入画布并创建一个新的 Raster Layer。在画布上单击 Bbox 按钮,此时图片的周围将显示一个边界框,使用鼠标按住可以拖动边界框的位置,放在边界框的四角可以调整边界框的大小。 将边界框移动到画布的一个完全空白的区域,此时边界框中没有任何 Raster Layer 的内容,单击 会生成一张新的图片。 生成前 生成后 将边界框移动到画布的一个包含部分 Raster Layer 内容的区域,单击 会将空白的部分补全,通常称之为 Out Painting 或 Infilling。 生成前 生成后 如果边界框和 Raster Layer 完全重合,单击 将会基于当前 Raster Layer 中的内容重新生成新的图片,通常称之为图像到图像(Image2Image)。 修复蒙版 修复蒙版(Inpaint Mask)用于控制在边界框中哪些区域会被修改。在图层中单击 + 新建一个 Inpaint Mask 图层。单击画布上的 按钮后,则可以在画布上绘制所需要修改的区域。 修复蒙版 此时可以将边界框进行缩放并移动到关注的指定区域。从左侧的 Image 面板中可以看到边界框的大小为 320x320 。 边界框缩放 但在图片生成过程中,仍然会以 1024x1024 分辨率进行生成,再通过缩放填充到边界框中。由于先生成了分辨率更高的图片,再进行的缩放,此时生成的部分可以具有更多的细节。这使得我们可以在不牺牲图片质量的前提下,对于图片的复杂区域进行优化。 修复蒙版可以让我们很方便的在图片中添加、移除和改变元素。例如,我们希望在楼梯台阶上添加两个人,可以按照如下步骤进行操作: 将边界框调整到一个合适的大小和位置。 创建一个 Inpaint Mask 图层,使用画笔勾勒出需要修改的区域。 返回 Raster Layer,选择一个颜色,使用画笔勾勒出两个人的大概位置。 在提示词的前面添加 two people 。 选择一个合适的 Denoising Strength,此处设置为 0.7 ,单击 按钮启动生成。 生成前 生成后 可以看出,在修复蒙版区域内,根据 Raster Layer 的修改和提示词的修改成功的在台阶上添加了两个人。

探索 AI 模型和概念适配器

2025/06/20 00:00 · 中文博客 on 范叶亮 | Leo Van

本节将介绍图片生成使用到的 AI 模型和概念适配器,我们将讨论提示词和模型的训练方式是如何最终决定提示词对生成图片的有效性。 Bilibili YouTube 在图片生成过程中你需要认识到提示词并非在任何时候都是有效的。相同的提示词在一个模型上可以获得很好的生成效果,但在另一个模型上可能无法生成所需的图片。这是由于模型训练所使用的图片和图片的标注文本不同所导致的,因此模型的提示词指南会格外重要。这也是为什么训练自己的模型会更好,因为你完全清楚在训练模型时所使用的标注文本。 在本节教程中我们不会讨论如何训练模型,我们将重点介绍不同模型之间的差异,展示它们如何影响图片生成的过程。除此之外我们还会讨论概念适配器(通常也称为 LoRA),来帮助你更好的理解相关工具。 模型比较 进入模型管理页面,在添加模型选项卡处选择 HuggingFace ,输入 cagliostrolab/animagine-xl-4.0 下载 Animagine XL 4.0 模型。Animagine XL 模型与其他的通用模型有很大的不同,Animagine XL 模型是一个动漫主题的 SDXL 微调模型。Animagine XL 4.0 基于 Stable Diffusion XL 1.0 进行重新训练所得,它使用了 840 万张不同来源不同动漫风格的图片进行微调。 Animagine XL 模型使用了一套自有的数据标注方法进行训练,提示词指南如下图所示: Animagine 提示词指南 整个提示词包含 6 个部分: 性别。例如: 1girl/1boy/1other 。 角色。例如: remilia scarlet 。 来源作品。例如: touhou 。 分级。例如: safe, sensitive, nsfw, explicit 。 一般标签。 质量标签。例如: masterpiece, high score, great score, absurdres 。 建议的负向提示词如下: lowres, bad anatomy, bad hands, text, error, missing finger, extra digits, fewer digits, cropped, worst quality, low quality, low score, bad score, average score, signature, watermark, username, blurry Animagine XL 模型支持一些特殊的标签用于控制图片生成。质量标签直接影响生成图像的整体质量和细节水平。可用的质量标签有: masterpiece,best quality,low quality,worst quality 。 masterpiece, best quality low quality, worst quality 与质量标签相比,分数标签可以对图像质量进行更细致的控制。在 Animagine XL 模型中,它们对输出质量的影响更大。可用的分数标签有: high score,great score,good score,average score,bad score,low score 。 high score, great score bad score, low score 时间标签允许根据特定时间段或年份来控制生成图片的艺术风格。这对于生成具有特定时代艺术特征的图像非常有用。支持的年份标签有: year 2005,year {n},year 2025 。 year 2007 year 2023 利用如下正向和负向提示词分别使用 Animagine XL 4.0 模型和 Juggernaut XL v9 模型生成图片。 正向提示词 1boy, black hoodie, white spiky punk hair, nose piercing, standing against a brick wall, masterpiece, best quality, high score, great score 负向提示词 lowres, bad anatomy, bad hands, text, error, missing finger, extra digits, fewer digits, cropped, worst quality, low quality, low score, bad score, average score, signature, watermark, username, blurry 同时,为了比较提示词在不同模型中对生成图片的影响,再利用如下正向和负向提示词分别使用 Animagine XL 4.0 模型和 Juggernaut XL v9 模型生成图片。 正向提示词 1boy, black hoodie, white spiky punk hair, nose piercing, standing against a brick wall 负向提示词 lowres, bad anatomy, bad hands, text, error, missing finger, extra digits, fewer digits, cropped, signature, watermark, username, blurry 为了确保可复现,手动将随机数种子固定设置为 42 ,生成的图片如下: Animagine XL 4.0 Juggernaut XL v9 Animagine XL 4.0 (删除部分提示词) Juggernaut XL v9 (删除部分提示词) 不难看出,从正向和负向提示词中删除关于图片质量的关键词后,Animagine XL 4.0 模型生成的图片有显著的画质降低,而 Juggernaut XL v9 模型生成的图片质量变化并不大。实验说明提示词在不同的模型中效果存在差异,你必须了解模型的训练过程才能更好的使用提示词生成所需的图片。 概念适配器 上述问题就导致了概念适配器的诞生,通过自己训练概念适配器,你可以完全掌握对于模型的修改。进入模型管理页面,在添加模型选项卡处选择 HuggingFace ,输入 nerijs/pixel-art-xl 下载 Pixel Art XL 概念适配器。利用如下正向和负向提示词分别使用 Animagine XL 4.0 模型和 Juggernaut XL v9 模型生成图片。 正向提示词 1boy, black hoodie, white spiky punk hair, nose piercing, standing against a brick wall, masterpiece, best quality, high score, great score, pixel art style 负向提示词 lowres, bad anatomy, bad hands, text, error, missing finger, extra digits, fewer digits, cropped, worst quality, low quality, low score, bad score, average score, signature, watermark, username, blurry 在 Generation 中添加概念适配器 pixel-art-xl 并启用: 概念适配器 Pixel Art XL 概念适配器用于生成像素风格的图片,生成的图片如下: Animagine XL 4.0 (Pixel Art XL) Juggernaut XL v9 (Pixel Art XL) 需要注意,LoRA 这类概念适配器与用于训练的原始模型之间存在关联。概念适配器可以理解为一个模型的上层封装,其扩展和增强了某些概念。将其放在另一个模型上,其仍可以将这个概念应用到新的模型上,但质量可能会有所下降。这是因为训练概念适配器的底层模型与当前应用的模型可能有着不同的架构和假设。也就是说 LoRA 这类模型并不是一个完全独立的模型,而是一个专门为某个基础模型构建的适配器,但如果两个模型本质上非常相似,则 LoRA 具有一定的可移植性。

理解图像到图像和降噪过程

2025/06/14 00:00 · 中文博客 on 范叶亮 | Leo Van

本节将介绍「 」和「降噪」两个重要概念,帮助大家更好的理解 Invoke 中的画布是如何工作的,或者说生成式 AI 图片生成是如何工作的。 Bilibili YouTube 在之前的图像生成示例中,单击 按钮后,整个图像生成过程会从一张静态噪声图像开始,模型会将噪声逐步转化为最终图片,整个过程如下图所示: 将噪声图像转化成最终图片的过程称之为降噪(Denoising)。 将示例图片拖拽至画布上,选择 New Raster Layer,示例图片如下 : 示例图片 在图层中,可以找到 Denosing Strength 参数: Denoising Strength Denosing Strength 用于控制初始图片或 Raster Layer 在降噪过程中影响最终输出图片的程度。设置较高的值会使降噪过程从一个具有更多噪声数据的图片开始,此时模型会具有更高的自由度根据提示词生成新的内容。 图像到图像和文本到图像的最主要区别在于图像生成的起点。文本到图像时从纯噪声开始,并根据提示词逐步细化。图像到图像则会根据 Denosing Strength 跳过前面的一些步骤,使用提供的图像作为起点。 以 a porcelain teacup on a table 作为提示词,选择 Photography (General) 作为提示词模板,分别将 Denosing Strength 设置为 0.2 和 0.8,生成的图片和原始图片对比如下: 原始图片 低 Denosing Strength 高 Denosing Strength 可以看出,较高 Denosing Strength 值可以让模型具有更高的自由度生成图片,而设置较低的 Denosing Strength 值时生成的图片仅有少量的变化。除此之外,在控制层和参考图片上也可以设置 Denosing Strength 来取得不同的效果。

使用控制层和指示控制图片的生成

2025/06/07 00:00 · 中文博客 on 范叶亮 | Leo Van

本节将介绍如何使用控制层和指示来精确控制图片的生成。 Bilibili YouTube 控制网络 控制层通常用作控制网络( )在图片生成中以线或结构的形式来提供参考。在 SDXL 中,常用的预训练控制网络有 : Contour Detection (scribble) Scribble 模型可以根据输入的图片生成线条画,处理后的图片作为原始图片的简化版本可以精准的捕捉图片的轮廓。 输入 分析 生成 Depth Map Depth Map 可以生成图片的深度图,在图片生成中模拟深度效果,从而创建更加逼真的 3D 图片。 输入 分析 生成 Hard Edge Detection (canny) Canny 边缘检测的原理是通过寻找强度突变来识别图片中的边缘。它能够准确的检测边缘并减少噪声和伪边缘,通过降低阈值可以识别更多的信息。采用 Canny 模型时,将会生成与检测到的边缘匹配的图片。 输入 分析 生成 Pose Detection (openpose) Openpose 模型可以检测身体、手部、面部等多个部位的关键点,在生成图片时可以控制人体的姿态。 输入 分析 生成 Soft Edge Detection (softedge) Softedge 模型与 Scribble 模型类似,处理后的图片作为原始图片的简化版本仅保留形状的柔和边缘和一些浅阴影。 Tile Tile 模型的主要功能可以归结为如下两点: 可以重新解读图片中的特定细节,并创建全新的元素。 当全局指令与图片的局部或特定部分存在差异时,可以忽略这些指令。在这种情况下,它可以使用局部上下文指示图片生成。 Tile 模型可以作为增强图片质量和细节的工具。如果在图片中存在一些不足的地方,例如调整图片大小导致的模糊,Tile 模型可以有效的消除此类问题从而获得更加清晰锐利的图片。此外 Tile 模型还可以添加更多细节,从而提升图片的整体质量。 控制层 在图层中单击 + Control Layer 添加控制层,或者在图片库中将图片拖拽至画布上,选择 New Control Layer 。 创建控制层 示例图片及其生成的提示词如下: 示例图片 正向提示词 : futuristic terraced structure built into a mountain at dusk, twilight hues, lush greenery illuminated by soft glowing lights, multiple levels, pathways, vast mountain range, distant winding roads, glowing city lights below, towering otherworldly rock formations, dreamy sky with soft clouds 负向提示词 : painting, digital art, sketch, blurry 控制层 本教程以 Hard Edge Detection (canny) 模型为例,单击 Filter 中的 Advanced 可以进行更多的调整: Canny Filter - Default Canny Filter - Advanced 调整完毕各项参数后,单击 Apply 即可生成控制图片。 控制图片 控制图片提供的线条可以为图片生成提供参考。在画布中,可以使用 、 和 等工具对控制图片进行添加或删除等微调操作。接下来对控制层进行设置: Weight :用于设置控制图层在图片生成过程中的权重,值越大则图片生成时越会严格遵守控制线条。 Begin/End % :用于设置在图片生成过程中在何时使用控制图层,将其设置为 0% 至 100% 表示从图片生成开始至结束一直使用控制图层。调整开始和结束的百分比可以给到模型更多的灵活性,从而获得更好的生成图片。 Control Mode :包含多种控制模式用于调节控制层的相关性( ): Balanced :提示词和控制层同等重要。 Prompt :提示词更加重要。 Control :控制层更加重要。 不同的 Control Mode 的生成示例如下 : 输入 Balanced Prompt Control 单击 开始生成图片。此时可以看到模型在控制线条的指示下开始生成图片。 生成图片 由于将结束百分比设置为了 70%,生成的图片也具有一定的灵活创意。单击 会将生成的图片添加到 Raster Layer 。单击 可以将画布保存到图片库中。新生成的图片和用于生成控制层的图片对比如下: 新生成的图片 生成控制层的图片 参考图片 接下来我们将添加一个参考图片,也称为 。模型会根据参考图片的风格和结构来生成图片。首先将参考图片添加到图片库,本教程中使用的图片如下 : 参考图片 将图片拖拽至左侧 Reference Image 上。 创建参考图片 在左侧将会创建一个 Reference Image ,并可以对其进行相关设置。 Global Reference Image 模型:在安装 SDXL 相关模型的情况下,选择 Standard Reference (IP Adapter ViT-H) 模型,这里可以选择 ViT-H 、 ViT-G 和 ViT-L 多种变种。 Mode : Style and Composition 表示参考样式和结构, Style 表示仅参考样式, Composition 表示仅参考结构。 Weight :类比控制层。 Begin/End % :类比控制层。 在本教程中,将参考图片的 Weight 设置为 0.7,将结束百分比设置为 70%,从而给到模型更多的自由度。删除之前生成的 Raster Layer ,单击 开始生成图片。应用参考图片生成的图片和之前生成的图片对比如下: 应用参考图片生成的图片 之前生成的图片 可以看出新生成的图片在遵循控制层的前提下同时应用了参考图片的白色风格。 局部指示 在新生成的图片中,可以看到左侧背景中的山峰也被应用了参考图片中的建筑风格。为了实现更精确的控制,可以选择局部参考图片,将图片拖拽至画布上,选择 New Regional Reference Image 。 创建局部参考图片 在画布上选择 ,设置合适的笔刷宽度,在画布上勾勒出需要应用参考的区域,这里我们仅勾勒出建筑所在的区域。 勾勒需要应用参考的区域 单击 开始生成图片。应用局部参考图片生成的图片和应用参考图片生成的图片对比如下: 应用局部参考图片生成的图片 应用参考图片生成的图片 可以看出新生成的图片仅在勾勒的区域内与参考图片的白色风格保持了一致,背后的山峰仍根据提示词生成相应的风格。 基于文本的指示 除了基于图片的指示以外,还可以创建基于文本的局部指示。在图层中单击 + ,选择 Reginal Guidance 创建局部指示。在画布上选择 ,设置合适的笔刷宽度,在画布上勾勒出需要应用参考的区域,这里我们勾勒出建筑后面的一座山峰。在 Reginal Guidance 中选择 + Prompt 并添加 lush greenery 提示词。 创建局部文本指示 单击 开始生成图片。应用局部基于文本的指示的图片和应用局部参考图片生成的图片对比如下: 应用局部基于文本的指示的图片 应用局部参考图片生成的图片 可以看出新生成的图片在勾勒的山峰区域增加了郁郁葱葱的树木。

使用 Invoke 创作你的第一张图片

2025/06/01 00:00 · 中文博客 on 范叶亮 | Leo Van

本节将展示如何使用 Invoke 创作你的第一张图片。 Bilibili YouTube 安装 Invoke 从 下载对应系统的安装包,根据如下步骤完成安装。 运行 Invoke 社区版本,单击 开始安装。 选择安装位置,单击 进行下一步。 选择安装版本,单击 进行下一步。 确认 GPU 情况,单击 进行下一步。 确认安装选项,单击 开始安装。 安装完成,单击 关闭安装向导。 安装完成后,单击 启动 Invoke。 用户界面 Invoke 启动后会打开主界面,从启动器的日志不难看出,Invoke 在后台启动了一个 HTTP 服务,用浏览器打开 http://127.0.0.1:9090 可以得到相同的界面: 主界面包含三个区域,分别是: 左侧:用于输入提示词、模型选择和参数设置等。 中间:用于显示生成的图片。 右侧:用于显示生成图片的所需的图层和历史生成的图片等。 左侧 提示词 提示词 提示词区域用于输入生成图片提示词。 在下拉菜单中可以选择预设的提示词模板。 在 Prompt 中输入正向提示词,在 中输入负向提示词。 也可以将自定义的提示词添加为模板以方便后续使用。 图像 图像 图像区域用于控制生成图片的比例和大小。 Aspect 用于设置生成图片的宽高比, Width 和 Height 用于设置生成图片的宽高。 用于设置生成图片的随机数种子,设置相同的随机数种子将在相同的条件下得到一致的图片,这在微调的时候会派上用场。 生成 生成 生成区域用于设置模型和相关参数。 Model 用于选择生成图片的模型。 Concepts 用于选择进行微调的 LoRA 模型。 高级选项中可以设置图片生成使用的调度器( )。调度器负责数据采样,包括采样的步骤数( )和提示词相关性( )等。 中间 中间区域 中间区域用于查看和调整生成的图片。在后续教程中将会深度介绍如何使用该区域来优化生成的图片。 在上方选项卡中单击 Canvas 可以打开画布,单击 Image Viewer 可打开图片浏览器。 右侧 图板和图片库 图板和图片库 图板用于组织和管理用户生成的图像,它提供了一种结构化的方式来高效地分类和访问这些图像。 在图片库中,你可以将图片拖拽到画布中来使用。此外,你还可以在图库中共享、下载和删除图片。 图层 图层 图层区域显示了工作区中用于修改图像的所有活动图层。单击右上角的 + 图标即可添加新图层。你可以创建多个图层并对其进行操作和变换,在生成图像之前进行组合使用。 模型 单击左侧面板的 图标打开模型页面。针对新手用户 Invoke 提供了新手模型包,单击 Starter Models 选项卡,可以看到系统提供了 Stable Diffusion 1.5 、 SDXL 和 FLUX 三款模型包。根据官方 和自己的设备性能选择合适的模型包。 Stable Diffusion 1.5 GPU:Nvidia 10xx 或更新,4GB+ 显存 内存:至少 8GB 磁盘:至少 30GB SDXL GPU:Nvidia 20xx 或更新,8GB+ 显存 内存:至少 18GB 磁盘:至少 100GB FLUX GPU:Nvidia 20xx 或更新,10GB+ 显存 内存:至少 32GB 磁盘:至少 200GB 在下载模型前,需在 HuggingFace 的 创建 Token,并将其保存在 Invoke 模型页面的 HuggingFace 选项卡中。本教程选择 SDXL 作为模型包,单击模型包启动下载。模型下载完毕后可以在 Model Manager 中查看已下载的模型。 创作图片 在提示词模板中选择 Environment Art ,在 Prompt 中输入如下提示词: futuristic urban park, neon lighting, raised highways, green spaces, modern architecture 单击模板中的 按钮会开启应用模板后的提示词预览,如下图所示: 模板提示词预览 可以看到,提示词模板在用户输入的提示词基础上添加了更多的正向和负向提示词。在 Generation 中选择 Juggernaut XL v9 作为生成模型。 在左上角 中输入生成图片的数量,单击 开始生成图片。单击左侧面板的 图标打开队列页面,等待中、执行中和已完成的所有任务都将显示在该页面中: 生成的 3 张图片如下所示: 第 1 张 第 2 张 第 3 张 中文测试 为了验证 Juggernaut XL v9 模型对于中文提示词的兼容性,对上述示例和 Environment Art 提示词模板中的提示词整理中英文对照版本如下: 提示词 英文 中文 用户 - 正向 futuristic urban park, neon lighting, raised highways, green spaces, modern architecture 未来城市公园, 霓虹灯, 高架公路, 绿色空间, 现代建筑 模板 - 正向 environment artwork, hyper-realistic digital painting style with cinematic composition, atmospheric, depth and detail, voluminous. textured dry brush 2d media 环境艺术作品, 具有电影构图的超现实数字绘画风格, 大气, 深度和细节, 丰满, 纹理干笔画 2D 媒体 模板 - 负向 photo, distorted, blurry, out of focus. sketch. 照片, 扭曲, 模糊, 失焦, 草图 用户的正向提示词使用中文,选择 Environment Art 提示词模板(即提示词模板使用英文),生成的图片如下: 第 1 张 第 2 张 第 3 张 用户的正向提示词使用中文,不选择提示词模板,将 Environment Art 提示词模板的中文提示词补充到用户的正向和负向提示词后,生成的图片如下: 第 1 张 第 2 张 第 3 张 不难看出虽然图片生成的画质不错,但其并未遵循提示词的指令生成(看起来是将中文提示词作为了画风),因此可以判断 Juggernaut XL v9 模型不具备直接使用中文提示词的能力。

在 OpenWrt 和群晖中自动申请和部署证书

2025/05/25 00:00 · 中文博客 on 范叶亮 | Leo Van

为了在本地局域网环境中摆脱 IP 用上域名(纯属闲来无事瞎鼓捣),购入了 leovan.dev 域名。想着把各种服务都映射到不同的二级域名上,这样就可以不用 IP 和端口了,岂不完美。然,问题这就来了。 acme.sh 域名是在 Cloudflare 上申请的,在 Cloudflare 上使用 部署网站就可以白嫖他家的证书,还能自动帮你续期,比如当前的站点就是使用 Page 进行部署的。但你要是想生成证书下载下来使用,就会很麻烦,因为证书的有效期只有三个月,手动续期再加上各种替换操作就不太方便了。 这时候就要请出我们的 了,除了支持各种桌面和服务器操作系统外,还支持 OpenWrt 路由器系统。 Cloudflare 使用 acme.sh 申请免费证书需要使用 DNS 验证对域名的所有权,本文以 Cloudflare 为例,其它 DNS 请参考 。Cloudflare 支持两种方式,一种是使用 API Token,另一种是使用全局 API Key,这里我们以 API Token 为例。 进入 ,单击 按钮,在 API 令牌模板中选择 编辑区域 DNS ,单击 按钮。在 权限 中添加 区域 - DNS - 编辑 和 区域 - 区域 - 读取 的权限,在 区域资源 中根据你的需求选择对应的 特定区域 ,例如 leovan.dev ,或为了省事选择 所有区域 也可以,如下图所示: 创建 API Token 创建完毕后会生成 Token,将 Token 保存为 CF_Token="xxxxxxxxx" ,注意该 Token 在 Cloudflare 中不会再展示。 之后从 Cloudflare 账户主页进入对应的域名详情页面,在右下角可以找到 API 的区域 ID 和账户 ID 两个代码,如下图所示: 区域 ID 和账户 ID 将区域 ID 保存为 CF_Zone_ID="xxxxxxxxx" ,将账户 ID 保存为 CF_Account_ID="xxxxxxxxx" 。 OpenWrt Opwnert 使用 作为默认的 Web 服务器。正如官网上说的,这是一个轻量极了的 Web 服务器,以至于不支持反向代理。 警告 那就安装一个 Nginx 吧,不是说不行,只是 Nginx 和 uHTTPd 存在冲突,你需要把路由器的 LuCI 也切换到 Nginx 上,麻烦不说,后续如果有更新还有可能又会变回 uHTTPd。自己搞了下,差点登录不进去 Web 页面,遂放弃。 但这不影响我们先把路由器的域名 router.leovan.dev 映射到 192.168.100.1 上先用起来。 acme.sh 通过 系统 - 软件包 或命令行安装 acme.sh 相关软件包: opkg install acme acme-acmesh-dnsapi luci-app-acme luci-i18n-acme-zh-cn luci-ssl-openssl 安装完毕后可以在 服务 菜单下找到 ACME 证书 子菜单,进入后在 ACME 全局配置 中输入 电子邮件帐户 ,勾选 启用调试日志记录 ,如下图所示: ACME 证书 - ACME 全局配置 在 证书配置 中删除默认的配置,在下方输入框中输入配置名称,例如 leovan_dev ,如下图所示: ACME 证书 - 证书配置 单击 按钮打开配置对话框。在 常规设置 中勾选 已启用 ,输入所需的域名,选择验证方式为 DNS ,其它保持默认,如下图所示: ACME 证书 - 证书配置 - 常规设置 在 DNS 质询验证 中选择对应的 DNS API(本文使用 CloudFlare.com ),并将上文中的 CF_Token="xxxxxxxxx" 、 CF_Zone_ID="xxxxxxxxx" 和 CF_Account_ID="xxxxxxxxx" 填写到对应的位置,其它保持默认,如下图所示: ACME 证书 - 证书配置 - DNS 质询验证 在 高级设置 中根据自己的需求选择 密钥长度 (本文使用 ECC 256 位 ),其它保持默认,如下图所示: ACME 证书 - 证书配置 - 高级设置 单击 按钮,并在 ACME 证书 页面单击 按钮。 稍等片刻后,如果运行正常则可以在 证书 中看到对应域名的证书,如下图所示: ACME 证书 - 证书 同时,系统会启动自动续签,在 系统 - 计划任务 中可以看到添加了如下一条记录: 0 0 * * * /etc/init.d/acme renew uHTTPd 通过 系统 - 软件包 或命令行安装 uHTTPd 的管理界面: opkg install luci-app-uhttpd luci-i18n-uhttpd-zh-cn 安装完毕后可以在 服务 菜单下找到 uHTTPd 子菜单,进入后在 MAIN - 常规设置 中添加 HTTPS 监听,如下图所示: uHTTPd - HTTPS 监听 在 HTTPS 证书 中选择上文中生成的证书(本文为 /etc/ssl/acme/leovan.dev.fullchain.crt ),如下图所示: uHTTPd - HTTPS 证书 在 HTTPS 私钥 中选择上文中生成的私钥(本文为 /etc/ssl/acme/leovan.dev.key ),如下图所示: uHTTPd - HTTPS 证书 在 uHTTPd 页面单击 按钮。 在 Cloudflare 中将 router.leovan.dev 解析到 192.168.100.1 上后,分别通过 http://192.168.100.1 、 https://192.168.100.1 和 https://router.leovan.dev 访问路由器,如下图所示: 路由器 - IP 和 域名访问 可以看出通过 router.leovan.dev 域名进行访问已经实现了 HTTPS 安全访问。 群晖 由于在 OpenWrt 上搞 Nginx 有些麻烦,此时此刻,恰巧手里还有一台群晖的 NAS,恰巧群晖默认支持反向代理服务器,这一切的一切不就又双叒叕完美了。 acme.sh 稍显遗憾的是在群晖中没有像 OpenWrt 那样的工具可以直接使用,这里就只能用脚本的方式手搓部署了。首先通过命令行 SSH 登录群晖,并切换到 root 用户: sudo su cd /root 由于群晖没有 crontab,因此需要使用如下命令强制安装,根据实际情况修改命令中的电子邮箱: curl https://get.acme.sh | sh -s email = my@example.com --force 当控制台显示 Install success! 后表示安装成功。进入 /root/.acme.sh 目录,修改 account.conf 文件: cd /root/.acme.sh vi account.conf account.conf 文件示例如下,请根据上文中的内容修改 CF_Token 、 CF_Zone_ID 和 CF_Account_ID 配置项: export CF_Token="xxxxxxxxx" export CF_Zone_ID="xxxxxxxxx" export CF_Account_ID="xxxxxxxxx" LOG_FILE="/root/.acme.sh/acme.sh.log" LOG_LEVEL=1 AUTO_UPGRADE="1" ACCOUNT_EMAIL="my@example.com" UPGRADE_HASH="xxxxxxxxx" 运行如下命令申请证书: ./acme.sh --set-default-ca --server letsencrypt ./acme.sh --issue --dns dns_cf --keylength ec-256 -d leovan.dev -d *.leovan.dev 正常情况下,申请的证书将保存在 /root/.acme.sh/leovan.dev_ecc 目录下。 运行如下命令将证书部署到群晖系统中: export SYNO_USE_TEMP_ADMIN = 1 ./acme.sh --deploy --deploy-hook synology_dsm -d leovan.dev -d *.leovan.dev 此时进入群晖的 控制面板 - 安全性 - 证书 中,可以看到 leovan.dev 证书已经部署到系统中并作为默认证书,如下图所示: 控制面板 - 安全性 - 证书 在群晖中创建计划任务来实现自动更新并部署证书,在 控制面板 - 计划任务 中选择 新建 - 计划的任务 - 用户自定的脚本 。在 常规 中设置 任务名称 ,选择 用户账号 为 root ,如下图所示: 计划任务 - 常规 在 计划 中设置执行的周期,由于 acme.sh 在证书到期前一个月会发起重新申请,因此可以将计划任务周期设置为每周,如下图所示: 计划任务 - 计划 在 任务设置 中设置 用户自定义的脚本 : /root/.acme.sh/acme.sh --cron --home /root/.acme.sh 根据个人需要可以勾选 通过电子邮件发送运行详情 ,如下图所示: 计划任务 - 任务设置 反向代理 在 Cloudflare 中将 nas.leovan.dev 解析到 192.168.100.10 上后,在群晖的 登录门户 - 高级 单击 按钮打开对话框,单击 按钮,根据下图添加配置: 反向代理 分别通过 http://192.168.100.10:500 和 访问群晖,如下图所示: 群晖 - IP 和 域名访问 可以看出通过 nas.leovan.dev 域名进行访问已经实现了 HTTPS 安全访问。 提示 针对局域网其它机器上的 Web 服务,可以先将域名解析到群晖的 IP 上,再利用群晖的反向代理转发到对应机器的 Web 服务上。对于非 Web 服务,将域名直接解析到对应的机器上即可。

凡人歌

2024/09/22 00:00 · 中文博客 on 范叶亮 | Leo Van

最近在没有快进的情况下看完了一部剧《凡人歌》,你说有多好看吗,也不是,只是共鸣多些,剧中的种种都好似在“点”我。这一度让我陷入了第二次职业焦虑,但比第一次职业焦虑(大概 5 年前)会显得没那么严重,没那么慌张。 豆 豆瓣评分 8.7 中国大陆 / 2024 / 导演: 简川訸 / 主演: 殷桃 王骁 章若楠 秦俊杰 张哲华 陈昊宇 该剧讲述了三对30岁、40岁的夫妻或情侣在快节奏的大环境下,被生活围追堵截,努力自救,从而实现各自人生价值的故事。当了五年全职主妇的沈琳(殷桃 饰)遭遇丈夫那伟(王骁 饰)失业,夫妻双双无业,二胎嗷嗷待哺,房贷月月逼近,沈琳回归职场之路频频碰壁之后,选择变身个体户实现再就业;名校毕业的沈磊(秦俊杰 饰),考了公务员,在单位档案科工作,岁月静好,与世无争,妻子谢美蓝(陈昊宇 饰)却因他安于现状与之离婚,沈磊信念崩塌,辞去工作,离家出走;百万年薪的程序员那隽(张哲华 饰)被大厂齿轮裹挟前进,因高强度的工作患了惊恐症,为怕失业拼命掩饰,让以及时行乐为人生态度的女友李晓悦(章若楠 饰)难以理解,彼此相爱的两人渐行渐远。面对各自的人生窘境,他们不控诉不自怜,直面内心,共渡人生危机。 悲观与乐观 我是一个做事比较喜欢先考虑最坏情况的人,或者说是一个对风险敏感的保守型人,我理解这算是一种悲观。但我也乐观,因为我认为只要努力总还是能够进步的,不是对自己的能力由多自信,只是感觉在合适的地方总会有一席用武之地。说好听了这可能是乐观,说不好听了这可能是自我感觉良好,甚至有种逆风而上的狂妄自大。不过实话实说狂妄应该不至于,年纪大了,各种情绪都会收敛很多,会觉得 。为什么聊到悲观和乐观,因为看下来这可能是引起我第二次职业焦虑的根因:对宏观(不够悲观)和微观(过于乐观)的认知偏差。 大学学了七年的管理,两门经济学基础课宏观经济学考的算是所有科目中最烂的,微观经济学到着实不赖。宏观经济学确实会比微观经济学难一些,毕竟有一只 老在调控这儿调控那儿的 。后疫情时代已经有三年左右,经济确实恢复的不理想,这点大家都有目共睹。但可能我仍是一叶障目,背后到底有多少问题可能也只是片面了解。看了付鹏在凤凰湾区财经论坛上的演讲,让我这个没啥宏观认知的人也能清晰地直面市场现状。 还有就是近期在招人,骚扰了很多有段时间(短则个把月,长则一两年)没太联系的前同事。聊下来,感觉能维持现状就算不错的了,还有些是在走下坡路。或许在当前的职位供需下,对大部分人来说可能最好的就是保持不变,对于发生变化的也只有降低个人预期才不至于出现空档。 剧中与剧外 写本文前也简单看了看豆瓣上的剧评,里面有不少提到这里面哪一个都不算是“凡人”。没有错,但剧的背景在北京,再加上编剧可能也会有一些夸张的描述,所以同更多人理解的“凡人”有很大差距,但对于我们这些在一线城市打拼的人来看,距离就没有那么远了。至少就我而言,剧中每个人的好我可能粘不上,但每个人的烦我却都似曾相识。 那伟从买了 50 万的宝马,到被裁员,到最后用宝马换了哈弗是第一个触动我的点。因为我最近也再考虑买车,想买一辆越野车,所以价格上也不算便宜。在我看来,虽然车是一个消费品,但他能够带来的快乐会高于我付出的金钱,我的 就是这样的。有了车至少不会被谢美蓝嫌弃沈磊用小电驴送他上班,不过北京的车牌确实是一个难受的客观因素,摇又摇不中,租又不好租。但那伟后面遭遇的一连串不幸,虽然感觉有点过了,但也确实让我会重新审视多攒些钱早点把房贷还完是不是更好的选择。 那隽是我羡慕的对象,学历好、工作好、房子好、女朋友好。但这些在他女朋友看来可能 ,但我很能理解那隽,因为这些会让他感觉很安全。剧中给到介绍那伟和那隽小时候家庭条件一般,那隽通过自己的努力走到这样一个位置,已经算是相当的成功了。最后没能和李晓悦走到一起倒不是工作和生活的平衡的问题,反到他身体的问题是,我认为他俩的问题在于 的差异过大。在我换到第二份工作之后,体重涨的速度应该超过了我挣钱的速度,Work Life Balance 这个道理谁人不懂呢,但又有哪些人能做到呢。之前会开玩笑的说:“若不是生活所迫,谁愿意把自己搞得一身才华!”,但殊不知这一切还不都是为了碎银几两。 那隽在那伟失业的时候讽刺他没有核心竞争力,看似狂妄却也实在,我感觉也也是他在发现后浪越来越优秀的时候对自己的质问。上面提到我的这次的职业焦虑没那么严重和慌张,就是当我在问自己“你的核心竞争力是什么?”时,我能够更快的发现问题并尽可能快的去改变。上周在和 HR 同学聊时,一个观点也给我带来了一些启发,他说核心竞争力应该是一个组合,上面说的我去改变具体一点是想在技术方面多下功夫,但多下功夫了就真的有核心竞争力了吗?我们总在谈短板和长板,那么核心竞争力到底是短板不那么短,还是长板要足够长?或许都不是,核心竞争力应该是你真的 这个问题了,然后也付诸行动去改变了,不奏效大不了再换一个思路去改变。 沈磊被谢美蓝诟病最大的就是在他母亲生命最后的阶段他没有去麻烦别人,看起来是他的理性在驱使,但如果事情发生在他自己的父母身上呢,这里不聊谁对谁错,选择是困难的,尤其是在不得不选的时候。不喜欢麻烦别人这个事我也是这样,我甚至把能不麻烦就不麻烦别人作为我的人生信条。但我现在有了些许改变,有些人值得去麻烦,因为我知道他不图有一天可以麻烦回我。我称这样的人为知己,人生有知己,三两足矣。 牛马一生 终其一生,不为牛马,能做到的就真的不是凡人了,大多数人可能是牛马一生。当下流行的说法是“牛马三件套”:房贷、车贷、传宗接代,好多鸡汤都在说让大家活出自我,其实没必要把两者放在对立面。牛马一生可能才是常态,每个人都有欲望,或大或小,但终会有两难全的事情,所以自我和解会更可取些。 每个人的情况各有不同,每个时段的情况也各有不同,审时度势,不把自己玩死,才会有追求更好的机会。所以在一个时间点大胆地假设小心地求证,事后不要以“都是为了什么或谁”的理由去懊悔,别绑架他人也别绑架自己,向前看就好。凡人,但不要烦心。