简介:面向零基础AI内容创作者的漫剧制作教程,聚焦Kimi K2.5、Flux、Seedance 2.0三款免费工具协同,解决不会写剧本、不会画分镜、不会做动效的三大痛点;直接套用示例设定(校园甜宠题材、日系二次元风、9:16竖屏)即可产出1分钟短视频,适合抖音、快手自媒体新人及学生快速上手。资源为单个docx文档,压缩包仅11KB,文字精炼但步骤完整。已有267人学习。教程按“Kimi生成分镜脚本→Flux生成日系漫画分镜图→Seedance生成动态视频→剪映拼接导出”的主线展开:前期先确定人设、风格与规格以避免返工,中期给出可直接复制的提示词模板、Flux参数设置(9:16、1080×1920、风格强度80%)及Seedance动效生成方法,后期补充脚本简化要点、避坑指南和批量生产进阶技巧。内容还附带6镜头示例脚本与各步骤耗时估算,按步骤复制粘贴即可复现成果。
1. 做AI漫剧最难的从来不是工具本身,而是把Kimi、Flux、Seedance串成一条不卡壳的生产线
AI漫剧制作眼下最热闹的玩法,是拿Kimi写对白、Flux出日系二次元分镜图、Seedance把静态图变成动态镜头。这三样工具单拎出来都不难,但真正做成一集短剧的人都会卡在同一个地方:剧本格式没法直接喂给画图模型,画出来的角色换个镜头就变脸,视频生成完又跟对白对不上时间轴。这套资源的价值,是给出了一个从文本到图像再到视频的中间层设计——用一套固定的角色设定、分镜编号、画面描述规范,把三个模型串成一条可以批量跑的生产线。适合零基础想搭第一条漫剧流水线的人,也适合已经用单点工具翻过车、想把成品率提上来的从业者。下面按模块拆开讲。
2. Kimi剧本模块:把小说式对白改造成可切分的结构化分镜
2.1 为什么漫剧剧本必须用Kimi这类长上下文模型来写
漫剧和普通短视频不一样,它每一集都有明确的角色关系、场景切换和镜头节奏。用通用大模型写剧本,经常出现对白写得漂亮、但没有画面信息的情况——镜头怎么走、角色什么状态、背景是什么,全部缺失。Kimi K2.5在长上下文保持上比较稳,能在一个上下文窗口里同时维护角色表、场景表和几十个分镜条目,这是漫剧剧本生产最需要的。
你不用纠结用Kimi网页版、客户端还是API,模型本身输出结构是一样的。但整套自动化流程里必须有API入口,后面会调用它做批量生成。网页版适合前期调prompt,API适合进生产流程,这是两种用途,不冲突。
2.2 提示词模板:强制输出可解析的JSON分镜结构
漫剧剧本要进自动化流程,第一件事是让Kimi输出结构化数据。我一般会在prompt里给出明确的JSON schema要求,让每个分镜都包含场景、镜头号、角色、对白、画面描述等字段。下面是我常用的一套模板:
{ "role": "漫剧编剧", "task": "生成日系二次元漫剧分镜脚本", "constraints": [ "只输出JSON,不要markdown代码块包裹", "角色表角色数量不超过5个", "每个分镜的shot_desc必须包含画面主体、景别、镜头运动、表情", "对白使用日系轻小说口吻,每句不超过30个汉字" ], "output_schema": { "title": "剧集标题", "roles": [ { "role_id": "R1", "name": "角色名", "appearance": "外貌特征描述", "personality": "性格关键词" } ], "scenes": [ { "scene_id": "S1", "location": "场景地点", "time": "时间段" } ], "shots": [ { "shot_id": "SH001", "scene_id": "S1", "roles_in_shot": ["R1", "R2"], "dialogue": "角色对白", "shot_desc": "画面描述,包含景别、镜头运动、角色动作、表情", "duration": "预估秒数" } ] } }这段模板的逻辑是把漫剧剧本拆成三个层次:角色层、场景层、分镜层。角色层负责定义“这个人长什么样”,场景层负责定义“在哪里拍”,分镜层负责定义“这一刻镜头里发生了什么”。三个层次之间用role_id和scene_id关联,后面Flux出图和Seedance出视频都要靠这两个ID做数据对齐。
参数说明里有几个值得注意的地方。角色数量限制5个是为了控制后续出图和视频生成的规模,角色越多,Flux保持角色一致性的难度越高。对白字数限制是为了让字幕和视频节奏匹配,纯漫剧对白太长,画面根本来不及展示。shot_desc里强制写景别和镜头运动,是因为Flux只看静态画面描述,而Seedance需要镜头运动信息才能生成动态效果。
2.3 批量生成与清洗:调用Kimi API并处理返回结果
prompt调好以后,可以写一个批量生成脚本,把整集的文本描述发给Kimi,拿到返回结果后做数据清洗。这里有个常见的坑:Kimi偶尔会在JSON外面套markdown代码块标注,或者在某条对白里多打一个引号导致JSON解析失败。所以我一般会做两轮处理,先剥离代码块标记,再尝试解析。
import re import json import time from openai import OpenAI client = OpenAI( api_key="your-kimi-api-key", base_url="https://api.moonshot.cn/v1" # Kimi兼容OpenAI协议 ) def generate_script(topic: str, prompt_template: dict) -> dict: prompt = json.dumps(prompt_template, ensure_ascii=False) + "\n\n主题:" + topic resp = client.chat.completions.create( model="kimi-k2.5", messages=[ {"role": "system", "content": "你是一个漫剧编剧,输出严格JSON。"}, {"role": "user", "content": prompt} ], temperature=0.4, max_tokens=4000 ) raw = resp.choices[0].message.content # 第一轮清洗:剥离可能的markdown代码块 raw = re.sub(r"```json|```", "", raw).strip() # 第二轮清洗:截取第一个大括号到最后一个大括号 start = raw.find("{") end = raw.rfind("}") if start == -1 or end == -1: raise ValueError("返回内容中没有JSON结构") raw_json = raw[start:end + 1] try: return json.loads(raw_json) except json.JSONDecodeError: # 兜底:把单引号替换成双引号再试一次 fixed = raw_json.replace("'", "\"") return json.loads(fixed) # 批量生成三集剧本 topics = ["放学后的屋顶告白", "深夜食堂的猫耳店员", "夏日祭烟花下的约定"] episodes = [] for idx, topic in enumerate(topics): time.sleep(2) # 手动限速,避免触发限流 episodes.append(generate_script(topic, template)) # 保存结果 with open("episodes.json", "w", encoding="utf-8") as f: json.dump(episodes, f, ensure_ascii=False, indent=2)这段脚本的逻辑是先把整集主题拼进prompt,然后调用Kimi的对话补全接口。temperature设成0.4是刻意的——漫剧剧本需要创意性,但更需要结构稳定,温度太高会出现分镜数量忽多忽少、角色名拼写不一致的情况。max_tokens设4000基本够一集短剧的剧本体量,如果分镜超过30个,需要调大这个值。
提示:Kimi的API兼容OpenAI的调用格式,base_url指向moonshot的地址即可,不需要额外装SDK。
time.sleep(2)是给API调用加的手动限速。漫剧剧本一次性批量生成很容易触发限流,与其等报错再处理,不如先粗暴地控制请求频率。实际生产里可以用指数退避重试替代,后面第5章会展开讲。
3. Flux图像生成:用固定seed和角色卡把“角色一致性”从玄学变工程
3.1 Flux模型出图特性与漫剧适配选型
Flux模型在日系二次元风格上的表现确实能打,线条干净、色彩饱和、光影层次好。不过它真正的优势是对长提示词的遵循度高——普通模型画面描述超过30个字就开始丢信息,Flux在80到100字的复杂场景描述下还能保持构图完整。这对漫剧分镜出图非常关键,因为同一张图里往往要同时描述角色、动作、表情、场景、镜头角度五个维度。
选择Flux而不是其他模型还有个实际原因:社区生态成熟,Lora资源多。如果你觉得默认画风不够日系,可以挂一个二次元风格的Lora,后面第6章会提到怎么用Lora统一风格。
3.2 角色卡与prompt拼接规则:每个分镜都要拼入同一段角色特征
漫剧出图最容易翻车的点,是同一个角色在不同分镜里长得不一样。这个问题的根源在于Flux模型对“角色名”没有记忆能力,它只认视觉描述。所以做法是:把Kimi生成的roles表转成角色卡,每个角色的外貌特征浓缩成一段固定文本,拼进每一个涉及该角色的分镜prompt里。
from diffusers import FluxPipeline import torch # 加载Flux模型,半精度节省显存 pipe = FluxPipeline.from_pretrained( "black-forest-labs/FLUX.1-dev", torch_dtype=torch.bfloat16 ) pipe.enable_model_cpu_offload() # 角色卡:从Kimi生成的roles表转换而来 role_cards = { "R1": "银色双马尾少女,琥珀色眼睛,白色水手服,表情冷淡", "R2": "黑发猫耳少年,绿色瞳孔,黑色夹克,嘴角带笑" } # 场景基础描述,全局共享 scene_base = { "S1": "放学后的学校屋顶,傍晚金色阳光,微风", "S2": "深夜的小餐馆,暖黄色灯光,木质吧台", "S3": "夏日祭的夜晚,烟花在天空绽放,人群拥挤" } def build_flux_prompt(shot: dict, role_cards: dict, scene_base: dict) -> str: scene_desc = scene_base[shot["scene_id"]] role_desc = [] for role_id in shot.get("roles_in_shot", []): role_desc.append(role_cards[role_id]) # 拼接顺序:场景 + 角色 + 镜头指令 + 风格后缀 prompt = ", ".join([ scene_desc, ",".join(role_desc), shot["shot_desc"], "日系二次元风格,高细节,精美插画,赛璐璐上色" ]) return prompt # 分镜列表(从Kimi输出中取前5个演示) shots = episodes[0]["shots"][:5] prompts = [build_flux_prompt(s, role_cards, scene_base) for s in shots] # 固定seed,保证同角色图像风格统一 seed = 14321 generator = torch.Generator("cuda").manual_seed(seed) for shot, prompt in zip(shots, prompts): image = pipe( prompt, width=1024, height=576, num_inference_steps=28, guidance_scale=3.5, generator=generator ).images[0] # 按shot_id命名,供Seedance阶段回填 image.save(f"frames/{shot['shot_id']}_seed.png")这段脚本的核心是build_flux_prompt函数。它的拼接顺序是有讲究的:场景描述放最前面,让模型先确定空间环境;角色描述紧随其后,用高度一致的措辞锁定外观;最后放镜头动作信息和风格后缀。这个顺序不是玄学,Flux对prompt的注意力分配是从前往后的,前面内容权重更高。
参数说明是重点。width和height设成1024×576,这是漫剧竖屏转横屏常用的2K比例,太宽或太高都会增加生成时间和显存占用。num_inference_steps设28,Flux在20到30步之间画面质量趋于稳定,步数太少会出现细节粗糙,太多只是浪费时间。guidance_scale设3.5,这个值和文字符合度相关,太高画面会过饱和,太低又容易跑偏提示词。seed固定为14321,这一步非常重要——虽然每个分镜画面不同,但同一集里保持seed稳定,能让色彩倾向和笔触风格更统一。
注意:生成结果按shot_id加seed后缀命名,这是为了后面Seedance阶段能反查每个镜头对应的首帧图,不要省掉这一步。
3.3 批量出图的并发控制与文件命名规则
分镜出图是整条流水线里最耗时的一环,一集短剧20个镜头,单线程跑可能得五六分钟。常见的做法是用线程池做并发,但并发数要控制好,否则显存会被打爆。FXLUX.1-dev在1024×576分辨率下单张图约需12到16G显存,如果显卡显存不够,并发数就得降到1。
from concurrent.futures import ThreadPoolExecutor, as_completed import os def generate_and_save(shot: dict, out_dir: str = "frames"): """单镜头出图任务""" prompt = build_flux_prompt(shot, role_cards, scene_base) image = pipe( prompt, width=1024, height=576, num_inference_steps=28, guidance_scale=3.5, generator=torch.Generator("cuda").manual_seed(seed) ).images[0] # 文件名:分镜ID_场景ID_角色ID.png,三步对齐便捷 fname = f"{shot['shot_id']}_{shot['scene_id']}_{'_'.join(shot['roles_in_shot'])}.png" image.save(os.path.join(out_dir, fname)) return fname # 用线程池控制并发,避免显存溢出 all_shots = episodes[0]["shots"] os.makedirs("frames", exist_ok=True) with ThreadPoolExecutor(max_workers=2) as executor: futs = [executor.submit(generate_and_save, s) for s in all_shots] for fut in as_completed(futs): fname = fut.result() print(f"完成: {fname}") print(f"共生成 {len(all_shots)} 张分镜图")文件名规则看起来简单,实际是整条流水线的数据契约。Shot ID对应Kimi剧本里的镜头编号,Scene ID对应场景描述,角色ID列表对应角色卡。这三个信息全在文件名里,Seedance阶段读文件的时候不需要再回查数据库就能知道这个镜头属于哪个场景、哪个角色出场。
max_workers设2是相对稳妥的起步值。如果有24G显存可以尝试3或4,但并发任务同时读取模型权重会增加显存碎片,实际提速并不线性。更合理的做法是通过队列控制显存占用,避免多个torch.Generator同时持有CUDA上下文。
4. Seedance视频生成:把静态分镜图变成可拼接的镜头
4.1 Seedance 2.0的镜头控制逻辑与导演台概念
Flux出好图之后,下一步是把静态图变成动态镜头。Seedance 2.0在这类任务上的表现比较突出,特别是对首帧图的理解——它能读取图片内容并生成合理的后续运动,而不是简单做缩放平移。
Seedance 2.0还有一个值得关注的“导演台”机制,它的开源版本允许通过分镜参数控制镜头运动方式、景别变化、主体运动轨迹。这正好匹配漫剧生产场景:我们可以把Kimi写的shot_desc里的“镜头运动”字段,映射到Seedance的镜头控制参数上。这个映射关系要做到足够细,才能保证生成出来的视频符合预期,而不是让模型自由发挥。
4.2 用脚本把分镜参数转换为Seedance请求体
Seedance的服务端API通常需要一个frame_list来描述首帧图的获取位置,以及motion参数来控制镜头运动。在实际项目中,我会把所有分镜的镜头参数整理成一个请求体,直接发给Seedance服务端。
import requests import json # 分镜数据:从episodes.json读取第一集,并与出图结果合并 with open("episodes.json", "r", encoding="utf-8") as f: episodes = json.load(f) def split_video_requests(shot: dict, frame_path: str) -> dict: """ 构造Seedance请求体,把文字分镜翻译成镜头参数 """ motion_map = { "推进": {"type": "zoom_in", "speed": 0.8, "duration": 3}, "拉远": {"type": "zoom_out", "speed": 0.8, "duration": 3}, "左摇": {"type": "pan_left", "speed": 0.4, "duration": 3}, "右摇": {"type": "pan_right", "speed": 0.4, "duration": 3}, "固定": {"type": "static", "speed": 0, "duration": 2} } # 深度解析场景文本,识别出镜头指令 desc = shot["shot_desc"] shot_keys = ["推进", "拉远", "左摇", "右摇", "固定"] matched_motion = "固定" for key in shot_keys: if key in desc: matched_motion = key break # 按镜号的规则生成请求体 return { "frame_path": frame_path, "motion": motion_map[matched_motion], "start_frame": "auto", "end_frame": "auto", # 让模型自动预测尾部画面 "resolution": "1024x576", "fps": 24, "total_frames": int(motion_map[matched_motion]["duration"] * 24) } # 构造请求列表 requests_list = [] for shot in episodes[0]["shots"]: # 读取上面Flux生成的frame路径 frame_path = f"frames/{shot['shot_id']}_{shot['scene_id']}_{'_'.join(shot['roles_in_shot'])}.png" requests_list.append({ "shot_id": shot["shot_id"], "video_request": split_video_requests(shot, frame_path) }) # 发送到Seedance服务端 for item in requests_list[:3]: # 先测试前3个镜头 resp = requests.post( "https://api-seedance.example.com/v1/video/generate", json=item["video_request"], headers={"Authorization": "Bearer your-seedance-api-key"} ) print(item["shot_id"], resp.status_code)这段请求体的构造逻辑,是把Kimi的文本描述翻译成Seedance能理解的镜头参数。motion_map里定义了五种基础镜头运动,每个对应一个模型层的type值、速度和时长。为什么要这么做?因为Flux生成的描述文字是给画图模型看的,其中“推进”“拉远”这些词汇对Flux毫无意义——画面本身是静态的——但对Seedance至关重要,它决定视频里镜头的运动方向。
参数方面,total_frames用duration乘以fps。我设定3秒镜头24帧,也就是72帧,视频生成时间会显著增加,而漫剧的节奏本身需要短镜头快切——3到4秒的镜头在第5章会有解释。fps设24是为了和国内短视频平台常用的帧率一致,这样后期拼接时对不同片段的帧率要复查一次,避免出现跳帧。
注意:这里的请求逻辑中,end_frame用了auto方式。实际生产环境中,首尾帧方式会更稳——首帧交给Flux出图,尾帧可以用Kimi的续写逻辑生成,或者干脆再用一张Flux图指定尾帧画面。auto适合测试阶段,生产建议切到“first_last_frame”模式。
4.3 生成结果的下载与对白时间轴拼接
Seedance服务端生成视频后,一般是异步返回任务ID,然后轮询任务状态。拿到结果后要下载视频并按镜头编号存储,再和Kimi里的对白时间对齐。下面是一个简单的轮询+下载逻辑:
import time import os def poll_generate_result(task_id: str, timeout: int = 300): """轮询任务状态,直到完成或超时""" start = time.time() while time.time() - start < timeout: resp = requests.get( f"https://api-seedance.example.com/v1/task/{task_id}", headers={"Authorization": "Bearer your-seedance-api-key"} ) data = resp.json() if data["status"] == "succeeded": return data["video_url"] elif data["status"] == "failed": raise RuntimeError(f"任务失败: {data['error']}") time.sleep(10) raise TimeoutError(f"任务超时: {task_id}") # 存储下载路径 os.makedirs("clips", exist_ok=True) for task in submitted_tasks: video_url = poll_generate_result(task["task_id"]) clip_path = f"clips/{task['shot_id']}.mp4" # 实际的下载逻辑就是标准文件下载,这里用一个示意 with open(clip_path, "wb") as f: f.write(requests.get(video_url).content)视频下载之后,对白时间轴拼接通常用剪辑软件或ffmpeg完成。Seedance生成的单个镜头时长是3到4秒,一集20个镜头大约80秒的成片,这种体量用剪映或Premiere Pro手动拖放是可行的。如果要做全自动拼接,需要用ffmpeg的concat协议,把每个片段按分镜顺序拼成一个完整视频文件。这一步对算力要求不高,但对编码参数有一定要求,后面第5章展开讲避坑点时再细说。
5. 编排层与常见问题排查:把剧本到成片的中间层做稳
5.1 中间层配置:一个JSON串起三个模块
现在三个核心模块已经清楚了:Kimi负责剧本结构化,Flux负责出首帧图,Seedance负责生成动态镜头。但如果你直接按顺序手动跑,会发现到处都需要手工搬运数据——把Kimi输出复制给Flux脚本,再把图片一张张上传。所以还需要一个编排层,用一个全局配置文件把三个模块的数据接口统一起来。
{ "project": "日系二次元漫剧测试季", "episode": 1, "kimi": { "model": "kimi-k2.5", "temperature": 0.4, "max_tokens": 4000 }, "flux": { "model": "black-forest-labs/FLUX.1-dev", "seed": 14321, "width": 1024, "height": 576, "steps": 28, "guidance": 3.5 }, "seedance": { "resolution": "1024x576", "fps": 24, "shot_duration": 3, "motion_map": { "推进": {"type": "zoom_in", "speed": 0.8}, "拉远": {"type": "zoom_out", "speed": 0.8}, "左摇": {"type": "pan_left", "speed": 0.4}, "右摇": {"type": "pan_right", "speed": 0.4}, "固定": {"type": "static", "speed": 0} } }, "output": { "frames_dir": "frames", "clips_dir": "clips", "final_video": "output/result.mp4" } }这个配置文件把三个模块的超参数都集中放在一处,它的真正价值在于版本管理——当你调整剧本或者更换模型版本,只需要改配置,不用在每个脚本里搜索参数。特别是seed和shot_duration这两个值,改了其中一个,其他模块的行为就会相关联,配置统一就能减少很多不一致的问题。
5.2 编排脚本的批次处理思路
有了配置后,需要写一个主控脚本,按顺序执行“剧本生成→分镜出图→镜头生成→视频拼接”。这里有一个坑:生成视频的耗时会远超想象,所以批次处理必须支持断点续跑。
# 主控脚本示意 import subprocess import json def run_pipeline(config_path: str): """执行整条AI漫剧流水线""" # 阶段1: 剧本生成 subprocess.run(["python", "scripts/step1_script.py", config_path], check=True) # 阶段2: 分镜出图(幂等,支持resume) subprocess.run(["python", "scripts/step2_flux.py", config_path], check=True) # 阶段3: 视频生成(耗时最长,可校验结果后重跑) subprocess.run(["python", "scripts/step3_seedance.py", config_path], check=True) # 阶段4: 视频拼接 subprocess.run(["python", "scripts/step4_concat.py", config_path], check=True) if __name__ == "__main__": run_pipeline("config/episode1.json")这套编排逻辑的关键思路是每个脚本都保持幂等——重复执行不会产生副作用。Step2的Flux脚本在保存图片之前会检查文件是否已存在,如果存在且文件大小合理就直接跳过。Step3的Seedance脚本会在本地记录已经提交成功的task_id,重跑时只提交缺失的镜头。这样即使某一步在凌晨三点崩了,第二天改完参数重新跑,不会从头再来。
5.3 常见问题排查
到了这个阶段,前面那套流程里最容易翻车的几个点基本都出来了。下面按“现象→原因→解决”的格式整理,都是实测踩过的坑。
第一,Flux出图同一角色前后不相似。现象是Kimi剧本里同一个角色,在第一个分镜里是银发少女,第二个分镜里变成了棕色头发。原因是角色的外观描述在Kimi生成时前后措辞不一致,同一句话在不同分镜里出现了微调,Flux把变化当成不同角色处理。解决方法是角色卡必须人工核对并统一措辞,而且角色卡要固定放在prompt的场景描述之后、镜头指令之前,让模型把稳定特征放在高注意力权重区。
第二,Seedance生成视频时首帧画面突然拉伸变形。现象是输入Flux生成的横版图像,Seedance输出的视频首帧对不上,画面被裁切。原因是Flux输出的是1024×576,而Seedance内部有自己的安全分辨率,如果输入不匹配某些规格,它会自动居中裁剪。解决方法是统一尺寸——在Flux生成时严格设成1024×576,不要用“接近”的分辨率,然后再做一次降采样确保精确匹配。
第三,Kimi输出的镜头数量总是上下浮动,一集20个镜头第1次生成18个,第2次生成23个。原因是temperature调太高导致生成不稳定性,而且prompt里没有写死“必须生成恰好20个分镜”。解决方法是把temperature降到0.4以下,并且在约束里明确加一条“本集必须有且仅有20个分镜”,如果数量不符就重新生成。
第四,Seedance请求报错或者超时。现象是第10个镜头开始,API响应变得很慢甚至返回429限流错误。原因是请求太密,漫剧镜头数量多且体积大。解决方法是把time.sleep(10)的轮询间隔放宽,并且在线程池里限制并发提交数量,一次最多提交3个任务。
第五,最终拼接视频画面流畅但没有声音。现象是剪辑软件里的成片视频正常,但音轨对不上。原因是漫剧对白不是后期配的,而是Kimi生成的文本,需要在剪辑软件里用TTS生成配音。常见的做法是在拼接完之后统一做一步配音对齐,根据每个镜头的对白长度分配配音段落。如果跳过配音直接发布,观众会觉得这是一个哑剧。
6. 验证方法:三表对账和一套我每次必做的检查清单
流程跑通以后,先别急着发布。我每次交付一集漫剧前,都会做一遍三表对账:角色表、场景表、分镜表三张数据表和实际生成的文件做交叉比对。角色表要和分镜文件里的角色ID一致,场景表要和Flux生成图中出现的背景一致,分镜表要和Seedance生成的视频片段数量一致。任何一张对不上,说明中间某一步数据被篡改或丢失。
这份检查清单我固定下来,每次跑完流水线都会执行。第一,核对角色卡数量——剧本里出场5个角色,Flux输出目录里对应的文件名里就应该出现5个不同的角色ID,一个不多一个不少;第二,核对分镜文件数量——剧本定义了20个分镜,frames目录里就该有20张图,clips目录里就该有20个视频,少了任何一个都说明有任务没有成功返回;第三,核对分辨率和帧率——抽查3个视频文件,用ffprobe确认宽高都是1024×576,fps是24,这两项不一致会导致拼接时出现黑边或跳帧。
进阶技巧是训练一个统一风格的Lora。Flux社区可以训练自定义Lora,用同一部漫剧的前几集成片做数据集,训练一个角色风格Lora,挂载到Flux推理流程里——具体方法是在加载模型时使用lora权重文件,让模型在生成时倾向特定角色风格,而不是依赖prompt里反复描述外貌。这样做能大幅减轻角色一致性压力。
从那以后,我每次搭建新项目的流水线,不管工具换成什么模型,都会强制把三表对账走一遍,数据对不齐绝不进入下一步。这套流程看着多一道工序,实际省掉的是后期数十个小时的返工时间。希望帮到你。
本文还有配套的精品资源,点击获取