<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>lili Blog</title>
    <description>关于程序与设计、测试与开发 |  李梨，Web &amp; Mobile Lover，Software Engineer，UX Designer | 这里是 @outman李梨 的个人博客，与你一起发现更大的世界。</description>
    <link>https://guanlili.github.io/</link>
    <atom:link href="https://guanlili.github.io/feed.xml" rel="self" type="application/rss+xml" />
    <pubDate>Sun, 17 May 2026 14:17:46 +0000</pubDate>
    <lastBuildDate>Sun, 17 May 2026 14:17:46 +0000</lastBuildDate>
    <generator>Jekyll v3.10.0</generator>
    
      <item>
        <title>再见前后端分离！我用 AI 一个人“合围”了软件工程</title>
        <description>&lt;h1 id=&quot;再见前后端分离我用-ai-一个人卷死了传统团队&quot;&gt;再见前后端分离！我用 AI 一个人卷死了传统团队&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;—— 告别高昂的“沟通税”：一场关于超级个体的效率回归实验&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;小时候读《三国演义》，开篇那句话总觉得气势磅礴：“天下大势，合久必分，分久必合。” 那时候以为这是写给帝王将相看的史诗。后来自己从全栈开发做到大型项目的PMO，又开始折腾属于自己的 AI 工作室，才在无数个联调到吐血的深夜恍然大悟——罗贯中这老头，分明是个看透了系统架构的顶级程序员穿越回去的。&lt;/p&gt;

&lt;p&gt;这八个字，写的哪是历史？分明就是软件工程的命。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://blog-1258476669.cos.ap-beijing.myqcloud.com/macAir/Gemini_Generated_Image_650vqh650vqh650v1.png?imageSlim&quot; alt=&quot;Gemini_Generated_Image_650vqh650vqh650v1&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;01-缘起在两条战线的极限拉扯中闭环&quot;&gt;01. 缘起：在两条战线的“极限拉扯”中闭环&lt;/h3&gt;

&lt;p&gt;最近一个月，我过得异常“激荡”。 我正试图用 AI，一个人撑起一间专注软件研发的科技工作室。目前，我的精力和代码正疯狂倾注在两条截然不同的战线上：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;ToC 的“尖刀”：&lt;/strong&gt; 结合我自己做科技岗与体制内求职辅导时洞察到的痛点，我单枪匹马开发了一款求职类效率产品，针对性地做突破。为了这把“尖刀”，我单月提交的代码量突破了数十万行，等解决了支付的问题会正式上线。&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;ToB 的“阵地”：&lt;/strong&gt; 同时，我还要负责工作室承接的几个面向高校和科研院所的B端系统交付，面对的是极其硬核且复杂的数据流转业务。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;在这些真刀真枪的业务磨砺中，我的工作流进化到了一个极为纯粹的境界：没有前端，没有后端，没有产品经理，甚至没有那个永远在吵架的“协作群”。 从需求拆解、架构设计、数据库建模，一路干到打包部署。全链路，一人闭合。这种感觉，像极了我在《2025年终总结》里提到的那种&lt;strong&gt;“亲手造引擎”&lt;/strong&gt;的快感。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://blog-1258476669.cos.ap-beijing.myqcloud.com/macAir/Gemini_Generated_Image_5dgj925dgj925dgj.png?imageSlim&quot; alt=&quot;Gemini_Generated_Image_5dgj925dgj925dgj&quot; /&gt;&lt;/p&gt;

&lt;p&gt;听起来像吹牛？为了验证这不是我的幸存者偏差，我专门搞了个“对照实验”。&lt;/p&gt;

&lt;h3 id=&quot;02-试炼一场关于沟通税的残酷拆解&quot;&gt;02. 试炼：一场关于“沟通税”的残酷拆解&lt;/h3&gt;

&lt;p&gt;我将项目分成了两组赛道： 一组是我的&lt;strong&gt;“兼职正规军”&lt;/strong&gt;：前后端分离，角色齐全，流程规范。看起来西装革履，非常专业。 另一组是我的&lt;strong&gt;“AI 游击队”&lt;/strong&gt;：全链路 AI 接入，我一人闭环。&lt;/p&gt;

&lt;p&gt;我就坐在监工位上，看着两组项目赛跑。结果出来后，我陷入了长久的沉思，甚至觉得有点对不起那些天天开会到深夜的同行。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;传统组：时间，在缝隙中被“税”掉了&lt;/strong&gt; 团队里没人摸鱼，大家都很努力。但软件开发最大的谎言就是：“明天联调。” 加一个简单的字段，前端等后端改接口，后端改完要重启服务，重启完了测试说环境又崩了。一个芝麻大的改动，在三个人之间转了一圈，半天时间凭空消失。 那些足以让项目经理心梗的对话，每天都在上演： “这个字段叫 userName 还是 user_name？” “Swagger 上的文档是上周的还是刚才的？” “跨域了！是你Nginx没配好，还是我Header没传对？”&lt;/p&gt;

&lt;p&gt;每一句对话背后，都是真实流失的金钱。联调沟通花掉的时间，往往是写代码本身的三倍。前后端分离原本是为了快，最后却变成了——&lt;strong&gt;大家都在为低效的协作缴纳高昂的“沟通税”。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AI 组：没有队友，原来可以这么爽&lt;/strong&gt; 切换到我独立操盘的 AI 组，世界清净了。 前端和后端在同一个工程里，数据模型和业务逻辑在同一个脑子里转。我不需要写给“另一个人”看的文档，因为那个人就是我自己。想改就改，改完即生效，沟通成本为零。 AI 承包了所有极端的边界处理和冗长的类型定义，而我成了那个拥有“外骨骼”的指挥官。 几个中小型项目跑下来，我一个人的交付节奏，比两人团队快了将近 2 倍。不是因为我天赋异禀，而是我把“协作损耗”从系统中物理切除了。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://blog-1258476669.cos.ap-beijing.myqcloud.com/macAir/Gemini_Generated_Image_8o94908o94908o94.png?imageSlim&quot; alt=&quot;Gemini_Generated_Image_8o94908o94908o94&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;03-觉醒为什么是现在为什么是合&quot;&gt;03. 觉醒：为什么是现在？为什么是“合”？&lt;/h3&gt;

&lt;p&gt;“一人全栈”是开发者的古老梦想，但在十年前，那是“个人英雄主义”的苦力活。 那时，前端框架一年换三套，后端架构门派林立，数据库、运维、安全，每一块都能耗尽一个人的精力。&lt;/p&gt;

&lt;p&gt;但 AI 来了以后，这道题的解法变了。 现在的“合”，不是因为我们变弱了，而是因为 AI 补齐了我们的短板：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;遇到生僻的算法，AI 是随叫随到的资深顾问；&lt;/li&gt;
  &lt;li&gt;面对枯燥的 CRUD，AI 是从不抱怨的超级实习生；&lt;/li&gt;
  &lt;li&gt;遇到复杂的服务器部署，AI 是精通指令的运维专家。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;复盘技术史，这真是一个有趣的轮回： 最早是&lt;strong&gt;“合”&lt;/strong&gt;：工具简陋，只能一个人硬扛，那是没得选； 后来是&lt;strong&gt;“分”&lt;/strong&gt;：项目规模爆炸，不得不拆成流水线，但也随之产生了高昂的“沟通税”； 现在又回到&lt;strong&gt;“合”&lt;/strong&gt;：AI 把个人生产力直接拉到了天花板，小而美的“一体化闭环”，重新在效率上降维打击了流水线分工。&lt;/p&gt;

&lt;p&gt;这一次的“合”，是基于强大的工具，重塑了超级个体的边界。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://blog-1258476669.cos.ap-beijing.myqcloud.com/macAir/Gemini_Generated_Image_rptr75rptr75rptr.png?imageSlim&quot; alt=&quot;Gemini_Generated_Image_rptr75rptr75rptr&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;04-展望在人迹罕至的路上构建自己的引擎&quot;&gt;04. 展望：在人迹罕至的路上，构建自己的引擎&lt;/h3&gt;

&lt;p&gt;回望这段时间的尝试，正如我之前在分享中反复回响的诗句： &lt;em&gt;“林中有两条路，我选择了人迹更少的那一条，而这让一切都截然不同。”&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;前后端分离没错，它是上一个时代的满分答案。但 AI 时代的超级个体，并不是在开历史倒车。我们是在用一种全新的耦合方式，重新定义交付的效率。&lt;/p&gt;

&lt;p&gt;我这间 AI 工作室，写的是落地的代码，解的是真实的痛点。我不卖课，只做真实的交付。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;如果你是创业者：&lt;/strong&gt; 有灵感但怕被传统开发的“重”拖累，我们可以聊聊，用轻量化的方式让创新落地。&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;如果你是甲方或项目负责人：&lt;/strong&gt; 想要交付得轻一点、快一点、沟通少一点，这里有一个不一样的答案。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;我已不再是那个在岸边看潮起潮落的人。我已经跳进了海里，通过自己的经验与思考，用 AI 探索超级个体的上限。&lt;/p&gt;

&lt;p&gt;道阻且长，行则将至。 2026，继续在人迹更少的路上，折腾，生长。觉得有意思，点个关注，咱们评论区见。&lt;/p&gt;
</description>
        <pubDate>Wed, 13 May 2026 00:00:00 +0000</pubDate>
        <link>https://guanlili.github.io/2026/05/13/%E5%86%8D%E8%A7%81%E5%89%8D%E5%90%8E%E7%AB%AF%E5%88%86%E7%A6%BB-%E6%88%91%E7%94%A8-AI-%E4%B8%80%E4%B8%AA%E4%BA%BA-%E5%90%88%E5%9B%B4-%E4%BA%86%E8%BD%AF%E4%BB%B6%E5%B7%A5%E7%A8%8B/</link>
        <guid isPermaLink="true">https://guanlili.github.io/2026/05/13/%E5%86%8D%E8%A7%81%E5%89%8D%E5%90%8E%E7%AB%AF%E5%88%86%E7%A6%BB-%E6%88%91%E7%94%A8-AI-%E4%B8%80%E4%B8%AA%E4%BA%BA-%E5%90%88%E5%9B%B4-%E4%BA%86%E8%BD%AF%E4%BB%B6%E5%B7%A5%E7%A8%8B/</guid>
        
        <category>AI</category>
        
        <category>架构</category>
        
        
      </item>
    
      <item>
        <title>🚀 实战进阶：将 ComfyUI 封装为 AI 视频生成网站 (FastAPI + WebUI)</title>
        <description>&lt;h1 id=&quot;-实战进阶将-comfyui-封装为-ai-视频生成网站-fastapi--webui&quot;&gt;🚀 实战进阶：将 ComfyUI 封装为 AI 视频生成网站 (FastAPI + WebUI)&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;背景：&lt;/strong&gt; 在上一篇文章中，我们已经在 Ubuntu 服务器 (RTX 4090) 上成功部署了 ComfyUI 并跑通了 Wan2.1 文生视频工作流。 但 ComfyUI 原生界面太复杂，不适合直接丢给最终用户使用。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;目标：&lt;/strong&gt; 我们要构建一个&lt;strong&gt;“业务网关”&lt;/strong&gt;，包含：&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;后端 (FastAPI)&lt;/strong&gt;：封装 ComfyUI 的 API，将复杂的 ComfyUI 工作流封装为干净、标准的 RESTful API，供上游服务 (如RuoYi) 调用。&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;运行环境:&lt;/strong&gt; 独立 Python &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;venv&lt;/code&gt; (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fastapi_venv&lt;/code&gt;)&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;前端 (HTML/JS)&lt;/strong&gt;：提供一个清爽的 Web 界面，用户只需输入提示词即可生成视频。&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;依赖服务:&lt;/strong&gt; ComfyUI AI 引擎 (必须在 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;http://127.0.0.1:8188&lt;/code&gt; 运行)&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;架构&lt;/strong&gt;：用户访问 -&amp;gt; FastAPI (9000端口) -&amp;gt; 内部转发 -&amp;gt; ComfyUI (8188端口)。&lt;/li&gt;
&lt;/ol&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;️-第一步准备独立环境&quot;&gt;🛠️ 第一步：准备独立环境&lt;/h3&gt;

&lt;p&gt;为了保证环境纯净，我们&lt;strong&gt;不要&lt;/strong&gt;复用 ComfyUI 的 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;venv&lt;/code&gt;，而是为 FastAPI 创建一个独立的虚拟环境。&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;创建并激活环境&lt;/strong&gt;&lt;/p&gt;

    &lt;p&gt;Bash&lt;/p&gt;

    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;cd ~/My-ComfyUI
python3 -m venv fastapi_venv
source fastapi_venv/bin/activate
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;安装依赖&lt;/strong&gt;&lt;/p&gt;

    &lt;p&gt;Bash&lt;/p&gt;

    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;pip install &quot;fastapi[all]&quot; uvicorn requests -i https://pypi.tuna.tsinghua.edu.cn/simple
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;-第二步导出-api-工作流-菜谱&quot;&gt;📂 第二步：导出 API 工作流 (“菜谱”)&lt;/h3&gt;

&lt;p&gt;FastAPI 需要知道如何“指挥” ComfyUI。我们需要将工作流导出为 JSON 模板。&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;打开 ComfyUI 界面&lt;/strong&gt; (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;http://服务器IP:8188&lt;/code&gt;)。&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;加载 T2V 工作流&lt;/strong&gt;：确保这是您调试通过的、包含 &lt;strong&gt;“Save Video”&lt;/strong&gt; 节点的工作流。
    &lt;ul&gt;
      &lt;li&gt;&lt;em&gt;注意：必须有 Save Video 节点，否则 FastAPI 无法捕获结果文件。&lt;/em&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;导出 API 格式&lt;/strong&gt;：
    &lt;ul&gt;
      &lt;li&gt;点击右侧菜单的 &lt;strong&gt;“Save (API format)”&lt;/strong&gt; 按钮。&lt;/li&gt;
      &lt;li&gt;下载 JSON 文件。&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;上传服务器&lt;/strong&gt;：
    &lt;ul&gt;
      &lt;li&gt;将文件重命名为 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;t2v_api.json&lt;/code&gt;。&lt;/li&gt;
      &lt;li&gt;上传到服务器的 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;~/My-ComfyUI/&lt;/code&gt; 目录下。&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;-第三步编写后端代码-api_serverpy&quot;&gt;💻 第三步：编写后端代码 (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;api_server.py&lt;/code&gt;)&lt;/h3&gt;

&lt;p&gt;在 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;~/My-ComfyUI/&lt;/code&gt; 目录下创建 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;api_server.py&lt;/code&gt;。 这段代码实现了：&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;静态文件托管&lt;/strong&gt;：让用户访问 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;http://IP:9000&lt;/code&gt; 就能看到网页。&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;API 转发&lt;/strong&gt;：接收前端请求，注入提示词，调用 ComfyUI。&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;结果解析&lt;/strong&gt;：智能解析 ComfyUI 复杂的输出路径，返回真实 URL。&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Python&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;import uvicorn
import requests
import json
import uuid
from fastapi import FastAPI
from pydantic import BaseModel
from fastapi.middleware.cors import CORSMiddleware # 允许 RuoYi 前端跨域

# (!!!) 新增下面这一行导入 (!!!)
from fastapi.staticfiles import StaticFiles
from fastapi.responses import HTMLResponse

app = FastAPI()

# --- CORS 跨域设置 ---
# 允许所有来源 (生产环境您应该改成 RuoYi 的前端地址)
app.add_middleware(
    CORSMiddleware,
    allow_origins=[&quot;*&quot;], 
    allow_credentials=True,
    allow_methods=[&quot;*&quot;],
    allow_headers=[&quot;*&quot;],
)

# (!!!) 新增以下代码 (!!!)

# 1. 挂载静态文件目录，这样前端才能访问 static 里的资源
app.mount(&quot;/static&quot;, StaticFiles(directory=&quot;static&quot;), name=&quot;static&quot;)

# 2. 添加根路由，直接返回 index.html
@app.get(&quot;/&quot;, response_class=HTMLResponse)
async def read_root():
    with open(&quot;static/index.html&quot;, &quot;r&quot;, encoding=&quot;utf-8&quot;) as f:
        return f.read()


# --- ComfyUI 配置 ---
COMFYUI_URL = &quot;http://127.0.0.1:8188&quot;
# (!!!) 新增此行 (!!!)
# 请将 [YOUR_SERVER_IP] 替换为您的公网 IP 或域名
PUBLIC_FACING_URL = &quot;http://127.0.0.1:8188&quot; # 返回给 RuoYi 时使用
# 启动时加载 API 工作流模板
try:
    with open(&quot;text_to_video_wan.json&quot;, &quot;r&quot;, encoding=&quot;utf-8&quot;) as f:
        API_WORKFLOW_TEMPLATE = json.load(f)
    print(&quot;text_to_video_wan 加载成功。&quot;)
except FileNotFoundError:
    print(&quot;错误:text_to_video_wan.json 未找到！&quot;)
    API_WORKFLOW_TEMPLATE = None

# --- Pydantic 模型定义 ---
class T2VRequest(BaseModel):
    prompt: str
    negative_prompt: str = &quot;low quality, worst quality, bad quality&quot;

# --- 辅助函数：定位提示词节点 ---
def find_prompt_node_id(workflow_template):
    &quot;&quot;&quot;在工作流 JSON 中自动查找 CLIP Text Encode 节点的 ID&quot;&quot;&quot;
    for node_id, node_data in workflow_template.items():
        if node_data.get(&quot;class_type&quot;) == &quot;CLIP Text Encode (Simple)&quot;:
            # 假设第一个找到的是我们的目标
            return node_id, &quot;positive&quot; # &quot;positive&quot; 是该节点的输入字段名
        if node_data.get(&quot;class_type&quot;) == &quot;CLIPTextEncode&quot;:
            # 兼容 ComfyUI 原生节点名
            return node_id, &quot;text&quot;
    return None, None # 如果找不到

# 动态查找 Positive 提示词节点的 ID 和字段
POSITIVE_NODE_ID, POSITIVE_FIELD_NAME = find_prompt_node_id(API_WORKFLOW_TEMPLATE)
if POSITIVE_NODE_ID:
    print(f&quot;自动定位到 Positive 提示词节点 ID: {POSITIVE_NODE_ID}, 字段: {POSITIVE_FIELD_NAME}&quot;)
else:
    print(&quot;警告：无法自动定位 Positive 提示词节点！&quot;)


# --- API 端点 ---

@app.post(&quot;/api/v1/generate-video&quot;)
def queue_generation(request: T2VRequest):
    &quot;&quot;&quot;
    1. 接收 RuoYi 的请求，排队任务
    2. 返回任务 ID
    &quot;&quot;&quot;
    if not API_WORKFLOW_TEMPLATE:
        return {&quot;error&quot;: &quot;服务器工作流模板未加载&quot;}, 500

    if not POSITIVE_NODE_ID:
        return {&quot;error&quot;: &quot;服务器工作流配置错误，找不到提示词节点&quot;}, 500

    # 1. 复制模板并注入提示词
    workflow = API_WORKFLOW_TEMPLATE.copy()
    workflow[POSITIVE_NODE_ID][&quot;inputs&quot;][POSITIVE_FIELD_NAME] = request.prompt

    # (可选) 注入负面提示词 (需要您自己找到负面节点的 ID)
    # workflow[&quot;NEGATIVE_NODE_ID&quot;][&quot;inputs&quot;][&quot;text&quot;] = request.negative_prompt

    # 2. 准备 payload
    client_id = str(uuid.uuid4())
    payload = {&quot;prompt&quot;: workflow, &quot;client_id&quot;: client_id}

    # 3. 调用 ComfyUI 的 /prompt 接口
    try:
        response = requests.post(f&quot;{COMFYUI_URL}/prompt&quot;, json=payload)
        response.raise_for_status()
        data = response.json()

        if &apos;prompt_id&apos; not in data:
            return {&quot;error&quot;: &quot;ComfyUI 未返回 prompt_id&quot;, &quot;details&quot;: data}, 500

        return {
            &quot;status&quot;: &quot;queued&quot;,
            &quot;task_id&quot;: data[&apos;prompt_id&apos;]
        }

    except requests.RequestException as e:
        return {&quot;error&quot;: f&quot;调用 ComfyUI 失败: {str(e)}&quot;}, 503


@app.get(&quot;/api/v1/status/{task_id}&quot;)
def get_task_status(task_id: str):
    &quot;&quot;&quot;
    1. 接收 RuoYi 的轮询请求
    2. 检查 ComfyUI 的 /history 接口
    3. (最终修正版) 查找 &apos;outputs&apos; -&amp;gt; &apos;node&apos; -&amp;gt; &apos;images&apos; -&amp;gt; list -&amp;gt; &apos;filename&apos; &amp;amp; &apos;subfolder&apos;
    &quot;&quot;&quot;
    try:
        # 1. 调用 ComfyUI 的 /history 接口
        response = requests.get(f&quot;{COMFYUI_URL}/history/{task_id}&quot;)
        response.raise_for_status()
        data = response.json()

        # 2. 检查 history
        if task_id not in data:
            # 任务还在队列中，尚未开始执行
            return {&quot;status&quot;: &quot;pending&quot;}

        history = data[task_id]

        # 3. 检查是否有错误
        if &apos;status&apos; in history and history[&apos;status&apos;].get(&apos;exception&apos;):
            return {&quot;status&quot;: &quot;error&quot;, &quot;message&quot;: history[&apos;status&apos;][&apos;exception&apos;][1]}

        # 4. 检查是否已完成
        if &apos;outputs&apos; in history:
            outputs = history[&apos;outputs&apos;]
            video_files = []
            
            # 遍历所有节点的输出 (outputs.values() 会返回 &quot;50&quot;: {...} 里的内容)
            for node_output in outputs.values():
                
                # 这是我们从您的 JSON 中找到的精确路径
                if &apos;images&apos; in node_output:
                    for image_data in node_output[&apos;images&apos;]:
                        # 确保这是一个已保存的 &quot;output&quot; 类型文件
                        if image_data.get(&apos;type&apos;) == &apos;output&apos;:
                            filename = image_data.get(&apos;filename&apos;)
                            subfolder = image_data.get(&apos;subfolder&apos;)
                            
                            if filename:
                                # 构建 ComfyUI /view 接口能识别的 URL
                                video_url = f&quot;{PUBLIC_FACING_URL}/view?filename={filename}&amp;amp;type=output&quot;
                                
                                # 如果有子目录，必须加上 subfolder 参数
                                if subfolder:
                                    video_url += f&quot;&amp;amp;subfolder={subfolder}&quot;
                                    
                                video_files.append(video_url)
            
            if video_files:
                # 去重，以防万一
                unique_video_files = list(set(video_files))
                return {
                    &quot;status&quot;: &quot;complete&quot;,
                    &quot;video_urls&quot;: unique_video_files
                }
            else:
                # 如果还是没找到 (几乎不可能了)，返回一个错误
                return {&quot;status&quot;: &quot;complete_no_files_found_in_history_FINAL&quot;}

        # 5. 如果都对不上，说明还在运行
        return {&quot;status&quot;: &quot;running&quot;}

    except requests.RequestException as e:
        return {&quot;error&quot;: f&quot;调用 ComfyUI 失败: {str(e)}&quot;}, 503


if __name__ == &quot;__main__&quot;:
    print(&quot;启动 FastAPI 服务器在 0.0.0.0:9000&quot;)
    uvicorn.run(app, host=&quot;0.0.0.0&quot;, port=9000)

&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;关键配置项 (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;api_server.py&lt;/code&gt;)&lt;/p&gt;

&lt;p&gt;在 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;api_server.py&lt;/code&gt; 文件的顶部，有两个关键配置项需要您根据环境修改：&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;COMFYUI_URL&lt;/code&gt;&lt;/strong&gt;
    &lt;ul&gt;
      &lt;li&gt;&lt;strong&gt;用途:&lt;/strong&gt; FastAPI &lt;strong&gt;内部&lt;/strong&gt;调用 ComfyUI 引擎的地址。&lt;/li&gt;
      &lt;li&gt;&lt;strong&gt;值:&lt;/strong&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;http://127.0.0.1:8188&lt;/code&gt;&lt;/li&gt;
      &lt;li&gt;&lt;strong&gt;备注:&lt;/strong&gt; 必须使用 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;127.0.0.1&lt;/code&gt;，确保服务间走内网通信，效率最高。&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PUBLIC_FACING_URL&lt;/code&gt;&lt;/strong&gt;
    &lt;ul&gt;
      &lt;li&gt;&lt;strong&gt;用途:&lt;/strong&gt; 在 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GET /status/{task_id}&lt;/code&gt; 接口&lt;strong&gt;返回&lt;/strong&gt;给调用方 (RuoYi) 的 URL 中，用于拼接视频地址。&lt;/li&gt;
      &lt;li&gt;&lt;strong&gt;值:&lt;/strong&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;http://[YOUR_SERVER_IP]:8188&lt;/code&gt; 或 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;https://[YOUR_DOMAIN.COM]&lt;/code&gt;&lt;/li&gt;
      &lt;li&gt;&lt;strong&gt;备注:&lt;/strong&gt; 这里&lt;strong&gt;必须&lt;/strong&gt;填写服务器的&lt;strong&gt;公网 IP&lt;/strong&gt; 或&lt;strong&gt;域名&lt;/strong&gt;，否则 RuoYi 前端将无法访问视频。&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;-第四步编写前端页面-staticindexhtml&quot;&gt;🎨 第四步：编写前端页面 (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;static/index.html&lt;/code&gt;)&lt;/h3&gt;

&lt;ol&gt;
  &lt;li&gt;创建目录：&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mkdir -p ~/My-ComfyUI/static&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;创建文件：&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nano ~/My-ComfyUI/static/index.html&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;粘贴以下极简风格的代码：&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;HTML&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&quot;zh-CN&quot;&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset=&quot;UTF-8&quot;&amp;gt;
    &amp;lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&amp;gt;
    &amp;lt;title&amp;gt;Wan2.1 视频生成工坊&amp;lt;/title&amp;gt;
    &amp;lt;style&amp;gt;
        :root { --primary: #2563eb; --bg: #f8fafc; --card: #ffffff; }
        body { font-family: &apos;Segoe UI&apos;, sans-serif; background: var(--bg); color: #1e293b; display: flex; justify-content: center; padding: 40px 20px; }
        .container { width: 100%; max-width: 600px; background: var(--card); padding: 30px; border-radius: 16px; box-shadow: 0 10px 25px rgba(0,0,0,0.05); }
        h1 { margin-top: 0; font-size: 24px; color: #0f172a; text-align: center; margin-bottom: 30px; }
        
        .form-group { margin-bottom: 20px; }
        label { display: block; margin-bottom: 8px; font-weight: 600; font-size: 14px; }
        textarea { width: 100%; height: 100px; padding: 12px; border: 2px solid #e2e8f0; border-radius: 8px; font-size: 16px; resize: vertical; transition: border 0.2s; box-sizing: border-box;}
        textarea:focus { border-color: var(--primary); outline: none; }
        
        button { width: 100%; padding: 14px; background: var(--primary); color: white; border: none; border-radius: 8px; font-size: 16px; font-weight: 600; cursor: pointer; transition: opacity 0.2s; }
        button:hover { opacity: 0.9; }
        button:disabled { background: #94a3b8; cursor: not-allowed; }

        .status-box { margin-top: 20px; padding: 15px; background: #f1f5f9; border-radius: 8px; font-size: 14px; display: none; }
        .status-box.active { display: block; }
        .loader { display: inline-block; width: 12px; height: 12px; border: 2px solid #64748b; border-radius: 50%; border-top-color: transparent; animation: spin 1s linear infinite; margin-right: 8px; }
        @keyframes spin { to { transform: rotate(360deg); } }

        .video-result { margin-top: 20px; display: none; }
        video { width: 100%; border-radius: 8px; box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1); }
        .download-link { display: block; text-align: center; margin-top: 10px; color: var(--primary); text-decoration: none; }
    &amp;lt;/style&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;

&amp;lt;div class=&quot;container&quot;&amp;gt;
    &amp;lt;h1&amp;gt;🎬 Wan2.1 文生视频工坊&amp;lt;/h1&amp;gt;
    
    &amp;lt;div class=&quot;form-group&quot;&amp;gt;
        &amp;lt;label for=&quot;prompt&quot;&amp;gt;提示词 (Prompt)&amp;lt;/label&amp;gt;
        &amp;lt;textarea id=&quot;prompt&quot; placeholder=&quot;例如：An astronaut walking on the moon, cinematic lighting, 4k&quot;&amp;gt;An astronaut walking on the moon&amp;lt;/textarea&amp;gt;
    &amp;lt;/div&amp;gt;

    &amp;lt;button id=&quot;generateBtn&quot; onclick=&quot;startGeneration()&quot;&amp;gt;✨ 开始生成视频&amp;lt;/button&amp;gt;

    &amp;lt;div id=&quot;statusBox&quot; class=&quot;status-box&quot;&amp;gt;
        &amp;lt;span class=&quot;loader&quot; id=&quot;loader&quot;&amp;gt;&amp;lt;/span&amp;gt;
        &amp;lt;span id=&quot;statusText&quot;&amp;gt;准备就绪&amp;lt;/span&amp;gt;
    &amp;lt;/div&amp;gt;

    &amp;lt;div id=&quot;videoContainer&quot; class=&quot;video-result&quot;&amp;gt;
        &amp;lt;label&amp;gt;生成结果：&amp;lt;/label&amp;gt;
        &amp;lt;video id=&quot;videoPlayer&quot; controls loop autoplay muted&amp;gt;&amp;lt;/video&amp;gt;
        &amp;lt;a id=&quot;downloadLink&quot; href=&quot;#&quot; target=&quot;_blank&quot; class=&quot;download-link&quot;&amp;gt;下载视频&amp;lt;/a&amp;gt;
    &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;script&amp;gt;
    // 这里填写您的 FastAPI 地址 (如果就在当前页面访问，留空或者是相对路径即可)
    // 由于我们是同源托管，直接用相对路径 &quot;/api/v1&quot;
    const API_BASE = &quot;/api/v1&quot;;

    let checkInterval = null;

    async function startGeneration() {
        const prompt = document.getElementById(&apos;prompt&apos;).value;
        if (!prompt) return alert(&quot;请输入提示词！&quot;);

        // UI 重置
        const btn = document.getElementById(&apos;generateBtn&apos;);
        const statusBox = document.getElementById(&apos;statusBox&apos;);
        const statusText = document.getElementById(&apos;statusText&apos;);
        const videoContainer = document.getElementById(&apos;videoContainer&apos;);
        const loader = document.getElementById(&apos;loader&apos;);

        btn.disabled = true;
        btn.innerText = &quot;生成中...&quot;;
        statusBox.classList.add(&apos;active&apos;);
        videoContainer.style.display = &apos;none&apos;;
        loader.style.display = &apos;inline-block&apos;;
        statusText.innerText = &quot;正在提交任务...&quot;;

        try {
            // 1. 提交任务
            const res = await fetch(`${API_BASE}/generate-video`, {
                method: &apos;POST&apos;,
                headers: { &apos;Content-Type&apos;: &apos;application/json&apos; },
                body: JSON.stringify({ prompt: prompt })
            });

            const data = await res.json();
            if (data.error) throw new Error(data.error);
            
            const taskId = data.task_id;
            statusText.innerText = `任务已提交 (ID: ${taskId.slice(0,8)}...)，正在排队...`;

            // 2. 开始轮询
            checkInterval = setInterval(() =&amp;gt; checkStatus(taskId), 3000);

        } catch (e) {
            showError(e.message);
        }
    }

    async function checkStatus(taskId) {
        const statusText = document.getElementById(&apos;statusText&apos;);
        
        try {
            const res = await fetch(`${API_BASE}/status/${taskId}`);
            const data = await res.json();

            if (data.status === &apos;running&apos;) {
                statusText.innerText = &quot;🚀 AI 正在努力生成中... (这可能需要几十秒)&quot;;
            } else if (data.status === &apos;pending&apos;) {
                statusText.innerText = &quot;⏳ 正在排队等待 GPU 资源...&quot;;
            } else if (data.status === &apos;complete&apos;) {
                clearInterval(checkInterval);
                showSuccess(data.video_urls[0]);
            } else if (data.status === &apos;error&apos;) {
                clearInterval(checkInterval);
                showError(data.message || &quot;生成失败&quot;);
            }
        } catch (e) {
            clearInterval(checkInterval);
            showError(&quot;网络连接错误&quot;);
        }
    }

    function showSuccess(url) {
        const btn = document.getElementById(&apos;generateBtn&apos;);
        const statusText = document.getElementById(&apos;statusText&apos;);
        const loader = document.getElementById(&apos;loader&apos;);
        const videoContainer = document.getElementById(&apos;videoContainer&apos;);
        const videoPlayer = document.getElementById(&apos;videoPlayer&apos;);
        const downloadLink = document.getElementById(&apos;downloadLink&apos;);

        btn.disabled = false;
        btn.innerText = &quot;✨ 再生成一个&quot;;
        loader.style.display = &apos;none&apos;;
        statusText.innerText = &quot;✅ 生成完成！&quot;;
        
        videoPlayer.src = url;
        downloadLink.href = url;
        videoContainer.style.display = &apos;block&apos;;
    }

    function showError(msg) {
        const btn = document.getElementById(&apos;generateBtn&apos;);
        const statusText = document.getElementById(&apos;statusText&apos;);
        const loader = document.getElementById(&apos;loader&apos;);
        
        clearInterval(checkInterval);
        btn.disabled = false;
        btn.innerText = &quot;重试&quot;;
        loader.style.display = &apos;none&apos;;
        statusText.innerText = &quot;❌ 错误: &quot; + msg;
    }
&amp;lt;/script&amp;gt;

&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;

&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;整体文件结构&lt;/p&gt;

&lt;p&gt;服务部署在 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;~/My-ComfyUI&lt;/code&gt; 目录下：&lt;/p&gt;

&lt;p&gt;Bash&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;~/My-ComfyUI/
├── api_server.py           # (核心) FastAPI 服务的主代码
├── t2v_api.json            # (核心) ComfyUI 导出的 API 格式工作流 &quot;菜谱&quot;
├── fastapi_venv/           # (环境) FastAPI 专用的 Python 虚拟环境
├── ComfyUI/                # (依赖) ComfyUI 引擎的完整目录
├── static/                 # (前端) FastAPI前端页面
└── venv/                   # (环境) ComfyUI 专用的 Python 虚拟环境

&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;-第五步部署与运行&quot;&gt;🚀 第五步：部署与运行&lt;/h3&gt;

&lt;p&gt;整体文件结构&lt;/p&gt;

&lt;p&gt;Bash&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;~/My-ComfyUI/
├── api_server.py           # (核心) FastAPI 服务的主代码
├── t2v_api.json            # (核心) ComfyUI 导出的 API 格式工作流 &quot;菜谱&quot;
├── fastapi_venv/           # (环境) FastAPI 专用的 Python 虚拟环境
├── ComfyUI/                # (依赖) ComfyUI 引擎的完整目录
├── static/                 # (前端) FastAPI前端页面
└── venv/                   # (环境) ComfyUI 专用的 Python 虚拟环境

&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;此服务与 ComfyUI 引擎一样，也需要使用 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;screen&lt;/code&gt; 在后台持久化运行。&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;进入 Screen 会话&lt;/strong&gt;&lt;/p&gt;

    &lt;p&gt;Bash&lt;/p&gt;

    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;screen -S fastapi
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;启动服务&lt;/strong&gt;&lt;/p&gt;

    &lt;p&gt;Bash&lt;/p&gt;

    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;cd ~/My-ComfyUI
source fastapi_venv/bin/activate  # 别忘了激活环境
python api_server.py
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;停止 / 重启服务 (最常用)&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;您需要更新代码 (如 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;api_server.py&lt;/code&gt;) 或工作流 (如 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;t2v_api.json&lt;/code&gt;) 时，&lt;strong&gt;必须&lt;/strong&gt;重启此服务。&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;“重连”到 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fastapi&lt;/code&gt; 会话：&lt;/p&gt;

    &lt;p&gt;Bash&lt;/p&gt;

    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;screen -r fastapi
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;您会看到正在滚动的日志。按 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Ctrl + C&lt;/code&gt; &lt;strong&gt;停止&lt;/strong&gt;当前服务。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;重新启动&lt;/strong&gt;服务：&lt;/p&gt;

    &lt;p&gt;Bash&lt;/p&gt;

    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;# (此时应仍在 venv 中)
python api_server.py
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;验证与脱离&lt;/strong&gt;&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;如果你看到 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Uvicorn running on http://0.0.0.0:9000&lt;/code&gt;，说明启动成功。&lt;/li&gt;
      &lt;li&gt;按 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Ctrl + A&lt;/code&gt;，然后松开，再按 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;D&lt;/code&gt;，让它在后台运行。&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;hr /&gt;

&lt;p&gt;如何更新 AI 工作流&lt;/p&gt;

&lt;p&gt;当您想调整 ComfyUI 的参数（例如更换模型、修改步数）时，必须同时更新此服务：&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;在 ComfyUI (浏览器)&lt;/strong&gt;:
    &lt;ul&gt;
      &lt;li&gt;打开 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;http://[服务器IP]:8188&lt;/code&gt;。&lt;/li&gt;
      &lt;li&gt;加载您的工作流，进行修改（例如，更换 KSampler 的步数）。&lt;/li&gt;
      &lt;li&gt;确保&lt;strong&gt;最后一步&lt;/strong&gt;的 “Save Video” 节点被正确连接。&lt;/li&gt;
      &lt;li&gt;点击 &lt;strong&gt;“Save (API format)”&lt;/strong&gt;，下载新的 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.json&lt;/code&gt; 文件。&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;在服务器 (终端)&lt;/strong&gt;:
    &lt;ul&gt;
      &lt;li&gt;将新下载的 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.json&lt;/code&gt; 文件上传到 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;~/My-ComfyUI/&lt;/code&gt; 目录。&lt;/li&gt;
      &lt;li&gt;&lt;strong&gt;覆盖&lt;/strong&gt;（或替换）掉旧的 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;t2v_api.json&lt;/code&gt; 文件。&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;重启 FastAPI 服务&lt;/strong&gt;:
    &lt;ul&gt;
      &lt;li&gt;按照 &lt;strong&gt;4.3&lt;/strong&gt; 中的步骤（&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;screen -r fastapi&lt;/code&gt; -&amp;gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Ctrl+C&lt;/code&gt; -&amp;gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;python api_server.py&lt;/code&gt; …）重启服务。&lt;/li&gt;
      &lt;li&gt;&lt;em&gt;FastAPI 服务只在启动时加载一次 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;t2v_api.json&lt;/code&gt;，因此&lt;strong&gt;必须&lt;/strong&gt;重启才能使新工作流生效。&lt;/em&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;-最终效果&quot;&gt;🎉 最终效果&lt;/h3&gt;

&lt;p&gt;现在，打开您的浏览器，访问： &lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;http://[您的服务器IP]:9000&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;您将看到一个简洁的 AI 视频生成页面。输入提示词，点击生成，喝口水，视频就出来了！&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://blog-1258476669.cos.ap-beijing.myqcloud.com/bjrb/image-20251118210258306.png?imageSlim&quot; alt=&quot;image-20251118210258306&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;-运维小贴士&quot;&gt;🔧 运维小贴士&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;我要修改视频时长/步数怎么办？&lt;/strong&gt;
    &lt;ol&gt;
      &lt;li&gt;在 ComfyUI 浏览器界面修改参数。&lt;/li&gt;
      &lt;li&gt;重新导出 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;t2v_api.json&lt;/code&gt; 并覆盖服务器上的文件。&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;screen -r fastapi&lt;/code&gt; -&amp;gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Ctrl+C&lt;/code&gt; -&amp;gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;python api_server.py&lt;/code&gt; (重启 FastAPI 才能加载新配置)。&lt;/li&gt;
    &lt;/ol&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;视频无法播放？&lt;/strong&gt; 请检查 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;api_server.py&lt;/code&gt; 中的 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PUBLIC_FACING_URL&lt;/code&gt; 是否填写了正确的公网 IP。&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Mon, 20 Oct 2025 00:00:00 +0000</pubDate>
        <link>https://guanlili.github.io/2025/10/20/%E5%AE%9E%E6%88%98%E8%BF%9B%E9%98%B6-%E5%B0%86-ComfyUI-%E5%B0%81%E8%A3%85%E4%B8%BA-AI-%E8%A7%86%E9%A2%91%E7%94%9F%E6%88%90%E7%BD%91%E7%AB%99-(FastAPI-+-WebUI)/</link>
        <guid isPermaLink="true">https://guanlili.github.io/2025/10/20/%E5%AE%9E%E6%88%98%E8%BF%9B%E9%98%B6-%E5%B0%86-ComfyUI-%E5%B0%81%E8%A3%85%E4%B8%BA-AI-%E8%A7%86%E9%A2%91%E7%94%9F%E6%88%90%E7%BD%91%E7%AB%99-(FastAPI-+-WebUI)/</guid>
        
        <category>AI</category>
        
        <category>ComfyUI</category>
        
        <category>FastAPI</category>
        
        
      </item>
    
      <item>
        <title>🚀 实战入门：在服务器单卡部署 ComfyUI + Wan2.1 文生视频最佳实践</title>
        <description>&lt;h1 id=&quot;-实战入门在服务器单卡部署-comfyui--wan21-文生视频最佳实践&quot;&gt;🚀 实战入门：在服务器单卡部署 ComfyUI + Wan2.1 文生视频最佳实践&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;背景：&lt;/strong&gt; 公司新媒体同事用闭源工具烧钱烧到财务报警，素材还往外网扔，老板直接放话：“本地化，自己搞一个能文生视频的。”&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;目标：&lt;/strong&gt; 在一台全新的 Ubuntu 服务器上，“傻瓜式”地部署 ComfyUI，用于 Wan2.1 文生视频 (T2V)。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;核心原则：&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;环境隔离：&lt;/strong&gt; 绝不污染系统 Python，使用 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;venv&lt;/code&gt;。&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;资源隔离：&lt;/strong&gt; 绝不抢占其他服务（如 vLLM），指定 GPU 运行。&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;网络优化：&lt;/strong&gt; 全程使用国内镜像加速。&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;稳定运维：&lt;/strong&gt; 使用 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;screen&lt;/code&gt; 进行后台持久化运行。&lt;/li&gt;
&lt;/ol&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;-一环境准备-prerequisites&quot;&gt;📚 一、环境准备 (Prerequisites)&lt;/h3&gt;

&lt;p&gt;在开始之前，确保您的新服务器满足以下条件。&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;检查NVIDIA驱动与CUDA&lt;/strong&gt;&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nvidia-smi&lt;/code&gt;&lt;/li&gt;
      &lt;li&gt;&lt;em&gt;确保能看到显卡列表（如 4090）和 CUDA 版本（如 12.x）。&lt;/em&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;检查核心工具&lt;/strong&gt;&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;python3 --version&lt;/code&gt; (推荐 Python 3.10 或 3.11)&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git --version&lt;/code&gt;&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;screen --version&lt;/code&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;(可选) 安装工具&lt;/strong&gt;&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;
        &lt;p&gt;如果缺少工具，运行：&lt;/p&gt;

        &lt;p&gt;Bash&lt;/p&gt;

        &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;sudo apt update
sudo apt install python3-venv git screen
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;        &lt;/div&gt;

        &lt;table&gt;
          &lt;thead&gt;
            &lt;tr&gt;
              &lt;th&gt;&lt;strong&gt;组件&lt;/strong&gt;&lt;/th&gt;
              &lt;th&gt;&lt;strong&gt;详情&lt;/strong&gt;&lt;/th&gt;
              &lt;th&gt;&lt;strong&gt;检查命令&lt;/strong&gt;&lt;/th&gt;
            &lt;/tr&gt;
          &lt;/thead&gt;
          &lt;tbody&gt;
            &lt;tr&gt;
              &lt;td&gt;&lt;strong&gt;操作系统&lt;/strong&gt;&lt;/td&gt;
              &lt;td&gt;Ubuntu (Linux)&lt;/td&gt;
              &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;uname -a&lt;/code&gt;&lt;/td&gt;
            &lt;/tr&gt;
            &lt;tr&gt;
              &lt;td&gt;&lt;strong&gt;GPU&lt;/strong&gt;&lt;/td&gt;
              &lt;td&gt;8 x NVIDIA GeForce RTX 4090&lt;/td&gt;
              &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nvidia-smi&lt;/code&gt;&lt;/td&gt;
            &lt;/tr&gt;
            &lt;tr&gt;
              &lt;td&gt;&lt;strong&gt;NVIDIA 驱动&lt;/strong&gt;&lt;/td&gt;
              &lt;td&gt;570.124.06&lt;/td&gt;
              &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nvidia-smi&lt;/code&gt;&lt;/td&gt;
            &lt;/tr&gt;
            &lt;tr&gt;
              &lt;td&gt;&lt;strong&gt;CUDA 版本&lt;/strong&gt;&lt;/td&gt;
              &lt;td&gt;12.8 (由驱动支持)&lt;/td&gt;
              &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nvidia-smi&lt;/code&gt;&lt;/td&gt;
            &lt;/tr&gt;
            &lt;tr&gt;
              &lt;td&gt;&lt;strong&gt;Python 版本&lt;/strong&gt;&lt;/td&gt;
              &lt;td&gt;3.10.9&lt;/td&gt;
              &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;python3 --version&lt;/code&gt;&lt;/td&gt;
            &lt;/tr&gt;
            &lt;tr&gt;
              &lt;td&gt;&lt;strong&gt;Git 版本&lt;/strong&gt;&lt;/td&gt;
              &lt;td&gt;2.43.0&lt;/td&gt;
              &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git --version&lt;/code&gt;&lt;/td&gt;
            &lt;/tr&gt;
          &lt;/tbody&gt;
        &lt;/table&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;-二项目安装与环境隔离-v-e-n-v&quot;&gt;📦 二、项目安装与环境隔离 (v-e-n-v)&lt;/h3&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;创建项目根目录：&lt;/strong&gt;&lt;/p&gt;

    &lt;p&gt;Bash&lt;/p&gt;

    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;cd ~
mkdir My-ComfyUI
cd My-ComfyUI
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;创建虚拟环境：&lt;/strong&gt;&lt;/p&gt;

    &lt;p&gt;Bash&lt;/p&gt;

    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;python3 -m venv venv
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;(关键!) 激活虚拟环境：&lt;/strong&gt;&lt;/p&gt;

    &lt;p&gt;Bash&lt;/p&gt;

    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;source venv/bin/activate
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;

    &lt;ul&gt;
      &lt;li&gt;&lt;em&gt;您的终端提示符前面会出现 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;(venv)&lt;/code&gt; 标记。&lt;/em&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;克隆 ComfyUI：&lt;/strong&gt;&lt;/p&gt;

    &lt;p&gt;Bash&lt;/p&gt;

    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;git clone https://github.com/comfyanonymous/ComfyUI.git
cd ComfyUI
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;

    &lt;ul&gt;
      &lt;li&gt;&lt;em&gt;此时，您应位于 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;~/My-ComfyUI/ComfyUI&lt;/code&gt; 目录，且 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;(venv)&lt;/code&gt; 已激活。&lt;/em&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;-三安装依赖-国内镜像加速&quot;&gt;🚀 三、安装依赖 (国内镜像加速)&lt;/h3&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;(推荐) 升级 pip：&lt;/strong&gt;&lt;/p&gt;

    &lt;p&gt;Bash&lt;/p&gt;

    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;pip install --upgrade pip -i https://pypi.tuna.tsinghua.edu.cn/simple
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;(关键) 安装 PyTorch (cu121)：&lt;/strong&gt;&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;&lt;em&gt;使用中科大 (USTC) 镜像，它对 PyTorch 的 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cuXXX&lt;/code&gt; 路径支持最好。&lt;/em&gt;&lt;/li&gt;
    &lt;/ul&gt;

    &lt;p&gt;Bash&lt;/p&gt;

    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;pip install torch torchvision torchaudio --index-url https://pypi.mirrors.ustc.edu.cn/pytorch-wheels/cu121
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;安装 ComfyUI 其它依赖：&lt;/strong&gt;&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;&lt;em&gt;使用清华 (Tsinghua) PyPI 镜像。&lt;/em&gt;&lt;/li&gt;
    &lt;/ul&gt;

    &lt;p&gt;Bash&lt;/p&gt;

    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;-四下载-wan21-t2v-核心模型&quot;&gt;💾 四、下载 Wan2.1 (T2V) 核心模型&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;em&gt;我们使用 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hf-mirror.com&lt;/code&gt; 国内镜像，并用 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;wget -O&lt;/code&gt; 直接保存到正确目录。&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;下载 T2V 核心模型 (约 5.18 GB):&lt;/strong&gt;&lt;/p&gt;

    &lt;p&gt;Bash&lt;/p&gt;

    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;mkdir -p models/diffusion_models
wget -O models/diffusion_models/wan2.1_t2v_1.3B_fp16.safetensors \
https://hf-mirror.com/ali-vilab/wan2.1-t2v/resolve/main/diffusion_models/wan2.1_t2v_1.3B_fp16.safetensors
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;下载文本编码器 (约 6.27 GB):&lt;/strong&gt;&lt;/p&gt;

    &lt;p&gt;Bash&lt;/p&gt;

    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;mkdir -p models/text_encoders
wget -O models/text_encoders/umt5_xxl_fp8_e4m3fn_scaled.safetensors \
https://hf-mirror.com/ali-vilab/wan2.1-fun/resolve/main/text_encoders/umt5_xxl_fp8_e4m3fn_scaled.safetensors
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;下载 VAE (约 242 MB):&lt;/strong&gt;&lt;/p&gt;

    &lt;p&gt;Bash&lt;/p&gt;

    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;mkdir -p models/vae
wget -O models/vae/wan_2.1_vae.safetensors \
https://hf-mirror.com/ali-vilab/wan2.1-fun/resolve/main/vae/wan_2.1_vae.safetensors
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;️-五安装-comfyui-manager-管理节点&quot;&gt;🛠️ 五、安装 ComfyUI Manager (管理节点)&lt;/h3&gt;

&lt;p&gt;这是为了方便未来安装新的自定义节点。&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;进入 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;custom_nodes&lt;/code&gt; 目录：&lt;/strong&gt;&lt;/p&gt;

    &lt;p&gt;Bash&lt;/p&gt;

    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;cd ~/My-ComfyUI/ComfyUI/custom_nodes
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;克隆 Manager：&lt;/strong&gt;&lt;/p&gt;

    &lt;p&gt;Bash&lt;/p&gt;

    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;git clone https://github.com/ltdrdata/ComfyUI-Manager.git
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;(重要) 未来如何手动安装节点：&lt;/strong&gt;&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;&lt;em&gt;我们以 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;VideoHelperSuite&lt;/code&gt; 为例，这是“傻瓜”步骤：&lt;/em&gt;&lt;/li&gt;
    &lt;/ul&gt;

    &lt;p&gt;Bash&lt;/p&gt;

    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;# 1. 在 custom_nodes 目录克隆
git clone https://github.com/Kosinkadink/ComfyUI-VideoHelperSuite.git
   
# 2. 进入新节点目录
cd ComfyUI-VideoHelperSuite
   
# 3. (关键!) 激活 venv 并安装它的依赖
source ../../../venv/bin/activate
pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
   
# 4. 回到 ComfyUI 根目录
cd ../..
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;️-六部署与日常维护-screen&quot;&gt;🖥️ 六、部署与日常维护 (Screen)&lt;/h3&gt;

&lt;h4 id=&quot;1-首次启动-前台测试&quot;&gt;1. 首次启动 (前台测试)&lt;/h4&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;回到 ComfyUI 根目录：&lt;/strong&gt;&lt;/p&gt;

    &lt;p&gt;Bash&lt;/p&gt;

    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;cd ~/My-ComfyUI/ComfyUI
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;(关键!) 激活虚拟环境&lt;/strong&gt; (如果已失效)：&lt;/p&gt;

    &lt;p&gt;Bash&lt;/p&gt;

    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;source ../venv/bin/activate
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;指定 GPU 6 启动：&lt;/strong&gt;&lt;/p&gt;

    &lt;p&gt;Bash&lt;/p&gt;

    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;CUDA_VISIBLE_DEVICES=6 python main.py --listen
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;em&gt;在您本地电脑浏览器访问 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;http://[服务器IP]:8188&lt;/code&gt;。&lt;/em&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;em&gt;拖入 T2V 工作流 (wan_t2v.json)，点击 “Queue Prompt” 测试。&lt;/em&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;em&gt;测试成功后，在 SSH 终端按 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Ctrl + C&lt;/code&gt; 停止。&lt;/em&gt;&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h4 id=&quot;2-后台部署-screen&quot;&gt;2. 后台部署 (Screen)&lt;/h4&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;创建一个名为 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;comfyui&lt;/code&gt; 的 screen 会话：&lt;/strong&gt;&lt;/p&gt;

    &lt;p&gt;Bash&lt;/p&gt;

    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;screen -S comfyui
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;em&gt;您会进入一个“新”的终端。在这个新终端里，执行标准启动流程：&lt;/em&gt;&lt;/p&gt;

    &lt;p&gt;Bash&lt;/p&gt;

    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;# 1. 进入目录
cd ~/My-ComfyUI/ComfyUI
   
# 2. 激活环境
source ../venv/bin/activate
   
# 3. 指定 GPU 6 启动 (这次不需要 &amp;amp;)
CUDA_VISIBLE_DEVICES=6 python main.py --listen
   
CUDA_VISIBLE_DEVICES=6 python main.py --listen --enable-cors
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;em&gt;程序开始运行。现在，您可以“脱离”这个会话了。&lt;/em&gt;&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;&lt;strong&gt;按 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Ctrl + A&lt;/code&gt;，然后松开，再按 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;D&lt;/code&gt;。&lt;/strong&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;em&gt;您会返回主终端，看到 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[detached]&lt;/code&gt;。程序已在后台运行，您可以关闭 SSH 了。&lt;/em&gt;&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h4 id=&quot;3-日常维护&quot;&gt;3. 日常维护&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;如何重连会话 (查看日志/停止程序):&lt;/strong&gt;&lt;/p&gt;

    &lt;p&gt;Bash&lt;/p&gt;

    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;screen -r comfyui
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;

    &lt;ul&gt;
      &lt;li&gt;&lt;em&gt;您会瞬间跳回 ComfyUI 的日志界面。按 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Ctrl + C&lt;/code&gt; 即可停止。&lt;/em&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;如何更新 ComfyUI:&lt;/strong&gt;&lt;/p&gt;

    &lt;ol&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;screen -r comfyui&lt;/code&gt; (重连)&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Ctrl + C&lt;/code&gt; (停止)&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git pull&lt;/code&gt; (更新 ComfyUI 代码)&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;source ../venv/bin/activate&lt;/code&gt; (激活环境)&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pip install -r requirements.txt -i ...&lt;/code&gt; (更新依赖)&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CUDA_VISIBLE_DEVICES=6 python main.py --listen&lt;/code&gt; (重新启动)&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Ctrl + A, D&lt;/code&gt; (脱离)&lt;/li&gt;
    &lt;/ol&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;如何查看所有 screen 会话：&lt;/strong&gt;&lt;/p&gt;

    &lt;p&gt;Bash&lt;/p&gt;

    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;screen -ls
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;-七常见问题-qa&quot;&gt;❓ 七、常见问题 (Q&amp;amp;A)&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Q: 提示 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Some Nodes Are Missing&lt;/code&gt; (缺少节点)?&lt;/strong&gt;
    &lt;ul&gt;
      &lt;li&gt;&lt;strong&gt;A:&lt;/strong&gt; 见【五.3】。&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git clone&lt;/code&gt; 节点到 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;custom_nodes&lt;/code&gt;，然后 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cd&lt;/code&gt; 进去 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pip install -r requirements.txt&lt;/code&gt;。&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Q: 我要 T2V，为什么提示我上传视频?&lt;/strong&gt;
    &lt;ul&gt;
      &lt;li&gt;&lt;strong&gt;A:&lt;/strong&gt; 您拖入了错误的工作流 (如 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;wan2.1-fun.json&lt;/code&gt;)。T2V 请使用 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;wan_t2v.json&lt;/code&gt; 工作流。&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Fri, 10 Oct 2025 00:00:00 +0000</pubDate>
        <link>https://guanlili.github.io/2025/10/10/%E5%AE%9E%E6%88%98%E5%85%A5%E9%97%A8-%E5%9C%A8%E6%9C%8D%E5%8A%A1%E5%99%A8%E5%8D%95%E5%8D%A1%E9%83%A8%E7%BD%B2-ComfyUI-+-Wan2.1-%E6%96%87%E7%94%9F%E8%A7%86%E9%A2%91%E6%9C%80%E4%BD%B3%E5%AE%9E%E8%B7%B5/</link>
        <guid isPermaLink="true">https://guanlili.github.io/2025/10/10/%E5%AE%9E%E6%88%98%E5%85%A5%E9%97%A8-%E5%9C%A8%E6%9C%8D%E5%8A%A1%E5%99%A8%E5%8D%95%E5%8D%A1%E9%83%A8%E7%BD%B2-ComfyUI-+-Wan2.1-%E6%96%87%E7%94%9F%E8%A7%86%E9%A2%91%E6%9C%80%E4%BD%B3%E5%AE%9E%E8%B7%B5/</guid>
        
        <category>AI</category>
        
        <category>ComfyUI</category>
        
        
      </item>
    
      <item>
        <title>🚀 实战部署：单卡4090跑通DeepSeek-OCR本地WebUI</title>
        <description>&lt;h2 id=&quot;-实战部署单卡4090跑通deepseek-ocr本地webui&quot;&gt;🚀 实战部署：单卡4090跑通DeepSeek-OCR本地WebUI&lt;/h2&gt;

&lt;p&gt;大家好！我是李梨。&lt;/p&gt;

&lt;p&gt;最近，我们想在本地的 4090 服务器上部署大名鼎鼎的 DeepSeek-OCR 模型，搭建一个内部的 WebUI 测试服务。我是个“小白”，本以为会很顺利，结果一路上遇到了各种“拦路虎”。&lt;/p&gt;

&lt;p&gt;这篇文章就是把我们从 0 到 1 成功运行的&lt;strong&gt;完整步骤&lt;/strong&gt;，以及（更重要的）&lt;strong&gt;所有报错和解决方案&lt;/strong&gt;，原汁原味地记录下来。&lt;/p&gt;

&lt;p&gt;如果你也是刚接触 AI 部署，这篇文章也许能帮你节省几个小时的“抓耳挠腮”时间！&lt;/p&gt;

&lt;h3 id=&quot;第一章基础环境准备-the-happy-path&quot;&gt;第一章：基础环境准备 (The “Happy Path”)&lt;/h3&gt;

&lt;p&gt;我们的目标是使用一个社区的 &lt;a href=&quot;https://github.com/newlxj/DeepSeek-OCR-Web-UI&quot;&gt;DeepSeek-OCR-Web-UI&lt;/a&gt; 项目，它提供了一个 Gradio 界面，比较简单易用。&lt;/p&gt;

&lt;h4 id=&quot;️-第-0-步-三件套-跑不了&quot;&gt;🛠️ 第 0 步: “三件套” 跑不了&lt;/h4&gt;

&lt;p&gt;在开始之前，确保你的 Linux 服务器（或本地电脑）装好了三样东西：&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;NVIDIA 驱动&lt;/strong&gt;：确保 4090 显卡驱动是最新的。&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Git&lt;/strong&gt;：用于下载代码。（&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sudo apt install git&lt;/code&gt;）&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Miniconda&lt;/strong&gt;：Python 环境管理的“神器”，避免把你电脑的 Python 环境搞乱。&lt;/li&gt;
&lt;/ol&gt;

&lt;h4 id=&quot;-第-1-步-创建一个干净的-python-沙盒&quot;&gt;📦 第 1 步: 创建一个干净的 Python “沙盒”&lt;/h4&gt;

&lt;p&gt;我们使用 Conda 来创建一个专门给 OCR 用的环境，这里我们用 Python 3.12。&lt;/p&gt;

&lt;p&gt;Bash&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;# 1. 创建一个叫 deepseek-ocr 的环境
conda create -n deepseek-ocr python=3.12 -y

# 2. 激活这个环境 (重要！后续所有命令都在这里执行)
conda activate deepseek-ocr

# 激活后，你的命令行前面会出现 (deepseek-ocr) 
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;-第-2-步-安装-pytorch-适配-4090-的核心&quot;&gt;🔥 第 2 步: 安装 PyTorch (适配 4090 的核心)&lt;/h4&gt;

&lt;p&gt;这是第一个关键点。4090 跑模型需要 CUDA，而 PyTorch 必须和 CUDA 版本匹配。我们选择一个稳定组合：PyTorch 2.6 + CUDA 11.8。&lt;/p&gt;

&lt;p&gt;Bash&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;# 直接运行这整条命令
pip install torch==2.6.0 torchvision==0.21.0 torchaudio==2.6.0 --index-url https://download.pytorch.org/whl/cu118
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;安装完成后，&lt;strong&gt;立即检查&lt;/strong&gt; PyTorch 能否“看到”你的 4090 显卡：&lt;/p&gt;

&lt;p&gt;Bash&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;python -c &quot;import torch; print(f&apos;CUDA 可用吗? {torch.cuda.is_available()}&apos;)&quot;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;[检查点]&lt;/strong&gt;：你&lt;strong&gt;必须&lt;/strong&gt;看到输出 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CUDA 可用吗? True&lt;/code&gt;。 如果是 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;False&lt;/code&gt;，停下来！检查你的 NVIDIA 驱动。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4 id=&quot;-第-3-步-下载模型本体&quot;&gt;🧠 第 3 步: 下载模型本体&lt;/h4&gt;

&lt;p&gt;模型文件很大，我们用 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;modelscope&lt;/code&gt; 工具下载。&lt;/p&gt;

&lt;p&gt;Bash&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;# 1. 安装下载工具
pip install modelscope

# 2. 下载模型 (注意！记住你下载的这个路径，后面要用)
# 我们把它下载到 /home/bjrbds/deepseek-ocr-model
modelscope download --model deepseek-ai/DeepSeek-OCR --local_dir /home/bjrbds/deepseek-ocr-model
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;-第-4-步-下载-webui-界面&quot;&gt;🌐 第 4 步: 下载 WebUI 界面&lt;/h4&gt;

&lt;p&gt;Bash&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;# 1. 回到你的主目录
cd ~

# 2. 下载 WebUI 项目代码
git clone https://github.com/newlxj/DeepSeek-OCR-Web-UI.git

# 3. 进入项目文件夹
cd DeepSeek-OCR-Web-UI
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;-第-5-步-安装-webui-的依赖&quot;&gt;🧩 第 5 步: 安装 WebUI 的依赖&lt;/h4&gt;

&lt;p&gt;Bash&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;# 1. 安装 requirements.txt 里写好的依赖
pip install -r requirements.txt

# 2. 单独安装 flash-attn (一个加速库)
pip install flash-attn==2.7.3 --no-build-isolation
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;️-第-6-步-告诉-webui-模型在哪&quot;&gt;✏️ 第 6 步: 告诉 WebUI 模型在哪&lt;/h4&gt;

&lt;p&gt;这是最后一步配置。编辑 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;start_ocr_webui.py&lt;/code&gt; 文件，告诉它我们第 3 步下载的模型路径。&lt;/p&gt;

&lt;p&gt;Bash&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;vim start_ocr_webui.py
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;找到第 26 行左右，把 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;self.model_path&lt;/code&gt; 改成你自己的路径：&lt;/p&gt;

&lt;p&gt;Python&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;# 原本:
# self.model_path = &apos;/path/to/your/DeepSeek-OCR&apos;

# 修改后 (使用你的真实路径):
self.model_path = &apos;/home/bjrbds/deepseek-ocr-model&apos;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;保存并退出 (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:wq&lt;/code&gt;)。&lt;/p&gt;

&lt;p&gt;好了！按照“剧本”，我们现在应该可以运行了： &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;python start_ocr_webui.py&lt;/code&gt; …然而，&lt;strong&gt;战斗才刚刚开始&lt;/strong&gt;。&lt;/p&gt;

&lt;h3 id=&quot;第二章小白踩坑实录-the-real-path&quot;&gt;第二章：小白“踩坑”实录 (The “Real Path”)&lt;/h3&gt;

&lt;p&gt;我们遇到了 6 个拦路虎。如果你也遇到了，别慌，这里是答案。&lt;/p&gt;

&lt;h4 id=&quot;️-坑-1-modulenotfounderror-no-module-named-typer&quot;&gt;🕳️ 坑 1: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ModuleNotFoundError: No module named &apos;typer&apos;&lt;/code&gt;&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;报错日志：&lt;/strong&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;import typer&lt;/code&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ModuleNotFoundError: No module named &apos;typer&apos;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;分析&lt;/strong&gt;：很明显，&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;requirements.txt&lt;/code&gt; 里漏掉了一个 Gradio 依赖的包。 &lt;strong&gt;✅ 解决&lt;/strong&gt;：手动装上它。&lt;/p&gt;

&lt;p&gt;Bash&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;pip install typer
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;️-坑-2-pip-说装了python-说没有&quot;&gt;🕳️ 坑 2: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pip&lt;/code&gt; 说”装了”，Python 说”没有”？&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;诡异现象&lt;/strong&gt;： 我运行 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pip install typer&lt;/code&gt;，它提示 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Requirement already satisfied&lt;/code&gt; (已经满足)。 但我再运行 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;python start_ocr_webui.py&lt;/code&gt;，&lt;strong&gt;它还是报 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;No module named &apos;typer&apos;&lt;/code&gt;&lt;/strong&gt;！&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;分析&lt;/strong&gt;：这是个经典的 Python 环境冲突。&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pip&lt;/code&gt; 在你的用户目录 (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;~/.local/lib...&lt;/code&gt;) 找到了 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;typer&lt;/code&gt;，就“偷懒”了。但我们 Conda 环境里的 Python 只在自己的环境目录 (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;~/.conda/envs/deepseek-ocr/lib...&lt;/code&gt;) 里找。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;✅ 解决&lt;/strong&gt;：强制 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pip&lt;/code&gt; 在&lt;strong&gt;当前环境&lt;/strong&gt;里重新安装。&lt;/p&gt;

&lt;p&gt;Bash&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;pip install --ignore-installed typer
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;️-坑-3-typeerror-argument-of-type-bool-is-not-iterable&quot;&gt;🕳️ 坑 3: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TypeError: argument of type &apos;bool&apos; is not iterable&lt;/code&gt;&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;报错日志&lt;/strong&gt;： 一长串 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gradio&lt;/code&gt; 和 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gradio_client&lt;/code&gt; 的报错，最后指向 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TypeError: argument of type &apos;bool&apos; is not iterable&lt;/code&gt;。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;分析&lt;/strong&gt;：这是 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gradio&lt;/code&gt; 库的一个 Bug，它和我们用的 Python 3.12 或其他库不兼容。 &lt;strong&gt;✅ 解决&lt;/strong&gt;：升级 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gradio&lt;/code&gt; 库到最新版。&lt;/p&gt;

&lt;p&gt;Bash&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;pip install --upgrade gradio gradio_client
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;️-坑-4-模型加载失败-incorrect-path_or_model_id&quot;&gt;🕳️ 坑 4: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;模型加载失败: Incorrect path_or_model_id&lt;/code&gt;&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;报错日志&lt;/strong&gt;： &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;模型加载失败: Incorrect path_or_model_id: &apos;/home/bjrbds/deepseek-ocr-model/DeepSeek-OCR&apos;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;分析&lt;/strong&gt;：我在第 6 步改配置时&lt;strong&gt;画蛇添足&lt;/strong&gt;了。我以为模型在 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;deepseek-ocr-model&lt;/code&gt; 文件夹 &lt;em&gt;里面&lt;/em&gt; 的 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DeepSeek-OCR&lt;/code&gt; 文件夹里。 但 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;modelscope&lt;/code&gt; 已经把所有文件（&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;config.json&lt;/code&gt; 等）&lt;strong&gt;直接&lt;/strong&gt;下载到了 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;deepseek-ocr-model&lt;/code&gt; 根目录。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;✅ 解决&lt;/strong&gt;：重新编辑 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vim start_ocr_webui.py&lt;/code&gt;，把路径改对。&lt;/p&gt;

&lt;p&gt;Python&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;# 错误路径: self.model_path = &apos;/home/bjrbds/deepseek-ocr-model/DeepSeek-OCR&apos;
# 正确路径:
self.model_path = &apos;/home/bjrbds/deepseek-ocr-model&apos;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;(顺便：在解决这个问题的过程中，我们还遇到了一个 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pillow&lt;/code&gt; 库的版本警告，用 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pip install --upgrade pillow&lt;/code&gt; 顺手解决了。)&lt;/em&gt;&lt;/p&gt;

&lt;h3 id=&quot;第三章让服务活下去-后台运行与日志&quot;&gt;第三章：让服务“活下去” (后台运行与日志)&lt;/h3&gt;

&lt;p&gt;我们总不能一直开着这个黑窗口（终端）。我们需要让它在后台稳定运行，并且把日志记录下来。&lt;/p&gt;

&lt;p&gt;我选择了最简单粗暴的 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nohup&lt;/code&gt; 命令。&lt;/p&gt;

&lt;h4 id=&quot;-启动&quot;&gt;🚀 启动！&lt;/h4&gt;

&lt;ol&gt;
  &lt;li&gt;确保你在 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;(deepseek-ocr)&lt;/code&gt; 环境下。&lt;/li&gt;
  &lt;li&gt;确保你在项目目录 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/home/bjrbds/DeepSeek-OCR-Web-UI&lt;/code&gt;。&lt;/li&gt;
  &lt;li&gt;执行下面这条“天书”一样的命令：&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Bash&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;nohup /home/bjrbds/.conda/envs/deepseek-ocr/bin/python start_ocr_webui.py &amp;gt; /home/bjrbds/DeepSeek-OCR-Web-UI/ocr-webui.log 2&amp;gt;&amp;amp;1 &amp;amp;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;-天书翻译&quot;&gt;📖 “天书”翻译&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nohup ... &amp;amp;&lt;/code&gt;：&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nohup&lt;/code&gt; (No Hang Up) 和 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;amp;&lt;/code&gt; 组合，让命令在后台运行，你关掉终端它也不死。&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/home/bjrbds/.conda/envs/deepseek-ocr/bin/python&lt;/code&gt;：&lt;strong&gt;[重点]&lt;/strong&gt; 我们不能只写 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;python&lt;/code&gt;，必须用 Conda 环境里那个 Python 的&lt;strong&gt;绝对路径&lt;/strong&gt;，&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nohup&lt;/code&gt; 才能找对环境。&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;gt; .../ocr-webui.log&lt;/code&gt;：把所有正常的日志 (stdout) 输出到 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ocr-webui.log&lt;/code&gt; 这个文件里。&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2&amp;gt;&amp;amp;1&lt;/code&gt;：把所有错误日志 (stderr) 也合并 ( &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;amp;1&lt;/code&gt;) 到和正常日志 (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2&amp;gt;&lt;/code&gt;) 一样的文件里。&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;-后续管理&quot;&gt;🏡 后续管理&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;怎么看日志？&lt;/strong&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tail -f /home/bjrbds/DeepSeek-OCR-Web-UI/ocr-webui.log&lt;/code&gt; (按 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Ctrl+C&lt;/code&gt; 退出查看)&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;怎么停掉它？&lt;/strong&gt;&lt;/p&gt;

    &lt;p&gt;Bash&lt;/p&gt;

    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;# 1. 找到它的进程号 (PID)
ps aux | grep start_ocr_webui.py
# 2. 杀死它 (假设 PID 是 12345)
kill 12345
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;总结&quot;&gt;总结&lt;/h3&gt;

&lt;p&gt;我们成功了！&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://blog-1258476669.cos.ap-beijing.myqcloud.com/bjrb/image-20251118212853528.png?imageSlim&quot; alt=&quot;image-20251118212853528&quot; /&gt;&lt;/p&gt;

&lt;p&gt;这次部署虽然曲折，但非常有价值。我们不仅让 DeepSeek-OCR 跑了起来，还亲手解决了 Python 环境冲突、&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gradio&lt;/code&gt; Bug、模型路径错误、以及最关键的“CPU 假运行”问题。&lt;/p&gt;

&lt;p&gt;希望这篇“踩坑”日记能帮到你！&lt;/p&gt;
</description>
        <pubDate>Wed, 01 Oct 2025 00:00:00 +0000</pubDate>
        <link>https://guanlili.github.io/2025/10/01/%E5%AE%9E%E6%88%98%E9%83%A8%E7%BD%B2-%E5%8D%95%E5%8D%A14090%E8%B7%91%E9%80%9ADeepSeek-OCR%E6%9C%AC%E5%9C%B0WebUI/</link>
        <guid isPermaLink="true">https://guanlili.github.io/2025/10/01/%E5%AE%9E%E6%88%98%E9%83%A8%E7%BD%B2-%E5%8D%95%E5%8D%A14090%E8%B7%91%E9%80%9ADeepSeek-OCR%E6%9C%AC%E5%9C%B0WebUI/</guid>
        
        <category>AI</category>
        
        <category>OCR</category>
        
        
      </item>
    
      <item>
        <title>队长别开枪！Java硬接AI模型当场暴毙，我用这套方案救回了项目</title>
        <description>&lt;h2 id=&quot;队长别开枪java硬接ai模型当场暴毙我用这套方案救回了项目&quot;&gt;&lt;strong&gt;队长别开枪！Java硬接AI模型当场暴毙，我用这套方案救回了项目&lt;/strong&gt;&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;一个 AI 工程师的“吐槽”，以及 Java 与 Python“异地恋”的正确姿势&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;大家好，我是、小李。&lt;/p&gt;

&lt;p&gt;最近我们团队春风得意，老板“王总”开完会回来，红光满面地拍着我的肩膀说：“小李啊，最近 AI 很火，你给咱们的 RuoYi 框架也整上！就那个，文生视频！明天能上线不？”&lt;/p&gt;

&lt;p&gt;我（面带微笑，内心 M**）：”王总…这…这Java…和Python…它俩…”&lt;/p&gt;

&lt;p&gt;如果你也是一名 Java 工程师或 AI 工程师，你一定懂我的痛。&lt;/p&gt;

&lt;p&gt;我们的 RuoYi 框架（或者 Jeecg、Spring Boot）是 Java 界的“三好学生”，严谨、稳定、企业级。而 AI 模型（PyTorch、Diffusers）是 Python 界的“艺术生”，自由、奔放、贼耗资源。&lt;/p&gt;

&lt;p&gt;你让三好学生去管艺术生…这不出事才怪！&lt;/p&gt;

&lt;p&gt;这篇文章，就是我这个 AI 工程师的“血泪史”，分享一下踩坑无数后，我们是怎么让 Java 和 Python 这对“欢喜冤家”和平共处，还顺便把性能拉满的。&lt;/p&gt;

&lt;h3 id=&quot;坑一天真的跨国直连--java-exec-python-脚本&quot;&gt;坑一：天真的“跨国直连” —— Java &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;exec&lt;/code&gt; Python 脚本&lt;/h3&gt;

&lt;p&gt;最开始，我们的 Java 队长（一个资深 Java 架构师）提出了一个“天真”的方案：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;“不就是调个 Python 吗？我用 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ProcessBuilder.command(&quot;python&quot;, &quot;run_video.py&quot;, &quot;一只猫&quot;)&lt;/code&gt;，分分钟搞定！”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;兄弟，&lt;strong&gt;千万别！&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;你知道这行命令背后发生了什么吗？&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;用户点击“生成”。&lt;/li&gt;
  &lt;li&gt;Java 启动一个全新的 Python 进程（&lt;strong&gt;冷启动&lt;/strong&gt;）。&lt;/li&gt;
  &lt;li&gt;Python 颤颤巍巍地开始加载十几 GB 的文生视频模型（&lt;strong&gt;加载中…&lt;/strong&gt;）。&lt;/li&gt;
  &lt;li&gt;GPU 预热，申请显存（&lt;strong&gt;加载中…&lt;/strong&gt;）。&lt;/li&gt;
  &lt;li&gt;30 秒过去了，模型终于加载完了，开始吭哧吭哧地算（&lt;strong&gt;生成中…&lt;/strong&gt;）。&lt;/li&gt;
  &lt;li&gt;又 30 秒过去了，视频生成了，Python 进程退出，GPU 资源释放。&lt;/li&gt;
  &lt;li&gt;Java 端：“太好了，我终于拿到这个…等等，我的 HTTP 请求呢？”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;你的用户请求早就在 30 秒前超时了！&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;更要命的是，GPU 是“独占”的。当第一个用户在“炼丹”时，第二个用户只能在旁边排队干瞪眼。如果 10 个人同时点，你的 RuoYi 服务器会直接卡死，当场给王总表演一个“服务器宕机”。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;结论：&lt;/strong&gt; AI 模型不是一个“函数”，它是一个“服务”。我们不能每次都请它“出山”，得让它“常驻”。&lt;/p&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;坑二异地恋的正确姿势--异步与解耦&quot;&gt;坑二：异地恋的正确姿势 —— “异步”与”解耦”&lt;/h3&gt;

&lt;p&gt;重型 AI 任务（文生图/视频）是“慢”任务。对付“慢”任务，唯一的办法就是&lt;strong&gt;“异步”&lt;/strong&gt;。&lt;/p&gt;

&lt;p&gt;你不能让 Java 队长在原地傻等 Python 艺术生画完画。&lt;/p&gt;

&lt;p&gt;正确的姿势是引入一个“传话筒”—— &lt;strong&gt;消息队列 (MQ)&lt;/strong&gt;，比如 RabbitMQ 或 Redis。&lt;/p&gt;

&lt;p&gt;我们的架构变成了“智能餐厅”模式：&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;RuoYi (Java 端) 成了“服务员”&lt;/strong&gt;：
    &lt;ul&gt;
      &lt;li&gt;用户（顾客）点了个“红烧 AI 视频”。&lt;/li&gt;
      &lt;li&gt;RuoYi（服务员）接过菜单（&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;prompt&lt;/code&gt;），转身贴在后厨的“订单墙”（&lt;strong&gt;RabbitMQ&lt;/strong&gt;）上。&lt;/li&gt;
      &lt;li&gt;服务员立刻回头对顾客说：“好嘞！您的订单（&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;task_id&lt;/code&gt;）已提交，后厨正在做！”&lt;/li&gt;
      &lt;li&gt;（RuoYi 瞬间响应，一点都不卡！）&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;AI Worker (Python 端) 成了“后厨大厨”&lt;/strong&gt;：
    &lt;ul&gt;
      &lt;li&gt;大厨（Python 脚本）正闲着呢，一抬头看到“订单墙”上有新活了。&lt;/li&gt;
      &lt;li&gt;他美滋滋地接下单子，开始点火、倒油、开“炼”（GPU 启动）。&lt;/li&gt;
      &lt;li&gt;这个菜（视频）要炒 1 分钟，没关系，餐厅（RuoYi）还在正常营业，服务员还在接新单子。&lt;/li&gt;
      &lt;li&gt;炒完后，大厨把菜（视频文件）放到“出菜口”（&lt;strong&gt;MinIO 对象存储&lt;/strong&gt;），并在数据库里把这个 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;task_id&lt;/code&gt; 标记为“已完成”。&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;前端 (Vue) 成了“着急的顾客”&lt;/strong&gt;：
    &lt;ul&gt;
      &lt;li&gt;顾客（前端）每 5 秒问一次服务员：“我的菜好了吗？”（前端轮询 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;task_id&lt;/code&gt; 状态）。&lt;/li&gt;
      &lt;li&gt;服务员（RuoYi）就去数据库查一下，直到发现“已完成”，立刻把“出菜口”的 URL 端给顾客。&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;好处：&lt;/strong&gt; RuoYi 和 AI 服务彻底解耦！就算 AI 后厨着火了（OOM 显存爆炸），RuoYi 前厅依然歌舞升平，继续接客。这才叫“企业级”！&lt;/p&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;坑三后厨管理--ai-网关到底谁来当&quot;&gt;坑三：后厨管理 —— “AI 网关”到底谁来当？&lt;/h3&gt;

&lt;p&gt;好了，现在后厨（AI Worker）独立了，但后厨里可能不止一个厨子啊！&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;有炒“文生视频”的（Wan2.1）&lt;/li&gt;
  &lt;li&gt;有烤“文生图”的（Stable Diffusion）&lt;/li&gt;
  &lt;li&gt;还有个“云厨子”（智谱 API）&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;RuoYi 不想管这么细，它只想把订单扔给“后厨总管”（AI 网关），让总管自己去分配。&lt;/p&gt;

&lt;p&gt;这个“总管”用谁来当？两个主流候选人：&lt;strong&gt;FastAPI&lt;/strong&gt; 和 &lt;strong&gt;LangChain&lt;/strong&gt;。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;候选人 A：LangChain&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;简历：&lt;/strong&gt; 博士学位，AI 界的“当红炸子鸡”，精通 RAG、Agents，能说会道（LLM 编排大师）。&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;面试表现：&lt;/strong&gt; 当我们让它去管理“文生视频”厨子时，它懵了。&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;LangChain：&lt;/strong&gt; “等等…这个厨子（Wan2.1）的 Prompt 模板是啥？他的输出怎么不是 JSON？我怎么给他挂载向量数据库？”&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;结论：&lt;/strong&gt; LangChain 是个“文科状元”，你让它去管“文本后厨”（LLM）是天作之合。但你让它去管“视频/图像”这种多模态后厨，它自己都得先学怎么使唤，太别扭了！&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;候选人 B：FastAPI&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;简历：&lt;/strong&gt; 高中毕业，但干了 10 年“物流总管”，快如闪电，极其务实。&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;面试表现：&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;FastAPI：&lt;/strong&gt; “哦，这个是视频单？扔给 1 号厨子（本地 Wan2.1）。这个是 API 单？我打个电话给云厨子（智谱）。这个是图片单？扔给 2 号厨子（本地 SD）。搞定。”&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;结论：&lt;/strong&gt; FastAPI 是个纯粹的“接入层”和“路由器”。它不关心 AI 模型是啥，只负责把活儿分下去。&lt;strong&gt;这不就是我们网关想要的吗！&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;胜出：&lt;/strong&gt; &lt;strong&gt;FastAPI&lt;/strong&gt;。我们用 FastAPI 来当我们的 AI 网关总管。&lt;/p&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;坑四后厨的装备--运行器用啥&quot;&gt;坑四：后厨的装备 —— “运行器”用啥？&lt;/h3&gt;

&lt;p&gt;总管（FastAPI）选好了，那厨子们（本地模型）在什么样的“灶台”（运行器）上干活呢？&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;方案一：DIY 灶台 (也用 FastAPI)&lt;/strong&gt;
    &lt;ul&gt;
      &lt;li&gt;就是让厨子自己搭个灶台。&lt;/li&gt;
      &lt;li&gt;&lt;strong&gt;问题：&lt;/strong&gt; 就像给米其林大厨一个“单眼电磁炉”。GPU（灶台）很贵很强大，但一次只能炒一个菜。你来了 10 个“文生图”订单，他就得一个一个炒，GPU 利用率低得可怜，吞吐量是灾难。&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;方案二：航母级灶台 (NVIDIA Triton)&lt;/strong&gt;
    &lt;ul&gt;
      &lt;li&gt;NVIDIA 官方出品，C++ 核心，性能核弹。&lt;/li&gt;
      &lt;li&gt;&lt;strong&gt;问题：&lt;/strong&gt; 安装配置手册是“天书”。等你看懂手册（&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;config.pbtxt&lt;/code&gt;），王总的项目都黄了。这是“配置地狱”。&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;方案三：专业级中央厨房 (BentoML)&lt;/strong&gt;
    &lt;ul&gt;
      &lt;li&gt;Python 优先，专为 AI 应用打包和部署而生。&lt;/li&gt;
      &lt;li&gt;它有个独门绝技：&lt;strong&gt;“动态批处理 (Dynamic Batching)”&lt;/strong&gt;。&lt;/li&gt;
      &lt;li&gt;&lt;strong&gt;翻译一下：&lt;/strong&gt;
        &lt;ul&gt;
          &lt;li&gt;DIY 厨子：来了 10 份“炒土豆丝”，他得炒 10 锅。&lt;/li&gt;
          &lt;li&gt;BentoML 厨子：来了 10 份“炒土豆丝”，他直接把 10 份的土豆丝&lt;strong&gt;倒进一个大锅里一起炒了！&lt;/strong&gt;（把 10 个请求合并成一个 Batch 喂给 GPU）。&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;GPU（大锅）一次就干完了 10 份的活，利用率 100%！然后再把菜（结果）分回 10 个盘子。&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;胜出：&lt;/strong&gt; &lt;strong&gt;BentoML&lt;/strong&gt;。它在“易用性”和“高性能”之间取得了完美的平衡。&lt;/p&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;最终的梦之队架构&quot;&gt;最终的“梦之队”架构&lt;/h3&gt;

&lt;p&gt;好了，我们的 Java 和 AI 联姻的“梦之队”诞生了：&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;门面担当 (Java 业务层)&lt;/strong&gt;: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RuoYi&lt;/code&gt;
    &lt;ul&gt;
      &lt;li&gt;职责：处理业务、权限，当个优雅的“服务员”。&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;传菜通道 (消息队列)&lt;/strong&gt;: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RabbitMQ&lt;/code&gt;
    &lt;ul&gt;
      &lt;li&gt;职责：任务解耦、排队、削峰填谷。&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;后厨总管 (AI 网关)&lt;/strong&gt;: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FastAPI (Python)&lt;/code&gt;
    &lt;ul&gt;
      &lt;li&gt;职责：监听 MQ，当“路由器”，把 AI 任务分发给正确的厨子。&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;专业厨房 (AI 运行器)&lt;/strong&gt;: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BentoML (Python)&lt;/code&gt;
    &lt;ul&gt;
      &lt;li&gt;职责：高性能运行本地的“文生图/视频”模型，开启“动态批处理”压榨 GPU。&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;菜品仓库 (对象存储)&lt;/strong&gt;: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MinIO&lt;/code&gt;
    &lt;ul&gt;
      &lt;li&gt;职责：存放所有 AI 生成的图片和视频。&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;这套架构下来，RuoYi 还是那个稳如老狗的 RuoYi，而 AI 在另一台服务器上玩命“炼丹”，互不打扰，丝般顺滑。&lt;/p&gt;

&lt;p&gt;王总看了看，露出了满意的微笑：“小管啊，这个月奖金…可以谈！”&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;希望这篇“不正经”的分享能帮到你。别再让 Java 和 Python 硬碰硬了，给它们一个舒服的“异地恋”环境吧！&lt;/p&gt;
</description>
        <pubDate>Mon, 01 Sep 2025 00:00:00 +0000</pubDate>
        <link>https://guanlili.github.io/2025/09/01/%E9%98%9F%E9%95%BF%E5%88%AB%E5%BC%80%E6%9E%AA-Java%E7%A1%AC%E6%8E%A5AI%E6%A8%A1%E5%9E%8B%E5%BD%93%E5%9C%BA%E6%9A%B4%E6%AF%99-%E6%88%91%E7%94%A8%E8%BF%99%E5%A5%97%E6%96%B9%E6%A1%88%E6%95%91%E5%9B%9E%E4%BA%86%E9%A1%B9%E7%9B%AE/</link>
        <guid isPermaLink="true">https://guanlili.github.io/2025/09/01/%E9%98%9F%E9%95%BF%E5%88%AB%E5%BC%80%E6%9E%AA-Java%E7%A1%AC%E6%8E%A5AI%E6%A8%A1%E5%9E%8B%E5%BD%93%E5%9C%BA%E6%9A%B4%E6%AF%99-%E6%88%91%E7%94%A8%E8%BF%99%E5%A5%97%E6%96%B9%E6%A1%88%E6%95%91%E5%9B%9E%E4%BA%86%E9%A1%B9%E7%9B%AE/</guid>
        
        <category>AI</category>
        
        <category>FastAPI</category>
        
        
      </item>
    
      <item>
        <title>高效 PDF 解析利器：MinerU 实战避坑与高精度调优指南</title>
        <description>&lt;h1 id=&quot;高效-pdf-解析利器mineru-实战避坑与高精度调优指南&quot;&gt;高效 PDF 解析利器：MinerU 实战避坑与高精度调优指南&lt;/h1&gt;

&lt;p&gt;在处理海量 PDF 文档（尤其是扫描件、统计年鉴或古籍方志）时，如何精准提取其中的文本和表格数据一直是个痛点。最近在服务器上部署并深入使用了 &lt;strong&gt;MinerU&lt;/strong&gt;，这是一款强大的开源 PDF 提取工具。&lt;/p&gt;

&lt;p&gt;在使用过程中，从环境配置到参数调优，我总结了一套“最佳实践”。本文将分享如何规避常见的环境坑，以及如何通过参数组合实现&lt;strong&gt;最高精度的中文识别&lt;/strong&gt;。&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;1-环境管理的第一信条&quot;&gt;1. 环境管理的“第一信条”&lt;/h2&gt;

&lt;p&gt;在使用 MinerU 之前，最容易被忽视的一步就是&lt;strong&gt;环境隔离&lt;/strong&gt;。&lt;/p&gt;

&lt;p&gt;很多时候我们会发现命令报错或者版本不对，原因往往是我们在默认的 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;(base)&lt;/code&gt; 环境中裸奔。为了保证工具的稳定性，&lt;strong&gt;必须&lt;/strong&gt;确保在独立的 Conda 环境中运行。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;❌ 错误姿势：&lt;/strong&gt; 直接在终端操作。 &lt;strong&gt;✅ 正确姿势：&lt;/strong&gt; 每次开始工作前，请务必激活专属环境：&lt;/p&gt;

&lt;p&gt;Bash&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;conda activate MinerU
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;当你的终端提示符从 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;(base)&lt;/code&gt; 变为 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;(MinerU)&lt;/code&gt; 时，才代表你进入了正确的工作区。&lt;/em&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;2-避坑指南pip-安装的正确姿势&quot;&gt;2. 避坑指南：Pip 安装的正确姿势&lt;/h2&gt;

&lt;p&gt;在多人共用的服务器环境下，直接使用 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pip install&lt;/code&gt; 经常会导致包被安装到用户主目录（&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;~/.local/&lt;/code&gt;）下，而不是我们激活的 Conda 环境中。这会导致严重的&lt;strong&gt;版本混乱&lt;/strong&gt;——明明安装了新版，运行的却是旧版。&lt;/p&gt;

&lt;p&gt;为了彻底解决这个问题，请养成使用 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;python -m pip&lt;/code&gt; 的习惯：&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;标准安装/升级命令：&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Bash&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;# 这种方式能确保 pip 是当前 Conda 环境下的 pip
python -m pip install --upgrade mineru

# 或者安装指定稳定版本（推荐）
python -m pip install mineru==2.2.2
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;3-基础使用与版本验证&quot;&gt;3. 基础使用与版本验证&lt;/h2&gt;

&lt;p&gt;环境准备好后，首先验证安装是否成功：&lt;/p&gt;

&lt;p&gt;Bash&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;mineru --version
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;基本解析命令：&lt;/strong&gt; 如果你只需要进行标准的文档解析，可以使用以下命令将 PDF 转换为 Markdown 或 JSON：&lt;/p&gt;

&lt;p&gt;Bash&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;# 示例：解析 report.pdf 并输出到 ./output 目录
mineru parse report.pdf --output_dir ./output
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;4-进阶调优如何处理复杂扫描件与表格&quot;&gt;4. 进阶调优：如何处理复杂扫描件与表格？&lt;/h2&gt;

&lt;p&gt;这是本文的&lt;strong&gt;核心干货&lt;/strong&gt;。&lt;/p&gt;

&lt;p&gt;如果你的目标是处理&lt;strong&gt;统计年鉴、地方志、旧文档扫描件&lt;/strong&gt;，或者对&lt;strong&gt;表格数据&lt;/strong&gt;的还原度有极高要求，默认的设置可能不够用。&lt;/p&gt;

&lt;p&gt;经过多次测试，建议使用以下“黄金组合”参数：&lt;/p&gt;

&lt;p&gt;Bash&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;mineru -p &amp;lt;PDF文件路径&amp;gt; -o &amp;lt;输出路径&amp;gt; --backend pipeline --lang ch_server
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;为什么选择这个组合&quot;&gt;为什么选择这个组合？&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--backend pipeline&lt;/code&gt; (结构化神器)&lt;/strong&gt; 这个后端模式是专门为精确提取&lt;strong&gt;表格、列表、段落&lt;/strong&gt;设计的。相比于通用的视觉模型（VLM），它拥有专门的表格识别模块，在处理密集数据表格时表现远超预期。&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--lang ch_server&lt;/code&gt; (精度优先)&lt;/strong&gt; 这是为了获得&lt;strong&gt;最高中文识别准确率&lt;/strong&gt;而设计的服务器级模型选项。
    &lt;ul&gt;
      &lt;li&gt;&lt;strong&gt;应对模糊字迹&lt;/strong&gt;：对于扫描件或图像质量不一的老旧文档，它的抗干扰能力最强。&lt;/li&gt;
      &lt;li&gt;&lt;strong&gt;严谨数据&lt;/strong&gt;：对于每一个数字都不能错的统计文档，这个选项能最大程度减少 OCR 幻觉。&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;5-常见故障排查-troubleshooting&quot;&gt;5. 常见故障排查 (Troubleshooting)&lt;/h2&gt;

&lt;p&gt;根据实战经验，如果你遇到以下问题，可以按此流程快速自救：&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Q1: 提示 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mineru: 未找到命令&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;检查&lt;/strong&gt;：你是否忘了运行 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;conda activate MinerU&lt;/code&gt;？&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;检查&lt;/strong&gt;：运行 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;which mineru&lt;/code&gt;，看系统是否找到了错误的路径。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Q2: 升级后版本号依然没变&lt;/strong&gt; 这通常是因为旧版本残留在 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;~/.local/bin&lt;/code&gt; 中，导致系统优先调用了旧版。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;解决方案&lt;/strong&gt;：执行“彻底清理-重装”流程。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Bash&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;# 1. 彻底卸载 (建议重复执行直到提示找不到包)
python -m pip uninstall mineru

# 2. 确认环境干净 (应提示 &quot;command not found&quot;)
mineru --version

# 3. 使用正确方式重装
python -m pip install mineru
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;结语&quot;&gt;结语&lt;/h3&gt;

&lt;p&gt;MinerU 是一个强大的工具，但只有配置好环境并选对参数，才能发挥它的最大威力。希望这份基于实战总结的指南，能帮助大家在处理文档解析任务时少走弯路，直接获取高质量的结构化数据。&lt;/p&gt;
</description>
        <pubDate>Wed, 20 Aug 2025 00:00:00 +0000</pubDate>
        <link>https://guanlili.github.io/2025/08/20/%E9%AB%98%E6%95%88-PDF-%E8%A7%A3%E6%9E%90%E5%88%A9%E5%99%A8-MinerU-%E5%AE%9E%E6%88%98%E9%81%BF%E5%9D%91%E4%B8%8E%E9%AB%98%E7%B2%BE%E5%BA%A6%E8%B0%83%E4%BC%98%E6%8C%87%E5%8D%97/</link>
        <guid isPermaLink="true">https://guanlili.github.io/2025/08/20/%E9%AB%98%E6%95%88-PDF-%E8%A7%A3%E6%9E%90%E5%88%A9%E5%99%A8-MinerU-%E5%AE%9E%E6%88%98%E9%81%BF%E5%9D%91%E4%B8%8E%E9%AB%98%E7%B2%BE%E5%BA%A6%E8%B0%83%E4%BC%98%E6%8C%87%E5%8D%97/</guid>
        
        <category>AI</category>
        
        <category>学习笔记</category>
        
        <category>OCR</category>
        
        
      </item>
    
      <item>
        <title>我刚拿到了8卡GPU服务器的钥匙，现在我慌得一批……”</title>
        <description>&lt;h1 id=&quot;我刚拿到了8卡gpu服务器的钥匙现在我慌得一批&quot;&gt;&lt;strong&gt;我刚拿到了8卡GPU服务器的钥匙，现在我慌得一批……&lt;/strong&gt;&lt;/h1&gt;

&lt;p&gt;一个“小白”的GPU服务器“踩坑”与“爬坑”指南&lt;/p&gt;

&lt;p&gt;朋友们，就在今天，我的人生（职业生涯）达到了一个小高峰。&lt;/p&gt;

&lt;p&gt;我拿到了团队一台全新8卡GPU服务器（8 x RTX 4090）的&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ssh&lt;/code&gt;登录权限。&lt;/p&gt;

&lt;p&gt;我的第一反应是：“不就是一台CPU核多一点、内存大一点的Linux服务器吗？&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ssh&lt;/code&gt;连上去，&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;htop&lt;/code&gt;跑起来，我就是这台机器的王！”&lt;/p&gt;

&lt;p&gt;然而，当我输入&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nvidia-smi&lt;/code&gt;并看到我同事的进程（&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Xinf vLLM worker&lt;/code&gt;）密密麻麻地占满了 6 张卡时，我才意识到——&lt;/p&gt;

&lt;p&gt;事情没那么简单。&lt;/p&gt;

&lt;p&gt;我不是王。在这台机器上，我充其量算是个“新来的租客”。管理这台机器，和我管理一台普通的Linux Web服务器，&lt;strong&gt;压根不是一回事&lt;/strong&gt;。&lt;/p&gt;

&lt;p&gt;如果你也像我一样，刚拿到这“核武器的发射按钮”却不知道怎么用，这篇笔记就是为你准备的。&lt;/p&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;-区别一思维转变你管理的不是厨房是停车场&quot;&gt;🧠 区别一：思维转变！你管理的不是“厨房”，是“停车场”&lt;/h3&gt;

&lt;p&gt;这是我学到的&lt;strong&gt;第一个痛彻心扉的区别&lt;/strong&gt;。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;普通Linux服务器（比如Web服务器）：&lt;/strong&gt;
    &lt;ul&gt;
      &lt;li&gt;它就像一个&lt;strong&gt;“共享厨房”&lt;/strong&gt;（CPU和内存）。&lt;/li&gt;
      &lt;li&gt;张三在用微波炉（一个CPU核心），李四在用另一个灶台（另一个CPU核心）。大家可以同时用，互不干扰。CPU是一种可以&lt;strong&gt;“分时共享”&lt;/strong&gt;的资源。我们最关心的是&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;htop&lt;/code&gt;里的CPU占用率别到100%。&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;GPU服务器（我这台）：&lt;/strong&gt;
    &lt;ul&gt;
      &lt;li&gt;它更像一个&lt;strong&gt;“VIP停车库”&lt;/strong&gt;（GPU显存）。&lt;/li&gt;
      &lt;li&gt;每张GPU卡就是一排固定车位（比如24GB显存）。&lt;/li&gt;
      &lt;li&gt;我同事的LLM服务，就像一辆&lt;strong&gt;加长悍马&lt;/strong&gt;（&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Xinf vLLM worker&lt;/code&gt;）。它一停进来，就&lt;strong&gt;“哐”&lt;/strong&gt;地一下占满了0、1、2、3号车位（GPU 0-3）。&lt;/li&gt;
      &lt;li&gt;&lt;strong&gt;关键来了：&lt;/strong&gt; 显存（VRAM）是&lt;strong&gt;“独占”&lt;/strong&gt;的！一个车位被占了，你就不能再往里塞任何东西。哪怕那辆悍马只占了23.8GB，你也不能把你那1GB的“小电驴”（小模型）塞进那剩下的0.2GB空隙里。&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;管理思维转变：&lt;/strong&gt; 在普通服务器，我关心“CPU别累死”。在GPU服务器，我关心“&lt;strong&gt;显存（车位）还够不够分？&lt;/strong&gt;”&lt;/p&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;-区别二体检工具升级从htop到nvidia-smi&quot;&gt;🩺 区别二：体检工具升级！从&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;htop&lt;/code&gt;到&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nvidia-smi&lt;/code&gt;&lt;/h3&gt;

&lt;p&gt;在普通Linux上，&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;htop&lt;/code&gt;就是我的“听诊器”。&lt;/p&gt;

&lt;p&gt;但在GPU服务器上，&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;htop&lt;/code&gt;只能算“量个血压”（看CPU和内存）。你真正的“心电图（EKG）”是&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nvidia-smi&lt;/code&gt;。&lt;/p&gt;

&lt;p&gt;但&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nvidia-smi&lt;/code&gt;本身只是个“静态快照”。你要用这个：&lt;/p&gt;

&lt;p&gt;Bash 猛击&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;watch -n 1 nvidia-smi
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;朋友们，&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;watch -n 1&lt;/code&gt;（每秒刷新一次）才是灵魂！它把静态的心电图照片变成了&lt;strong&gt;实时的心电监护仪&lt;/strong&gt;。&lt;/p&gt;

&lt;p&gt;你必须实时盯着两个指标：&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Memory-Usage&lt;/code&gt; (显存占用)&lt;/strong&gt;：你的“车位”还剩多少？&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GPU-Util&lt;/code&gt; (计算利用率)&lt;/strong&gt;：如果显存满了（车停进去了），但这玩意儿是 0%，说明司机（程序）在车里睡着了（卡在CPU数据预处理），GPU在“摸鱼”！&lt;/li&gt;
&lt;/ol&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;-区别三生存法则从我的地盘到合租公寓&quot;&gt;🔑 区别三：生存法则！从“我的地盘”到“合租公寓”&lt;/h3&gt;

&lt;p&gt;这台8卡服务器就是一间“合租公寓”，你和你的同事都是租客。为了不被同事“真人PK”，你必须遵守“合租条约”。&lt;/p&gt;

&lt;h4 id=&quot;合租条约a环境隔离别用公用牙刷&quot;&gt;合租条约A：环境隔离（“别用公用牙刷！”）&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;问题：&lt;/strong&gt; 服务器的 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;(base)&lt;/code&gt; 环境，就像是公寓里那支&lt;strong&gt;公用的牙刷&lt;/strong&gt;。&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;场景：&lt;/strong&gt; 你同事的LLM服务需要 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PyTorch 2.1&lt;/code&gt;（薄荷味牙膏）。你新来的视频模型要用 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PyTorch 2.3&lt;/code&gt;（草莓味牙膏）。&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;你做了什么：&lt;/strong&gt; 你在 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;(base)&lt;/code&gt; 环境里 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pip install --upgrade torch&lt;/code&gt;。&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;后果：&lt;/strong&gt; 你把牙刷和牙膏全换了。你同事的服务&lt;strong&gt;“哐”&lt;/strong&gt;的一声就崩了。他会顺着网线来找你。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;正确做法（Conda / Venv）：&lt;/strong&gt; &lt;strong&gt;永远别用公用牙刷！&lt;/strong&gt; 用 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;conda&lt;/code&gt; 给自己创建一个“专属洗漱包”：&lt;/p&gt;

&lt;p&gt;Bash 猛击&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;# 1. 创建你的专属小天地
conda create -n my_video_env python=3.10

# 2. 激活它（拉上帘子）
conda activate my_video_env

# 3. 在里面随便折腾！爱用什么味牙膏都行！
pip install torch==2.3 ...
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;合租条约bgpu隔离戴上你的魔法眼罩&quot;&gt;合租条约B：GPU隔离（“戴上你的‘魔法眼罩’”）&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;问题：&lt;/strong&gt; 你登录进来，默认能看到所有8张卡（0-7号房）。你一跑程序，它默认就想冲进 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GPU 0&lt;/code&gt;（0号房），那里已经住了你同事的“悍马”！&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;解决方案：&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CUDA_VISIBLE_DEVICES&lt;/code&gt;&lt;/strong&gt; 这是我学到的&lt;strong&gt;最强黑魔法&lt;/strong&gt;。它是一个环境变量，就像一副“魔法眼罩”。&lt;/p&gt;

    &lt;p&gt;在你的终端里输入：&lt;/p&gt;

    &lt;p&gt;Bash 猛击&lt;/p&gt;

    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;# 关键！戴上眼罩！
export CUDA_VISIBLE_DEVICES=6,7
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;

    &lt;p&gt;奇迹发生了：&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;你的程序（PyTorch等）被“骗”了。它以为这台服务器&lt;strong&gt;总共就只有2张卡&lt;/strong&gt;。&lt;/li&gt;
      &lt;li&gt;它会把你物理上的 &lt;strong&gt;GPU 6&lt;/strong&gt;（6号房）当作 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cuda:0&lt;/code&gt;（它眼里的0号房）。&lt;/li&gt;
      &lt;li&gt;它会把你物理上的 &lt;strong&gt;GPU 7&lt;/strong&gt;（7号房）当作 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cuda:1&lt;/code&gt;（它眼里的1号房）。&lt;/li&gt;
    &lt;/ul&gt;

    &lt;p&gt;现在，你让程序“去0号房”，它就会乖乖地走进物理上的6号房，完美避开了你同事！&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;-终极方案酒店管家-xinference--bentoml&quot;&gt;🤵 终极方案：“酒店管家” (Xinference / BentoML)&lt;/h3&gt;

&lt;p&gt;学完上面那些，我感觉自己像个“DIY修理工”。&lt;/p&gt;

&lt;p&gt;但其实，我（和我的同事）正在用一种更高级的玩法：&lt;strong&gt;调度框架 (Xinference)&lt;/strong&gt;。&lt;/p&gt;

&lt;p&gt;Xinference 就像一个“五星级酒店管家”。&lt;/p&gt;

&lt;p&gt;我根本不需要自己去设置“魔法眼罩”，我只需要在它的UI界面上点一下（或者用Python API告诉它）：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;“管家（Xinference），我要部署 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Wan2.1-14B&lt;/code&gt; 这个模型，请把它安排到 &lt;strong&gt;GPU 6 和 7&lt;/strong&gt; 这两个套间里。”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;“管家”会帮我搞定所有事：模型下载、环境配置、GPU隔离、启动进程，并给我一个API地址。我直接访问API就能用我的视频模型了。&lt;/p&gt;

&lt;p&gt;这，才是我这种“小白”该有的、体面的入门方式！&lt;/p&gt;

&lt;h3 id=&quot;总结附赠一个忠告&quot;&gt;总结（附赠一个忠告）&lt;/h3&gt;

&lt;p&gt;管理一台GPU服务器，我的思维从“CPU”转向了“&lt;strong&gt;VRAM（显存）&lt;/strong&gt;”，工具从&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;htop&lt;/code&gt;转向了&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;watch -n 1 nvidia-smi&lt;/code&gt;，心态从“独占”转向了“&lt;strong&gt;合租&lt;/strong&gt;”。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;最后的忠告：&lt;/strong&gt; 这台服务器的功耗是 &lt;strong&gt;4000W&lt;/strong&gt;。它满载时，风扇的声音不像电脑，&lt;strong&gt;像一架即将起飞的波音747&lt;/strong&gt;。千万别想把它放办公桌下面，除非你想体验什么叫“工业噪音疗法”。&lt;/p&gt;

&lt;p&gt;好了，不说了，我的 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Wan2.1-14B&lt;/code&gt; 部署成功了，我要去生成视频了！&lt;/p&gt;
</description>
        <pubDate>Fri, 01 Aug 2025 00:00:00 +0000</pubDate>
        <link>https://guanlili.github.io/2025/08/01/%E6%88%91%E5%88%9A%E6%8B%BF%E5%88%B0%E4%BA%868%E5%8D%A1GPU%E6%9C%8D%E5%8A%A1%E5%99%A8%E7%9A%84%E9%92%A5%E5%8C%99-%E7%8E%B0%E5%9C%A8%E6%88%91%E6%85%8C%E5%BE%97%E4%B8%80%E6%89%B9/</link>
        <guid isPermaLink="true">https://guanlili.github.io/2025/08/01/%E6%88%91%E5%88%9A%E6%8B%BF%E5%88%B0%E4%BA%868%E5%8D%A1GPU%E6%9C%8D%E5%8A%A1%E5%99%A8%E7%9A%84%E9%92%A5%E5%8C%99-%E7%8E%B0%E5%9C%A8%E6%88%91%E6%85%8C%E5%BE%97%E4%B8%80%E6%89%B9/</guid>
        
        <category>AI</category>
        
        <category>运维</category>
        
        
      </item>
    
      <item>
        <title>玩转Dify：三步设置，让你的AI从“智障”变“专家”</title>
        <description>&lt;h3 id=&quot;玩转dify三步设置让你的ai从智障变专家&quot;&gt;&lt;strong&gt;玩转Dify：三步设置，让你的AI从“智障”变“专家”&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;你是否遇到过这样的情况：明明把文件喂给了 AI，但它的回答总是不尽人意，要么答非所问，要么信息不全？别急，问题通常不出在模型本身，而在于我们“喂”给它知识的方式。&lt;/p&gt;

&lt;p&gt;今天，我们就用大白话聊聊 Dify 知识库背后最重要的技术——&lt;strong&gt;文本分段（Chunking）&lt;/strong&gt;。我们将从基础的“通用模式”讲起，再深入到效果拔群的“父子模式”，让你彻底掌握如何配置，将你的 AI 从“人工智障”调教成“行业专家”。&lt;/p&gt;

&lt;h4 id=&quot;核心概念ai-是如何阅读你的文档的&quot;&gt;&lt;strong&gt;核心概念：AI 是如何“阅读”你的文档的？&lt;/strong&gt;&lt;/h4&gt;

&lt;p&gt;想象一下，你扔给 AI 一本厚厚的书。AI 不会真的从头到尾“阅读”一遍。相反，系统会先把这本书拆成一张张的“知识卡片”，这个过程就是&lt;strong&gt;分段&lt;/strong&gt;。当你提问时，系统会先找出与问题最相关的几张卡片，然后交给 AI 根据卡片内容来组织答案。&lt;/p&gt;

&lt;p&gt;所以，卡片拆分得好不好，直接决定了最终回答的质量。Dify 提供了两种制作“知识卡片”的模式：“通用分段”和“父子分段”。&lt;/p&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;第一部分基础篇--通用分段模式&quot;&gt;&lt;strong&gt;第一部分：基础篇 —— 通用分段模式&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;“通用模式”是最基础、最直接的分段方式，它有三个核心配置项，我们称之为“分段三剑客”。&lt;/p&gt;

&lt;h4 id=&quot;1-分段标识符--定义怎么切&quot;&gt;&lt;strong&gt;1. 分段标识符 —— 定义“怎么切”&lt;/strong&gt;&lt;/h4&gt;

&lt;p&gt;“分段标识符”就像一把尺子，它告诉系统应该&lt;strong&gt;沿着什么规则&lt;/strong&gt;来切割你的文档。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;实战案例：一份《1990年鉴》的启示&lt;/p&gt;

    &lt;p&gt;我们来看一个真实的用户测试案例。用户上传了一份结构清晰的《1990年鉴》Markdown 文档，并尝试了两种不同的分段标识符：&lt;/p&gt;

    &lt;ol&gt;
      &lt;li&gt;&lt;strong&gt;按段落切分 (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;\n\n&lt;/code&gt;)&lt;/strong&gt;：系统预估会生成 &lt;strong&gt;8310&lt;/strong&gt; 个知识块。&lt;/li&gt;
      &lt;li&gt;&lt;strong&gt;按标题切分 (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;\n#&lt;/code&gt;)&lt;/strong&gt;：系统预估只生成 &lt;strong&gt;2075&lt;/strong&gt; 个知识块。&lt;/li&gt;
    &lt;/ol&gt;

    &lt;p&gt;这个数量差异的背后，是质量上的巨大鸿沟。8310 个块意味着年鉴被拆成了非常零碎的段落。而 2075 个块则意味着每个知识块都是一个语义完整的章节（例如“年度经济概述”）。当提问时，AI 得到的是一个完整的章节而不是一个孤立的段落，答案的质量自然会高得多。&lt;/p&gt;

    &lt;p&gt;结论：对于有标题的文档，按标题分段（如 \n#）是无可争议的最佳选择。&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;2-分段最大长度--设置安全网&quot;&gt;&lt;strong&gt;2. 分段最大长度 —— 设置“安全网”&lt;/strong&gt;&lt;/h4&gt;

&lt;p&gt;这规定了每张“知识卡片”的最大尺寸，是一个&lt;strong&gt;防止单个知识块过大的“保险丝”&lt;/strong&gt;，而不是一个目标尺寸。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;推荐值&lt;/strong&gt;：&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1024&lt;/code&gt; characters。&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;工作原理&lt;/strong&gt;：系统会先按你的“分段标识符”（比如 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;\n#&lt;/code&gt;）切分。只有当某个切出来的块&lt;strong&gt;超过了 1024 个字符&lt;/strong&gt;，系统才会把它再切得小一点。&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;3-分段重叠长度--建立上下文的桥梁&quot;&gt;&lt;strong&gt;3. 分段重叠长度 —— 建立“上下文的桥梁”&lt;/strong&gt;&lt;/h4&gt;

&lt;p&gt;它让相邻的两个“知识卡片”之间共享一小部分内容，像一座桥梁，&lt;strong&gt;确保了信息的连续性&lt;/strong&gt;。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;推荐值&lt;/strong&gt;：设置为“最大长度”的 &lt;strong&gt;10% 到 15%&lt;/strong&gt;，例如 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;150&lt;/code&gt; characters。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;通用模式的局限&lt;/strong&gt;：这种模式存在一个“上下文两难”问题。为了检索精准，知识块不能太大；但块太小，又会导致 AI 回答时上下文信息不足。如何两全其美？这就引出了我们的进阶方案。&lt;/p&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;第二部分进阶篇--父子分段模式&quot;&gt;&lt;strong&gt;第二部分：进阶篇 —— 父子分段模式&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;“父子模式”是一种更高级的策略，它巧妙地解决了“通用模式”的痛点。&lt;/p&gt;

&lt;h4 id=&quot;核心思想用索引卡查原文页&quot;&gt;&lt;strong&gt;核心思想：用“索引卡”查“原文页”&lt;/strong&gt;&lt;/h4&gt;

&lt;p&gt;想象一下，我们为一本书制作了两种东西：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;子块 (Child Chunks)&lt;/strong&gt;：一套非常精炼的&lt;strong&gt;“索引卡”&lt;/strong&gt;，每张卡片只有一小段文字，信息密度极高。&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;父块 (Parent Chunks)&lt;/strong&gt;：完整的&lt;strong&gt;“原文页”&lt;/strong&gt;，包含丰富的上下文。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;它的工作流程是：&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;检索时&lt;/strong&gt;：系统在海量的“索引卡”（子块）里快速、精准地找到匹配项。&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;回答时&lt;/strong&gt;：系统不会把这张小小的索引卡直接给 AI，而是找到它指向的那一整页“原文页”（父块），把这页内容交给 AI 去生成答案。&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;这样就实现了&lt;strong&gt;精准检索&lt;/strong&gt;和&lt;strong&gt;丰富上下文&lt;/strong&gt;的完美结合！&lt;/p&gt;

&lt;h4 id=&quot;如何配置父子模式&quot;&gt;&lt;strong&gt;如何配置父子模式？&lt;/strong&gt;&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;父块配置 (用于提供上下文)&lt;/strong&gt;
    &lt;ul&gt;
      &lt;li&gt;&lt;strong&gt;分段标识符&lt;/strong&gt;：设置为 &lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;\n#&lt;/code&gt;&lt;/strong&gt;。这确保了每个“父块”都是一个完整的章节，上下文最丰富。&lt;/li&gt;
      &lt;li&gt;&lt;strong&gt;分段最大长度&lt;/strong&gt;：设置为 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1024&lt;/code&gt;。作为过长章节的安全网。&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;子块配置 (用于精准检索)&lt;/strong&gt;
    &lt;ul&gt;
      &lt;li&gt;&lt;strong&gt;分段标识符&lt;/strong&gt;：设置为 &lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;\n\n&lt;/code&gt;&lt;/strong&gt;。这将父块（章节）进一步拆分为段落，形成小而精的“子块”。&lt;/li&gt;
      &lt;li&gt;&lt;strong&gt;分段最大长度&lt;/strong&gt;：设置为 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;512&lt;/code&gt;。这个尺寸非常适合向量检索。&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;最终对决我该如何选择&quot;&gt;&lt;strong&gt;最终对决：我该如何选择？&lt;/strong&gt;&lt;/h3&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;&lt;strong&gt;选择“通用模式”，如果你…&lt;/strong&gt;&lt;/th&gt;
      &lt;th&gt;&lt;strong&gt;选择“父子模式”，如果你…&lt;/strong&gt;&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;刚刚开始使用，想用最简单的方式配置。&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;追求最高的问答质量&lt;/strong&gt;，愿意进行更精细的配置。&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;你的知识库文档内容比较简单、直接（例如 FAQ 列表）。&lt;/td&gt;
      &lt;td&gt;你的文档&lt;strong&gt;复杂、密集且长&lt;/strong&gt;（例如技术手册、法律文件、&lt;strong&gt;我们案例中的年鉴&lt;/strong&gt;）。&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;“通用模式”的测试结果已经让你满意。&lt;/td&gt;
      &lt;td&gt;发现“通用模式”生成的答案&lt;strong&gt;经常缺少上下文，显得很零碎或片面&lt;/strong&gt;。&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;&lt;strong&gt;最终建议&lt;/strong&gt;：对于结构化的复杂文档，&lt;strong&gt;“父子模式”是能将知识库效果最大化的专业选择&lt;/strong&gt;。&lt;/p&gt;

&lt;p&gt;最后，无论选择哪种模式，请一定记得使用 Dify 提供的“&lt;strong&gt;预览块&lt;/strong&gt;”功能！它能让你直观地看到文档被切分成的样子，是验证配置效果的终极武器。&lt;/p&gt;
</description>
        <pubDate>Thu, 10 Apr 2025 00:00:00 +0000</pubDate>
        <link>https://guanlili.github.io/2025/04/10/%E7%8E%A9%E8%BD%ACDify-%E4%B8%89%E6%AD%A5%E8%AE%BE%E7%BD%AE-%E8%AE%A9%E4%BD%A0%E7%9A%84AI%E4%BB%8E-%E6%99%BA%E9%9A%9C-%E5%8F%98-%E4%B8%93%E5%AE%B6/</link>
        <guid isPermaLink="true">https://guanlili.github.io/2025/04/10/%E7%8E%A9%E8%BD%ACDify-%E4%B8%89%E6%AD%A5%E8%AE%BE%E7%BD%AE-%E8%AE%A9%E4%BD%A0%E7%9A%84AI%E4%BB%8E-%E6%99%BA%E9%9A%9C-%E5%8F%98-%E4%B8%93%E5%AE%B6/</guid>
        
        <category>AI</category>
        
        
      </item>
    
      <item>
        <title>如何度量代码生成大模型的准确性？</title>
        <description>&lt;h1 id=&quot;如何度量代码生成大模型的准确性&quot;&gt;如何度量代码生成大模型的准确性？&lt;/h1&gt;

&lt;h2 id=&quot;项目背景&quot;&gt;项目背景&lt;/h2&gt;

&lt;p&gt;在公司内网部署StarCoder-1B大模型已经半月有余了，在考虑继续优化升级StarCoder-7B模型的同时，一个重要的问题出现了。&lt;/p&gt;

&lt;p&gt;在实际生产开发中，我们应该如何评估代码生成大模型的准确性？是从10亿到70亿参数越多就越好吗？还是看论文测试说哪个模型好就一定更好？&lt;/p&gt;

&lt;p&gt;用数据说话！&lt;/p&gt;

&lt;h2 id=&quot;评估指标&quot;&gt;评估指标&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;插件的下载数量—-普及度
    &lt;ul&gt;
      &lt;li&gt;由于我把插件放在飞书文档，因此无法统计下载安装的数量（失策了..）&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;代码的生成质量—-满意度
    &lt;ul&gt;
      &lt;li&gt;通过tabby产生的日志可以分析。&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;日志分析&quot;&gt;日志分析&lt;/h2&gt;

&lt;p&gt;tabby服务端会每天产生日志如：2024-03-07.json&lt;/p&gt;

&lt;p&gt;日志的内容：&lt;/p&gt;

&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;ts&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1709541131885&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;event&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;completion&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;completion_id&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;cmpl-dea2b314-0518-414e-ace7-f74c3494ba20&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;language&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;java&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;prompt&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;*******&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;segments&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;prefix&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;*****&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;suffix&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;*****&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;choices&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:[{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;index&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;text&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;*********&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}]}}}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;ts&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1709541132062&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;event&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;view&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;completion_id&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;cmpl-dea2b314-0518-414e-ace7-f74c3494ba20&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;choice_index&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;view_id&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;view-dea2b314-0518-414e-ace7-f74c3494ba20-at-1709541131909&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}}}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;ts&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1709541132768&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;event&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;select&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;completion_id&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;cmpl-dea2b314-0518-414e-ace7-f74c3494ba20&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;choice_index&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;view_id&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;view-dea2b314-0518-414e-ace7-f74c3494ba20-at-1709541131909&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;elapsed&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;704&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}}}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;ts&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1709541133661&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;event&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;view&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;completion_id&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;cmpl-dea2b314-0518-414e-ace7-f74c3494ba20&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;choice_index&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;view_id&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;view-dea2b314-0518-414e-ace7-f74c3494ba20-at-1709541133514&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}}}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;ts&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1709541134151&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;event&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;select&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;completion_id&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;cmpl-dea2b314-0518-414e-ace7-f74c3494ba20&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;choice_index&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;view_id&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;view-dea2b314-0518-414e-ace7-f74c3494ba20-at-1709541133514&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;elapsed&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;489&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}}}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;ts&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1709541134902&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;event&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;view&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;completion_id&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;cmpl-dea2b314-0518-414e-ace7-f74c3494ba20&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;choice_index&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;view_id&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;view-dea2b314-0518-414e-ace7-f74c3494ba20-at-1709541134755&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}}}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;ts&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1709541135314&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;event&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;select&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;completion_id&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;cmpl-dea2b314-0518-414e-ace7-f74c3494ba20&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;choice_index&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;view_id&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;view-dea2b314-0518-414e-ace7-f74c3494ba20-at-1709541134755&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;elapsed&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;412&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}}}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;

&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;通过分析日志的结构可以看出，日志一共分为4类&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;completion：完成&lt;/li&gt;
  &lt;li&gt;view：展示&lt;/li&gt;
  &lt;li&gt;select ：选择&lt;/li&gt;
  &lt;li&gt;dismiss：放弃&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;数据分析&quot;&gt;数据分析&lt;/h2&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;日期&lt;/th&gt;
      &lt;th&gt;completion&lt;/th&gt;
      &lt;th&gt;view&lt;/th&gt;
      &lt;th&gt;dismiss&lt;/th&gt;
      &lt;th&gt;select&lt;/th&gt;
      &lt;th&gt;代码采纳率&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;2024-03-07&lt;/td&gt;
      &lt;td&gt;2451&lt;/td&gt;
      &lt;td&gt;2059&lt;/td&gt;
      &lt;td&gt;1873&lt;/td&gt;
      &lt;td&gt;183&lt;/td&gt;
      &lt;td&gt;8.89%&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;2024-03-08&lt;/td&gt;
      &lt;td&gt;1276&lt;/td&gt;
      &lt;td&gt;933&lt;/td&gt;
      &lt;td&gt;859&lt;/td&gt;
      &lt;td&gt;73&lt;/td&gt;
      &lt;td&gt;7.82%&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;2024-03-11&lt;/td&gt;
      &lt;td&gt;2137&lt;/td&gt;
      &lt;td&gt;1581&lt;/td&gt;
      &lt;td&gt;1504&lt;/td&gt;
      &lt;td&gt;77&lt;/td&gt;
      &lt;td&gt;4.87%&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;2024-03-12&lt;/td&gt;
      &lt;td&gt;1642&lt;/td&gt;
      &lt;td&gt;1527&lt;/td&gt;
      &lt;td&gt;1407&lt;/td&gt;
      &lt;td&gt;116&lt;/td&gt;
      &lt;td&gt;7.60%&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;2024-03-13&lt;/td&gt;
      &lt;td&gt;1483&lt;/td&gt;
      &lt;td&gt;1146&lt;/td&gt;
      &lt;td&gt;1068&lt;/td&gt;
      &lt;td&gt;78&lt;/td&gt;
      &lt;td&gt;6.81%&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;2024-03-14&lt;/td&gt;
      &lt;td&gt;1649&lt;/td&gt;
      &lt;td&gt;1132&lt;/td&gt;
      &lt;td&gt;1080&lt;/td&gt;
      &lt;td&gt;52&lt;/td&gt;
      &lt;td&gt;4.59%&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;2024-03-15&lt;/td&gt;
      &lt;td&gt;1495&lt;/td&gt;
      &lt;td&gt;1159&lt;/td&gt;
      &lt;td&gt;1096&lt;/td&gt;
      &lt;td&gt;62&lt;/td&gt;
      &lt;td&gt;5.35%&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;2024-03-18&lt;/td&gt;
      &lt;td&gt;834&lt;/td&gt;
      &lt;td&gt;645&lt;/td&gt;
      &lt;td&gt;625&lt;/td&gt;
      &lt;td&gt;16&lt;/td&gt;
      &lt;td&gt;2.48%&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;2024-03-19&lt;/td&gt;
      &lt;td&gt;931&lt;/td&gt;
      &lt;td&gt;690&lt;/td&gt;
      &lt;td&gt;659&lt;/td&gt;
      &lt;td&gt;30&lt;/td&gt;
      &lt;td&gt;4.35%&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;2024-03-20&lt;/td&gt;
      &lt;td&gt;1395&lt;/td&gt;
      &lt;td&gt;1017&lt;/td&gt;
      &lt;td&gt;961&lt;/td&gt;
      &lt;td&gt;54&lt;/td&gt;
      &lt;td&gt;5.31%&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;2024-03-21&lt;/td&gt;
      &lt;td&gt;1391&lt;/td&gt;
      &lt;td&gt;1007&lt;/td&gt;
      &lt;td&gt;937&lt;/td&gt;
      &lt;td&gt;71&lt;/td&gt;
      &lt;td&gt;7.05%&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;2024-03-22&lt;/td&gt;
      &lt;td&gt;1352&lt;/td&gt;
      &lt;td&gt;1041&lt;/td&gt;
      &lt;td&gt;974&lt;/td&gt;
      &lt;td&gt;66&lt;/td&gt;
      &lt;td&gt;6.34%&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h2 id=&quot;分析结论&quot;&gt;分析结论&lt;/h2&gt;

&lt;p&gt;通过数据可以得到代码的采纳率大概在5%左右，考虑到很多用户都是设置的自动模式，因此必定会有非常多的无效提示。实际有效的采纳估计会超过15%&lt;/p&gt;

&lt;p&gt;数据也算是差强人意，但还有很大的提升空间。&lt;/p&gt;

&lt;h2 id=&quot;后续规划&quot;&gt;后续规划&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;升级7B模型，通过测试用例和「代码采纳率」来评估新模型的效果。&lt;/li&gt;
  &lt;li&gt;优化idea和vscode插件的功能，增加埋点，更精准的统计用户数据，使分析结果更科学。&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Wed, 10 Apr 2024 00:00:00 +0000</pubDate>
        <link>https://guanlili.github.io/2024/04/10/%E5%A6%82%E4%BD%95%E5%BA%A6%E9%87%8F%E4%BB%A3%E7%A0%81%E7%94%9F%E6%88%90%E5%A4%A7%E6%A8%A1%E5%9E%8B%E7%9A%84%E5%87%86%E7%A1%AE%E6%80%A7/</link>
        <guid isPermaLink="true">https://guanlili.github.io/2024/04/10/%E5%A6%82%E4%BD%95%E5%BA%A6%E9%87%8F%E4%BB%A3%E7%A0%81%E7%94%9F%E6%88%90%E5%A4%A7%E6%A8%A1%E5%9E%8B%E7%9A%84%E5%87%86%E7%A1%AE%E6%80%A7/</guid>
        
        <category>AI</category>
        
        <category>代码生成</category>
        
        
      </item>
    
      <item>
        <title>二次开发tabby插件</title>
        <description>&lt;h1 id=&quot;二次开发tabby插件&quot;&gt;二次开发tabby插件&lt;/h1&gt;

&lt;p&gt;以下同时包含idea和vscode教程。&lt;/p&gt;

&lt;h2 id=&quot;1tabby架构&quot;&gt;1、tabby架构&lt;/h2&gt;

&lt;p&gt;Tabby的架构由多个&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;crate&lt;/code&gt;（模块）组成，主要包括：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;crates/tabby&lt;/code&gt;&lt;/strong&gt;：处理核心功能和HTTP API。&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;crates/tabby-download&lt;/code&gt;&lt;/strong&gt;：从互联网获取模型。&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;crates/tabby-inference&lt;/code&gt;&lt;/strong&gt;：用于LLM推理的功能和工具。&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;crates/tabby-scheduler&lt;/code&gt;&lt;/strong&gt;：执行异步任务。&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ee/tabby-ui&lt;/code&gt;&lt;/strong&gt;：提供Web UI。&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ee/tabby-webserver&lt;/code&gt;&lt;/strong&gt;：集成UI并提供团队管理和身份验证。&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;2了解下intellij插件结构&quot;&gt;2、了解下intellij插件结构&lt;/h2&gt;

&lt;p&gt;开发IntelliJ插件时，插件的基本项目结构如下：&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;├── build.gradle.kts # 构建脚本文件
├── gradle # Gradle包装器
│   └── wrapper
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties # 包装器配置文件
├── gradlew # shell脚本
├── gradlew.bat # 批处理脚本
├── settings.gradle.kts # 对于单个项目，设置文件是可选的
└── src
    └── main
        ├── java
        │   └── io
        │       └── org
        │           └── example
        │               └── plugin
        │                   ├── MyToolWindow.form
        │                   ├── MyToolWindow.java
        │                   └── MyToolWindowFactory.java
        └── resources 
	    ├── images
	    │		├── a.svg
	    │           └── b.svg
	    ├── messages
	    │		├── TBundle.properties #Bundle
		        └── TBundle_zh_CN.properties #国际化Bundle
            ├── META-INF
            │   ├── plugin.xml # 插件配置文件
            └── └── pluginIcon.svg #Plugin Logo ，插件在IDEA/Plugins中的展示图标
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;如何打包&quot;&gt;如何打包？&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;IntelliJ中&lt;/strong&gt;：&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;gradle tasks
gradle intellij.buildplugin
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;VS Code中&lt;/strong&gt;：&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;进入&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;./clients/vscode&lt;/code&gt;目录。&lt;/li&gt;
  &lt;li&gt;安装依赖项：&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;yarn&lt;/code&gt;。&lt;/li&gt;
  &lt;li&gt;开发模式下运行：&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;yarn run dev&lt;/code&gt;。&lt;/li&gt;
  &lt;li&gt;修改代码后，打包插件：&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vsce package --no-dependencies&lt;/code&gt;。&lt;/li&gt;
  &lt;li&gt;安装生成的&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.vsix&lt;/code&gt;文件到VS Code中。&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;如果遇到问题，确保VS Code版本与&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;package.json&lt;/code&gt;中的&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;engines&lt;/code&gt;字段兼容，并查看开发者工具控制台日志。&lt;/p&gt;

&lt;h2 id=&quot;修改插件配置&quot;&gt;修改插件配置&lt;/h2&gt;

&lt;p&gt;plugin.xml&lt;/p&gt;

&lt;p&gt;1.4.0-dev&lt;/p&gt;

&lt;p&gt;修改&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&amp;lt;name&amp;gt;Tabby&amp;lt;/name&amp;gt;
&amp;lt;vendor url=&quot;https://tabbyml.com&quot;&amp;gt;TabbyML&amp;lt;/vendor&amp;gt;

&amp;lt;description&amp;gt;&amp;lt;![CDATA[
    &amp;lt;h1 id=&quot;UmeAiCoder-plugin-for-intellij-platform&quot;&amp;gt;umeAiCoder Plugin for IntelliJ Platform&amp;lt;/h1&amp;gt;
    &amp;lt;p&amp;gt;umeAiCoder is an AI coding assistant that can suggest multi-line code or full functions in real-time.&amp;lt;/p&amp;gt;
    &amp;lt;br/&amp;gt;
    &amp;lt;h2 id=&quot;demo&quot;&amp;gt;Demo&amp;lt;/h2&amp;gt;
    &amp;lt;p&amp;gt;Try our online demo &amp;lt;a href=&quot;https://tabby.tabbyml.com/playground/&quot;&amp;gt;here&amp;lt;/a&amp;gt;.&amp;lt;/p&amp;gt;
    &amp;lt;h2 id=&quot;requirements&quot;&amp;gt;Requirements&amp;lt;/h2&amp;gt;
    Tabby plugin requires &amp;lt;a href=&quot;https://nodejs.org/&quot;&amp;gt;Node.js&amp;lt;/a&amp;gt; v18+ installed. &amp;lt;/p&amp;gt;
]]&amp;gt;&amp;lt;/description&amp;gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;设置默认ip端口（不好使）&lt;/p&gt;

&lt;p&gt;/Users/guanhongli/Downloads/tabby-main/clients/intellij/src/main/kotlin/com/tabbyml/intellijtabby/settings/ApplicationSettingsPanel.kt&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;  var serverEndpoint: String
    get() = serverEndpointTextField.text
    set(value) {
      serverEndpointTextField.text = value
    }
#增加默认配置
  init {
    // Set a default value for serverEndpoint
    serverEndpoint = &quot;http://172.24.82.15:8186&quot;
  }
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;package.json&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;{
  &quot;name&quot;: &quot;intellij-umeAiCoder&quot;,
  &quot;version&quot;: &quot;1.0.0-dev&quot;,
  &quot;description&quot;: &quot;IntelliJ plugin for umeAiCoder AI coding assistant.&quot;,
  &quot;repository&quot;: &quot;https://i2wp4yetps.feishu.cn/wiki/XORAwmB53iORXHk7YSGcRFrWnhh&quot;,
  &quot;scripts&quot;: {
    &quot;preupgrade-agent&quot;: &quot;cd ../tabby-agent &amp;amp;&amp;amp; yarn build&quot;,
    &quot;upgrade-agent&quot;: &quot;rimraf ./node_scripts  &amp;amp;&amp;amp;  cpy ../tabby-agent/dist/cli.js ./node_scripts/ --flat --rename=tabby-agent.js &amp;amp;&amp;amp; cpy ../tabby-agent/dist/wasm/* ./node_scripts/wasm/ --flat &amp;amp;&amp;amp; cpy ../tabby-agent/dist/win-ca/* ./node_scripts/win-ca/ --flat&quot;
  },
  &quot;devDependencies&quot;: {
    &quot;cpy-cli&quot;: &quot;^4.2.0&quot;,
    &quot;rimraf&quot;: &quot;^5.0.1&quot;,
    &quot;tabby-agent&quot;: &quot;1.0.0-dev&quot;
  }
}
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;状态栏&quot;&gt;状态栏&lt;/h3&gt;

&lt;h5 id=&quot;idea&quot;&gt;idea&lt;/h5&gt;

&lt;p&gt;StatusBarWidgetFactory.kt //状态栏小部件&lt;/p&gt;

&lt;p&gt;TabbyStatusBarItem.ts&lt;/p&gt;

&lt;h2 id=&quot;修改配置&quot;&gt;修改配置&lt;/h2&gt;

&lt;p&gt;settings&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;ApplicationConfigurable.kt ：实现了 Configurable 接口，为插件提供了一个可配置的设置 UI。这是用户与插件设置交互的界面。&lt;/li&gt;
  &lt;li&gt;ApplicationSettingsPanel.kt ：定义了插件设置界面的布局和逻辑。这个文件负责创建和管理插件配置界面的所有组件（如输入框、复选框等）。&lt;/li&gt;
  &lt;li&gt;ApplicationSettingsState.kt ：管理和存储插件的设置状态。这个文件定义了一个或多个用于持久化插件配置的数据类。&lt;/li&gt;
  &lt;li&gt;KeymapSettings.kt ：特别管理键盘映射（快捷键）设置。这可能包括自定义键盘快捷键配置，以及与插件功能交互的快捷方式。&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;默认ip端口&quot;&gt;默认ip端口&lt;/h2&gt;

&lt;h5 id=&quot;idea-1&quot;&gt;idea&lt;/h5&gt;

&lt;p&gt;umeAiCoder/tabby-main/clients/intellij/node_scripts/tabby-agent.js&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;修改默认endpoint:”https://umeaicoder.local.umetrip.com.cn”&lt;/li&gt;
  &lt;li&gt;修改默认token:”auth_325ecaec60b84a46b8fc1320a1bfe10c”&lt;/li&gt;
  &lt;li&gt;修改[server] （感觉不改也行，有空试试）&lt;/li&gt;
&lt;/ul&gt;

&lt;h5 id=&quot;vscode&quot;&gt;vscode&lt;/h5&gt;

&lt;p&gt;/Users/guanhongli/Documents/umeAiCoder/tabby-main/clients/tabby-agent/src/AgentConfig.ts&lt;/p&gt;

&lt;p&gt;需要修改的文件&lt;/p&gt;

&lt;p&gt;配置设置导航&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;@ext:TabbyML.vscode-tabby
修改为
@ext:UmeTabby.vscode-ume-ai-coder
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;package.json文件&lt;/p&gt;

&lt;p&gt;修改打包文件：&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;  &quot;name&quot;: &quot;vscode-ume-ai-coder&quot;,
  &quot;publisher&quot;: &quot;umeAiCoder&quot;,
  &quot;displayName&quot;: &quot;umeAiCoder&quot;,
  &quot;description&quot;: &quot;你的代码，何必要自己写...&quot;,
  &quot;homepage&quot;: &quot;https://umedevops.local.umetrip.com.cn&quot;,
  &quot;repository&quot;: &quot;https://umedevops.local.umetrip.com.cn/&quot;,
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;启动命令&quot;&gt;启动命令&lt;/h2&gt;

&lt;p&gt;cpu&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;docker run &lt;span class=&quot;nt&quot;&gt;-it&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--gpus&lt;/span&gt; all &lt;span class=&quot;nt&quot;&gt;-p&lt;/span&gt; 8080:8080 &lt;span class=&quot;nt&quot;&gt;-v&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$HOME&lt;/span&gt;/.tabby:/data tabbyml/tabby serve &lt;span class=&quot;nt&quot;&gt;--model&lt;/span&gt; TabbyML/StarCoder-1B &lt;span class=&quot;nt&quot;&gt;--device&lt;/span&gt; cuda
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;常见问题解答&quot;&gt;常见问题解答&lt;/h3&gt;

&lt;h4 id=&quot;1-团队自己的代码来训练模型&quot;&gt;1. &lt;strong&gt;团队自己的代码来训练模型？&lt;/strong&gt;&lt;/h4&gt;

&lt;p&gt;是的，您可以使用团队自己的代码来训练模型。具体步骤如下：&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;检查您使用的工具或平台是否支持自定义代码训练。&lt;/li&gt;
  &lt;li&gt;确保代码结构化并与工具要求兼容。&lt;/li&gt;
  &lt;li&gt;上传代码到平台或工具。&lt;/li&gt;
  &lt;li&gt;配置训练过程，使用自定义代码进行训练。&lt;/li&gt;
  &lt;li&gt;启动训练并监控进度。&lt;/li&gt;
  &lt;li&gt;分析结果，调整代码以优化性能。&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;更多讨论可以访问Tabby社区：&lt;a href=&quot;https://slack.tabbyml.com/&quot;&gt;Tabby Slack&lt;/a&gt;&lt;/p&gt;

&lt;h4 id=&quot;2-始终无法获取模型tabbymlsantacoder-1b&quot;&gt;2. &lt;strong&gt;始终无法获取模型：&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TabbyML/SantaCoder-1B&lt;/code&gt;&lt;/strong&gt;&lt;/h4&gt;

&lt;p&gt;有时您可能会遇到无法获取模型的情况。可以尝试摆脱对注册表&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;models.json&lt;/code&gt;的依赖，或检查是否能够直接加载自定义模型。&lt;/p&gt;

&lt;p&gt;相关链接：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://tabby.tabbyml.com/docs/faq/&quot;&gt;Tabby: 自定义模型加载&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/TabbyML/tabby/blob/main/MODEL_SPEC.md&quot;&gt;如何向Tabby指示自定义模型&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;3-如何指定下载镜像&quot;&gt;3. &lt;strong&gt;如何指定下载镜像？&lt;/strong&gt;&lt;/h4&gt;

&lt;p&gt;如果需要使用特定的镜像下载模型，您可以参考&lt;a href=&quot;https://github.com/TabbyML/tabby/issues/710&quot;&gt;Tabby模型下载镜像设置&lt;/a&gt;。&lt;/p&gt;

&lt;h4 id=&quot;4-tabby支持哪些隐私和安全问题&quot;&gt;4. &lt;strong&gt;Tabby支持哪些隐私和安全问题？&lt;/strong&gt;&lt;/h4&gt;

&lt;p&gt;Tabby在数据收集和隐私方面有一些问题和解决措施。详细内容请查看：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://slack.tabbyml.com/PR5d7LvOdJ3/what-are-the-privacy-and-security-concerns-with-tabbyml&quot;&gt;Tabby隐私与安全问题&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://tabby.tabbyml.com/docs/configuration/#usage-collection&quot;&gt;Tabby文档：配置和使用收集&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;5-tabby支持离线模式运行吗&quot;&gt;5. &lt;strong&gt;Tabby支持离线模式运行吗？&lt;/strong&gt;&lt;/h4&gt;

&lt;p&gt;是的，Tabby支持离线模式运行，您可以设置并在没有互联网连接的情况下使用Tabby。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://slack.tabbyml.com/bl5OPj307QN/does-tabby-supports-runs-in-offline-mode&quot;&gt;Tabby离线模式支持&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;6-如何在m1-mac上构建自托管服务器&quot;&gt;6. &lt;strong&gt;如何在M1 Mac上构建自托管服务器？&lt;/strong&gt;&lt;/h4&gt;

&lt;p&gt;可以参考Tabby的文档来在M1 Mac上进行构建：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/TabbyML/tabby/issues/340&quot;&gt;在M1 Mac上构建Tabby自托管服务器&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;7-如何构建和运行具有cuda支持的tabby&quot;&gt;7. &lt;strong&gt;如何构建和运行具有CUDA支持的Tabby？&lt;/strong&gt;&lt;/h4&gt;

&lt;p&gt;如果您想构建并运行支持CUDA的Tabby，可以参考以下资源：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://slack.tabbyml.com/Oq57bPkvX7B/how-can-i-build-and-run-tabby-with-cuda-support&quot;&gt;构建Tabby并启用CUDA支持&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;8-如何创建交互式聊天窗口&quot;&gt;8. &lt;strong&gt;如何创建交互式聊天窗口？&lt;/strong&gt;&lt;/h4&gt;

&lt;p&gt;Tabby支持创建交互式聊天窗口，您可以参考相关文档和讨论：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/TabbyML/tabby/issues/1025&quot;&gt;Tabby创建交互式聊天窗口&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;9-如何从头开始构建并安装vs-code扩展&quot;&gt;9. &lt;strong&gt;如何从头开始构建并安装VS Code扩展？&lt;/strong&gt;&lt;/h4&gt;

&lt;p&gt;如果您需要从头开始构建并安装VS Code扩展，按以下步骤操作：&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;导航到&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;./clients/vscode&lt;/code&gt;目录。&lt;/li&gt;
  &lt;li&gt;使用&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;yarn&lt;/code&gt;安装依赖项。&lt;/li&gt;
  &lt;li&gt;使用&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;yarn run dev&lt;/code&gt;启动开发模式。&lt;/li&gt;
  &lt;li&gt;对代码进行修改后，使用&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vsce package --no-dependencies&lt;/code&gt;命令打包扩展。&lt;/li&gt;
  &lt;li&gt;安装生成的&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.vsix&lt;/code&gt;文件。&lt;/li&gt;
&lt;/ol&gt;

&lt;h4 id=&quot;10-如何在本地工作区使用tabby-vscode扩展&quot;&gt;10. &lt;strong&gt;如何在本地工作区使用Tabby VSCode扩展？&lt;/strong&gt;&lt;/h4&gt;

&lt;p&gt;如果您希望在本地工作区而不是开发容器中使用Tabby VSCode扩展，请参考以下链接：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://slack.tabbyml.com/260Y3Z2LlZk/how-to-use-tabby-vscode-extension-in-a-local-workspace&quot;&gt;使用Tabby VSCode扩展在本地工作区&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;11-是否可以在不触发模型下载的情况下启动tabby容器&quot;&gt;11. &lt;strong&gt;是否可以在不触发模型下载的情况下启动Tabby容器？&lt;/strong&gt;&lt;/h4&gt;

&lt;p&gt;可以通过特定的设置启动Tabby容器而不下载模型。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://slack.tabbyml.com/blXnXlOYkJv/is-it-possible-to-start-a-tabby-container-without-triggering&quot;&gt;启动Tabby容器而不触发模型下载&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;12-如何使用python运行tabby服务器或自定义&quot;&gt;12. &lt;strong&gt;如何使用Python运行Tabby服务器或自定义？&lt;/strong&gt;&lt;/h4&gt;

&lt;p&gt;如果您希望使用Python自定义或运行Tabby服务器，请参考相关讨论：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://slack.tabbyml.com/bl5rG9ojrGd/is-there-a-way-to-run-tabby-server-using-python&quot;&gt;如何使用Python运行Tabby服务器&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;13-如何删除tabby模型&quot;&gt;13. &lt;strong&gt;如何删除Tabby模型？&lt;/strong&gt;&lt;/h4&gt;

&lt;p&gt;如果需要删除Tabby模型，可以参考以下讨论：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://slack.tabbyml.com/Gd5DrzkPXZJ/how-to-remove-model-tabby&quot;&gt;如何删除Tabby模型&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;14-为服务命令添加chat-device标志&quot;&gt;14. &lt;strong&gt;为服务命令添加–chat-device标志&lt;/strong&gt;&lt;/h4&gt;

&lt;p&gt;您可以为服务命令添加&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--chat-device&lt;/code&gt;标志，以指定使用的设备类型。更多信息请参考：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/TabbyML/tabby/issues/1659&quot;&gt;如何为服务命令添加–chat-device标志&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;15-如何设置身份验证令牌&quot;&gt;15. &lt;strong&gt;如何设置身份验证令牌？&lt;/strong&gt;&lt;/h4&gt;

&lt;p&gt;要设置身份验证令牌，请参考以下讨论：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/TabbyML/tabby/issues/1159#top&quot;&gt;如何设置身份验证令牌&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;16-编码llm排行榜简介&quot;&gt;16. &lt;strong&gt;编码LLM排行榜简介&lt;/strong&gt;&lt;/h4&gt;

&lt;p&gt;Tabby提供了一个编码LLM排行榜，帮助您了解当前模型的性能和排名：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://tabby.tabbyml.com/blog/2023/11/23/coding-llm-leaderboard/&quot;&gt;编码LLM排行榜&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;17-模型下载地址&quot;&gt;17. &lt;strong&gt;模型下载地址&lt;/strong&gt;&lt;/h4&gt;

&lt;p&gt;以下是一些常见的模型下载链接：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://huggingface.co/&quot;&gt;HuggingFace&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://hf-mirror.com/&quot;&gt;HF Mirror&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://huggingface.co/TabbyML/StarCoder-1B&quot;&gt;StarCoder-1B模型下载&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Wed, 20 Mar 2024 00:00:00 +0000</pubDate>
        <link>https://guanlili.github.io/2024/03/20/%E4%BA%8C%E6%AC%A1%E5%BC%80%E5%8F%91tabby%E6%8F%92%E4%BB%B6/</link>
        <guid isPermaLink="true">https://guanlili.github.io/2024/03/20/%E4%BA%8C%E6%AC%A1%E5%BC%80%E5%8F%91tabby%E6%8F%92%E4%BB%B6/</guid>
        
        <category>AI</category>
        
        <category>代码生成</category>
        
        <category>学习笔记</category>
        
        
      </item>
    
  </channel>
</rss>
