前面几篇,我们已经分析了 Pixelle-Video 的整体定位、目录结构、生成流程,以及快速启动方式。
这一篇继续往下看一个非常关键的模块:配置系统。
为什么配置系统重要?
因为 Pixelle-Video 不是一个只调用单一模型的项目。它要同时接入 LLM、TTS、ComfyUI、RunningHub、本地图像工作流、云端视频模型、API 图像模型、API 视频模型、模板系统、BGM 等多个能力。
如果没有一套清晰的配置系统,代码很快就会变成这样:
LLM 的 API Key 写在一个地方
ComfyUI 的地址写在另一个地方
RunningHub 的 Key 写在页面里
TTS 的默认音色写死在函数里
图像模型配置散落在多个模块
视频模型配置又单独维护
这种写法短期能跑,但后期很难维护。
Pixelle-Video 的配置系统,核心目标就是把这些外部能力统一组织起来,让 WebUI、核心服务、pipeline、TTS、媒体生成模块都能从同一套配置里读取参数。
一、配置文件从哪里开始?
Pixelle-Video 根目录下提供了一个 config.example.yaml,说明用户需要复制成 config.yaml,然后填写自己的配置。这个示例配置文件包含几个主要部分:llm、api_providers、comfyui、template。其中 llm 用于配置 OpenAI SDK 兼容的 LLM 接口,api_providers 用于直连图像/视频模型服务,comfyui 用于配置本地 ComfyUI 和 RunningHub,template 用于指定默认视频模板。
从结构上看,它大致是这样的:
project_name: Pixelle-Video
llm:
api_key: ""
base_url: ""
model: ""
api_providers:
common:
print_model_input: false
local_proxy: ""
openai:
api_key: ""
base_url: ""
use_proxy: false
dashscope:
api_key: ""
base_url: ""
use_proxy: false
ark:
api_key: ""
base_url: ""
use_proxy: false
kling:
base_url: ""
access_key: ""
secret_key: ""
use_proxy: false
comfyui:
comfyui_url: http://127.0.0.1:8188
comfyui_api_key: ""
runninghub_api_key: ""
runninghub_concurrent_limit: 1
tts:
default_workflow: selfhost/tts_edge.json
image:
default_workflow: runninghub/image_flux.json
prompt_prefix: ""
video:
default_workflow: runninghub/video_wan2.1_fusionx.json
prompt_prefix: ""
template:
default_template: "1080x1920/image_default.html"
这个结构很清晰:
llm 管文字生成。
comfyui 管工作流类能力。
api_providers 管直连 API 的媒体模型。
template 管视频默认样式。
也就是说,Pixelle-Video 没有把“模型配置”简单理解成一个 API Key,而是按照能力类型拆成了多个配置块。
二、LLM 配置:所有文案生成的基础
先看 llm 配置。
它只有三个核心字段:
llm:
api_key: ""
base_url: ""
model: ""
这三个字段分别表示:
api_key:模型服务的访问密钥。
base_url:OpenAI SDK 兼容接口地址。
model:具体模型名称。
为什么这里强调 OpenAI SDK 兼容?
因为 Pixelle-Video 的 LLM 服务不是只为 OpenAI 写死的。LLMService 使用 AsyncOpenAI 客户端,并在注释中说明支持 OpenAI SDK 兼容的 provider,包括 OpenAI、通义千问、DeepSeek、Ollama 以及自定义 OpenAI-compatible API。
这意味着,只要某个服务提供类似 OpenAI Chat Completions 的接口,就可以通过改 base_url 和 model 接入。
例如:
llm:
api_key: "你的 key"
base_url: "兼容 OpenAI SDK 的接口地址"
model: "模型名称"
这套设计的好处是:LLM 层只关心统一接口,不关心背后是哪家模型。
在 Pixelle-Video 的生成流程中,LLM 主要负责:
生成短视频解说文案。
生成标题。
根据文案生成画面提示词。
输出结构化分镜内容。
因此,LLM 配置是整个系统最基础的配置。如果 LLM 没配好,后面的图片、视频、TTS、模板合成都没有内容来源。
三、Pydantic Schema:配置不是随便读字典
有些项目读取 YAML 后,直接把配置当普通 dict 使用:
config["llm"]["api_key"]
这种方式简单,但问题是缺少默认值、类型约束和校验逻辑。
Pixelle-Video 在 pixelle_video/config/schema.py 中使用 Pydantic 定义配置结构。源码里有 LLMConfig、APIProvidersConfig、ComfyUIConfig、TTSSubConfig、ImageSubConfig、VideoSubConfig、TemplateConfig、PixelleVideoConfig 等模型,并且在字段上定义了默认值、描述、范围限制。
例如:
LLMConfig
api_key
base_url
model
ComfyUIConfig
comfyui_url
comfyui_api_key
runninghub_api_key
runninghub_concurrent_limit
runninghub_instance_type
tts
image
video
APIProvidersConfig
common
openai
dashscope
deepseek
gemini
ark
kling
这样做有几个好处。
第一,有默认值。
即使 config.yaml 不完整,系统也能用默认配置对象启动。
第二,有类型约束。
比如 RunningHub 并发限制可以限制在合理范围内,避免用户输入乱值。
第三,有结构提示。
读代码的人可以直接通过 schema 看出配置系统支持哪些能力。
第四,有统一校验。
PixelleVideoConfig 中提供了 is_llm_configured() 和 validate_required(),用于判断 LLM 的 api_key、base_url、model 是否填写完整。
所以,配置系统的第一层不是 YAML,而是 schema。
YAML 只是存储格式。
Pydantic schema 才是配置系统的结构定义。
四、loader.py:只负责读写 YAML
接下来看 loader.py。
这个文件很简单,但职责很清楚:只负责从 YAML 文件读取 dict,以及把 dict 保存回 YAML 文件。源码中 load_config_dict() 默认读取 config.yaml,如果文件不存在,就记录 warning 并返回空 dict;save_config_dict() 则把配置写回 YAML 文件。
它不负责判断配置是否合法,也不负责解释 LLM、ComfyUI、RunningHub 的意义。
这种拆分很好。
loader.py
只负责文件读写
schema.py
负责配置结构和默认值
manager.py
负责统一访问、更新、保存、校验
这样以后如果配置文件从 YAML 换成 JSON、数据库、环境变量,理论上只需要调整加载层,不应该影响业务服务。
五、ConfigManager:配置系统的统一入口
真正把配置系统串起来的是 ConfigManager。
manager.py 里使用了单例模式,ConfigManager 初始化时会加载配置文件,然后创建 PixelleVideoConfig 对象。它还提供了 reload()、save()、update()、get_llm_config()、set_llm_config()、get_comfyui_config()、set_comfyui_config()、get_api_providers_config()、set_api_provider_config() 等方法。
可以把它理解成配置系统的“门面”:
WebUI 不直接操作 YAML
业务服务不直接操作 YAML
pipeline 不直接操作 YAML
它们都通过 config_manager 获取配置
项目的 pixelle_video/config/__init__.py 里创建了一个全局单例 config_manager = ConfigManager(),并在注释中给出了典型用法:导入 config_manager、访问 config_manager.config.llm.api_key、调用 config_manager.update()、config_manager.save()、config_manager.validate()。
这种设计的好处是明显的:
第一,配置入口统一。
第二,WebUI 保存配置后,后端服务可以读取同一份配置。
第三,后续支持热更新更方便。
第四,避免各个模块各自解析 YAML。
六、WebUI 配置面板:用户改的是 config_manager
配置系统不是只在后端使用,它也和 WebUI 绑定得很紧。
web/components/settings.py 中的 render_advanced_settings() 会渲染系统配置面板。这个面板包含 LLM 设置、ComfyUI 设置、RunningHub 设置,以及 API 媒体模型配置。代码里会读取 config_manager.get_llm_config()、config_manager.get_comfyui_config()、config_manager.get_api_providers_config() 来填充当前配置,并在用户点击保存按钮时调用 config_manager.set_llm_config()、set_comfyui_config()、set_api_provider_config(),最后调用 config_manager.save() 写入文件。
也就是说,用户在 WebUI 上填的内容,最终不是存在 Streamlit session 里,而是写回配置系统。
这个流程可以画成这样:
用户在 WebUI 填写配置
↓
settings.py 收集输入
↓
config_manager.set_llm_config()
config_manager.set_comfyui_config()
config_manager.set_api_provider_config()
↓
config_manager.save()
↓
写入 config.yaml
这就实现了“页面配置”和“后端配置”的统一。
用户不需要手动编辑 YAML,也可以完成模型配置;开发者想手动改配置,也可以直接改 config.yaml。
七、ComfyUI 配置:本地工作流和云端工作流的共同入口
接下来重点看 comfyui 配置。
config.example.yaml 中的 comfyui 包含:
comfyui:
comfyui_url: http://127.0.0.1:8188
comfyui_api_key: ""
runninghub_api_key: ""
runninghub_concurrent_limit: 1
tts:
default_workflow: selfhost/tts_edge.json
image:
default_workflow: runninghub/image_flux.json
prompt_prefix: ""
video:
default_workflow: runninghub/video_wan2.1_fusionx.json
prompt_prefix: ""
这部分配置有两层意思。
第一层是连接参数:
comfyui_url
comfyui_api_key
runninghub_api_key
runninghub_concurrent_limit
runninghub_instance_type
第二层是不同能力的默认工作流:
tts.default_workflow
image.default_workflow
video.default_workflow
也就是说,Pixelle-Video 把 ComfyUI / RunningHub 当成一个“工作流执行平台”。TTS、图片、视频都可以通过不同 workflow 来执行。
在 PixelleVideoCore 中,ComfyKit 不是初始化时立即创建,而是懒加载。_get_comfykit_config() 会从 config_manager 读取 comfyui_url、comfyui_api_key、runninghub_api_key、runninghub_instance_type 等参数;_get_or_create_comfykit() 会计算配置 hash,如果配置发生变化,就关闭旧实例并重新创建 ComfyKit。
这个设计很实用。
因为用户可能在 WebUI 中修改 ComfyUI 地址或 RunningHub Key。
如果服务一启动就固定一个 ComfyKit 实例,后面修改配置可能不生效。
Pixelle-Video 通过“懒加载 + 配置 hash 检测”的方式,解决了配置变更后的重建问题。
八、RunningHub:解决没有本地显卡的问题
Pixelle-Video 同时支持本地 ComfyUI 和 RunningHub 云端工作流。
本地 ComfyUI 依赖用户自己的机器环境和显卡。
RunningHub 则可以把工作流放到云端执行。
从配置上看,RunningHub 主要依赖:
runninghub_api_key: ""
runninghub_concurrent_limit: 1
runninghub_instance_type: ""
其中 runninghub_concurrent_limit 用于控制并发执行数量,schema 中限制它的范围是 1 到 10。
这对 AI 视频生成很重要。
因为每个分镜都可能要生成图片或视频,如果逐帧串行执行,速度会比较慢。
如果使用云端工作流,并发限制允许,就可以同时处理多个分镜,缩短生成时间。
但是并发不是越高越好。
并发太高可能导致:
API 限流
任务失败率上升
云端费用增加
资源竞争
排队时间变长
所以把并发限制写进配置,是比较合理的设计。
九、MediaService:通过 workflow 生成图片和视频
Pixelle-Video 的媒体生成分两条路线。
第一条路线是 ComfyUI / RunningHub workflow。
这条路线由 MediaService 负责。media.py 中说明它是基于 ComfyUI workflow 的媒体生成服务,使用 ComfyKit 执行图片或视频生成工作流,并且会扫描 workflows 目录下以 image_ 或 video_ 开头、以 .json 结尾的工作流文件。
也就是说,如果你想增加一个新的本地生图工作流,思路大概是:
1. 在 workflows/selfhost/ 下增加 image_xxx.json
2. 在配置里把 image.default_workflow 指向它
3. WebUI 或 pipeline 调用 media 服务
4. MediaService 解析 workflow
5. ComfyKit 执行工作流
如果你想增加一个新的视频工作流,则类似:
1. 在 workflows/selfhost/ 或 workflows/runninghub/ 下增加 video_xxx.json
2. 在配置里把 video.default_workflow 指向它
3. 生成视频时传入 media_type="video"
4. MediaService 执行对应 workflow
所以,workflows/ 目录和 comfyui.image.default_workflow、comfyui.video.default_workflow 是配套关系。
配置决定默认用哪个工作流。
MediaService 负责找到并执行这个工作流。
十、TTS 配置:本地 Edge TTS 和 ComfyUI TTS
TTS 配置也是 Pixelle-Video 配置系统里比较有意思的一部分。
schema.py 中定义了 TTSSubConfig,其中包含 inference_mode、local、comfyui 三部分;本地 TTS 默认音色是 zh-CN-YunjianNeural,默认语速是 1.2。
tts_service.py 中的 TTSService 支持两种模式:local 和 comfyui。如果模式是 local,就走本地 Edge TTS;如果是 comfyui,就解析 workflow 并执行 ComfyUI 工作流。源码中 __call__() 支持 workflow、comfyui_url、runninghub_api_key、voice、speed、inference_mode、output_path 等参数。
这说明 Pixelle-Video 的 TTS 设计不是单一路线。
它可以:
用 Edge TTS 快速生成普通旁白
用 ComfyUI 工作流生成更复杂的语音
通过 RunningHub 执行云端 TTS 工作流
在调用时覆盖 voice、speed、workflow 等参数
这种设计对短视频工具很实用。
普通用户先用 Edge TTS 跑通流程。
高级用户再接入声音克隆、数字人语音或其他 TTS 工作流。
十一、API Providers:绕过 ComfyUI,直接调用图像/视频模型
Pixelle-Video 还有另一条媒体生成路线:直连 API 模型。
config.example.yaml 中的 api_providers 包含 openai、dashscope、ark、kling 等 provider,并且有 common.print_model_input、common.local_proxy、各 provider 的 api_key / base_url / use_proxy 等配置。
这部分由 APIProviderMediaService 负责。
api_media.py 中可以看到,它是“Direct API provider media generation adapter”,用于把 Pixelle 的媒体调用适配到直连 provider API。源码中维护了图片模型和视频模型列表,例如 DashScope、OpenAI、Seedream、Kling、Seedance 等,并且为部分视频模型定义了能力信息,如 text-to-video、image-to-video、reference-to-video、video-editing、duration、resolution、ratio、fps 等。
这条路线和 ComfyUI workflow 路线的区别是:
ComfyUI / RunningHub 路线:
通过工作流 JSON 调度模型
API Providers 路线:
直接调用云厂商图像/视频 API
为什么要同时支持两条路线?
因为用户需求不同。
有些用户熟悉 ComfyUI,希望自由组合节点、模型和工作流。
有些用户不想维护 ComfyUI,只想填 API Key 直接生成图片或视频。
有些模型可能还没有成熟的 ComfyUI 工作流,但已经提供了官方 API。
有些场景需要调用特定厂商的视频模型,比如可灵、Wan、Seedance 等。
所以 Pixelle-Video 把媒体生成能力拆成两类:
workflow-based media
direct provider media
这让系统更灵活。
十二、配置如何进入核心服务?
配置系统最终要被业务服务使用。
PixelleVideoCore 初始化时会从全局 config_manager 读取配置,并在 initialize() 中创建 LLMService、TTSService、APIProviderMediaService、MediaService、VideoService、FrameProcessor、PersistenceService、HistoryManager 等核心服务,同时注册 standard、custom、asset_based 三个 pipeline。
大致流程是:
config.yaml
↓
loader.py 读取 YAML
↓
schema.py 转成 PixelleVideoConfig
↓
ConfigManager 持有配置对象
↓
PixelleVideoCore 读取配置
↓
初始化 LLM / TTS / Media / API Media / Pipeline
↓
生成视频时各服务读取配置并执行
更关键的是,部分服务并不是只在初始化时读取一次配置。
例如 LLMService 中有注释说明,它不再缓存配置,而是通过 _get_config_value() 动态从 config_manager 读取 LLM 配置,以支持热更新。每次调用时也支持通过参数覆盖 api_key、base_url、model。
这说明 Pixelle-Video 的配置系统并不是静态的。
它考虑到了用户在 WebUI 中修改配置后,后续调用能使用新配置。
十三、为什么要分 LLM、ComfyUI、API Providers?
有人可能会问:
既然都是模型接口,为什么不统一写成一个 models 配置?
原因是它们的职责完全不同。
LLM 负责文字和结构化内容:
主题 → 文案
文案 → 分镜
文案 → 图片提示词
主题 → 标题
ComfyUI / RunningHub 负责工作流执行:
prompt → 图片
prompt → 视频
text → TTS
图片 + prompt → 视频
API Providers 负责直连云端媒体模型:
prompt → API 图像
prompt → API 视频
图片 + prompt → API 图生视频
视频 + 指令 → API 视频编辑
这三类能力虽然都叫“AI”,但调用方式、参数结构、错误处理、成本模型、输出结果都不同。
如果强行揉在一个配置块里,会非常混乱。
Pixelle-Video 的拆分方式更符合实际工程:
llm
只处理文本模型配置
comfyui
处理工作流执行平台配置
api_providers
处理直连媒体模型配置
template
处理视频视觉模板配置
这就是配置系统的核心设计思路:按能力边界拆分,而不是按厂商名称堆配置。
十四、模板配置:决定默认视频样式
除了模型配置,template 也放在配置系统里。
config.example.yaml 中的 template.default_template 默认指向 1080x1920/image_default.html,并且注释说明模板命名规范:static_*.html 表示不需要 AI 媒体的静态模板,image_*.html 表示需要 AI 图片的模板,video_*.html 表示需要 AI 视频的模板。
这说明模板不是简单的 UI 皮肤,而会影响生成流程。
例如:
static 模板
不需要生成 AI 图片/视频
image 模板
需要为每个分镜生成图片
video 模板
需要为每个分镜生成视频片段
所以模板配置和媒体生成配置是有关联的。
这也是 Pixelle-Video 比较有意思的地方:
视觉模板会反过来影响 AI 生成流程。
十五、从配置到生成的完整链路
现在可以把整个配置链路画出来:
【配置来源】
config.example.yaml
↓
复制为 config.yaml
↓
用户手动编辑,或在 WebUI 中填写
【配置加载】
loader.py
↓
读取 YAML 为 dict
↓
schema.py
↓
转成 PixelleVideoConfig
【配置管理】
ConfigManager
↓
提供 get / set / update / save / validate
【WebUI 配置】
settings.py
↓
读取当前配置
↓
用户修改 LLM、ComfyUI、RunningHub、API Providers
↓
保存回 config.yaml
【核心服务】
PixelleVideoCore
↓
初始化 LLMService
↓
初始化 TTSService
↓
初始化 MediaService
↓
初始化 APIProviderMediaService
↓
初始化 pipelines
【生成视频】
StandardPipeline
↓
LLM 生成文案和提示词
↓
TTS 生成旁白
↓
MediaService 或 APIProviderMediaService 生成图片/视频
↓
VideoService 合成最终视频
这条链路说明,配置系统不是孤立模块。
它贯穿了:
启动
页面展示
用户填写
配置保存
服务初始化
模型调用
工作流执行
视频生成
十六、二次开发时怎么扩展配置?
如果你想基于 Pixelle-Video 做二次开发,配置系统大概率是绕不开的。
1. 增加新的 LLM 预设
如果新模型兼容 OpenAI SDK,通常不需要大改 LLMService。
你主要需要增加预设,让用户在 WebUI 中可以快速选择:
base_url
model
api_key_url
默认 key 规则
因为底层 LLMService 已经按 OpenAI-compatible 的方式调用。
2. 增加新的 ComfyUI 工作流
如果是新的图片、视频或 TTS 工作流,通常需要:
1. 把 workflow JSON 放到 workflows/selfhost/ 或 workflows/runninghub/
2. 文件名按 image_、video_、tts_ 前缀命名
3. 在配置里设置 default_workflow
4. 确认参数能被 MediaService 或 TTSService 正确传入
MediaService 会扫描 image_ 和 video_ 前缀的 workflow 文件。
TTSService 则使用 tts_ 前缀的 workflow。
3. 增加新的 API 媒体模型
如果要支持一个新的云端图像/视频模型,通常需要:
1. 在 schema.py 中增加 provider 配置
2. 在 config.example.yaml 中增加示例字段
3. 在 settings.py 中增加 WebUI 输入项
4. 在 APIProviderMediaService 中增加 provider 调用逻辑
5. 定义模型能力、输入参数和输出解析方式
这个比增加 ComfyUI workflow 更复杂,因为直连 API 涉及认证方式、请求格式、返回格式、轮询任务、下载结果等问题。
4. 增加新的模板配置
如果只是换默认模板,改配置即可:
template:
default_template: "1080x1920/image_modern.html"
如果是新模板,需要放到 templates/ 目录,并遵守命名规范。模板类型会影响是否生成 AI 图片或 AI 视频。
十七、配置系统的优点和不足
从源码设计看,Pixelle-Video 的配置系统有几个明显优点。
第一,结构清楚。
LLM、ComfyUI、API Providers、Template 各自独立。
第二,有类型校验。
Pydantic schema 让配置不再是散乱 dict。
第三,支持 WebUI 保存。
普通用户可以直接在页面中配置,不一定要手写 YAML。
第四,支持热更新。
LLM 和 ComfyKit 都考虑了配置变更后的读取或重建。
第五,适合扩展。
新增模型、新增 workflow、新增 provider 都有明确入口。
当然,也有一些可以继续优化的地方。
比如,API Key 都写入本地 config.yaml,对本地工具没问题,但如果改造成 SaaS,就需要更严格的密钥管理。
再比如,直连 API Provider 越来越多后,settings.py 的配置面板可能会越来越长,后续可以考虑把 provider 配置抽象成动态表单。
另外,不同 provider 的能力差异很大,如果 UI 层能根据模型能力自动显示参数,会比手动写死更灵活。
十八、总结
这一篇我们分析了 Pixelle-Video 的配置系统。
它的核心不是简单读取一个 YAML 文件,而是形成了一条完整配置链路:
config.yaml
↓
loader.py
↓
schema.py
↓
ConfigManager
↓
WebUI settings.py
↓
PixelleVideoCore
↓
LLMService / TTSService / MediaService / APIProviderMediaService
↓
pipeline 生成视频
从设计上看,Pixelle-Video 把模型能力分成了四类配置:
llm
负责文案、标题、分镜、提示词
comfyui
负责本地 ComfyUI、RunningHub、TTS/Image/Video workflow
api_providers
负责 OpenAI、DashScope、ARK、Kling 等直连图像/视频 API
template
负责默认视频模板和视觉风格
这套设计的价值在于:
配置集中管理,能力按边界拆分,模型可以替换,工作流可以扩展,WebUI 和核心服务共用同一套配置。
对于一个 AI 短视频生成项目来说,这比单纯写死 API Key 和模型名要可靠得多。
397

被折叠的 条评论
为什么被折叠?



