突破静态边界:FLUX.1-dev-Controlnet-Union帧序列生成全指南
你是否还在为AI图像生成停留在单帧而苦恼?是否尝试过将ControlNet的精确控制与视频流畅性结合却不得其门而入?本文将系统揭示如何利用FLUX.1-dev-Controlnet-Union实现从静态控制到动态视频的完整工作流,包含7种控制模式的帧间一致性优化、3种插值算法对比、以及工业级批量处理方案,让你的AI创作从此动起来。
读完本文你将掌握:
- 多ControlNet协同控制帧序列生成的核心参数调优
- 帧间一致性保持的5大关键技术(含代码实现)
- 从单张控制图到60秒视频的全流程自动化方案
- 不同插值算法在视频生成中的性能对比与选型指南
- 批量处理1000+帧的显存优化策略
技术背景与核心挑战
FLUX.1-dev-Controlnet-Union作为新一代多模态控制网络,支持Canny边缘检测(控制模式0)、Tile纹理控制(控制模式1)、Depth深度估计(控制模式2)等7种控制模式,其核心优势在于通过单一模型实现多维度条件控制。但将其能力扩展到视频领域面临三大核心挑战:
表1:FLUX.1-dev-Controlnet-Union控制模式视频适用性评估
| 控制模式 | 模式ID | 视频适用性 | 帧间一致性 | 计算开销 | 典型应用场景 |
|---|---|---|---|---|---|
| Canny边缘检测 | 0 | ★★★★☆ | 高 | 低 | 角色动作捕捉 |
| Tile纹理控制 | 1 | ★★★★★ | 最高 | 中 | 背景纹理生成 |
| Depth深度估计 | 2 | ★★★☆☆ | 中 | 高 | 3D场景漫游 |
| Blur模糊控制 | 3 | ★★☆☆☆ | 低 | 低 | 动态焦点变化 |
| Pose姿态控制 | 4 | ★★★★☆ | 高 | 中 | 人物动画生成 |
| Gray灰度控制 | 5 | ★☆☆☆☆ | 中 | 低 | 黑白风格视频 |
| LQ低质量重建 | 6 | ★★★☆☆ | 中 | 高 | 视频超分辨率 |
帧序列生成基础架构
实现基于ControlNet的视频生成需要构建"控制信号提取→关键帧生成→帧间插值→后处理优化"的完整流水线。以下为系统架构流程图:
环境准备与基础配置
首先克隆项目仓库并安装依赖:
git clone https://gitcode.com/mirrors/InstantX/FLUX.1-dev-Controlnet-Union
cd FLUX.1-dev-Controlnet-Union
pip install -r requirements.txt
核心配置文件config.json包含模型关键参数,其中与视频生成相关的核心配置如下:
{
"num_inference_steps": 24, // 推理步数,影响生成质量与速度
"guidance_scale": 3.5, // 引导尺度,控制prompt遵从度
"controlnet_conditioning_scale": 0.5, // 控制强度,影响控制信号权重
"joint_attention_dim": 4096, // 联合注意力维度,影响多模态融合质量
"num_attention_heads": 24 // 注意力头数量,影响特征提取能力
}
关键帧生成技术详解
关键帧是视频生成的基础,其质量直接决定最终视频效果。以下实现基于Canny边缘检测的人物动作关键帧生成完整代码:
import torch
import cv2
import numpy as np
from diffusers.utils import load_image
from diffusers import FluxControlNetPipeline, FluxControlNetModel
from PIL import Image
class KeyframeGenerator:
def __init__(self, control_mode=0, device="cuda"):
"""
初始化关键帧生成器
:param control_mode: 控制模式,0=Canny,1=Tile,2=Depth,3=Blur,4=Pose,5=Gray,6=LQ
:param device: 运行设备,"cuda"或"cpu"
"""
self.control_mode = control_mode
self.device = device
self.base_model = "black-forest-labs/FLUX.1-dev"
self.controlnet_model = "InstantX/FLUX.1-dev-Controlnet-Union"
# 加载模型
self.controlnet = FluxControlNetModel.from_pretrained(
self.controlnet_model,
torch_dtype=torch.bfloat16
)
self.pipe = FluxControlNetPipeline.from_pretrained(
self.base_model,
controlnet=self.controlnet,
torch_dtype=torch.bfloat16
)
self.pipe.to(self.device)
# 设置控制模式特定参数
self.control_params = self._get_control_params()
def _get_control_params(self):
"""根据控制模式设置最优参数"""
params = {
0: {"controlnet_conditioning_scale": 0.6, "guidance_scale": 3.5}, # Canny
1: {"controlnet_conditioning_scale": 0.8, "guidance_scale": 4.0}, # Tile
2: {"controlnet_conditioning_scale": 0.7, "guidance_scale": 3.8}, # Depth
3: {"controlnet_conditioning_scale": 0.5, "guidance_scale": 3.2}, # Blur
4: {"controlnet_conditioning_scale": 0.75, "guidance_scale": 3.6}, # Pose
5: {"controlnet_conditioning_scale": 0.4, "guidance_scale": 3.0}, # Gray
6: {"controlnet_conditioning_scale": 0.65, "guidance_scale": 3.7} # LQ
}
return params.get(self.control_mode, {"controlnet_conditioning_scale": 0.5, "guidance_scale": 3.5})
def preprocess_control_image(self, image_path):
"""预处理控制图像"""
image = load_image(image_path).convert("RGB")
# 根据控制模式进行预处理
if self.control_mode == 0: # Canny边缘检测
img_np = np.array(image)
img_gray = cv2.cvtColor(img_np, cv2.COLOR_RGB2GRAY)
edges = cv2.Canny(img_gray, 100, 200)
edges = cv2.cvtColor(edges, cv2.COLOR_GRAY2RGB)
return Image.fromarray(edges)
elif self.control_mode == 2: # Depth深度估计
# 实际应用中应使用专门的深度估计模型
return image
else:
return image
def generate_keyframe(self, prompt, control_image_path, seed=None, num_inference_steps=24):
"""
生成单帧关键帧
:param prompt: 文本提示词
:param control_image_path: 控制图像路径
:param seed: 随机种子,None为随机
:param num_inference_steps: 推理步数
:return: 生成的图像
"""
# 加载并预处理控制图像
control_image = self.preprocess_control_image(control_image_path)
width, height = control_image.size
# 设置随机种子
generator = torch.Generator(self.device).manual_seed(seed) if seed else None
# 生成图像
result = self.pipe(
prompt=prompt,
control_image=control_image,
control_mode=self.control_mode,
width=width,
height=height,
controlnet_conditioning_scale=self.control_params["controlnet_conditioning_scale"],
guidance_scale=self.control_params["guidance_scale"],
num_inference_steps=num_inference_steps,
generator=generator
)
return result.images[0]
def generate_keyframe_sequence(self, prompts, control_image_paths, seeds=None):
"""
生成关键帧序列
:param prompts: 提示词列表
:param control_image_paths: 控制图像路径列表
:param seeds: 种子列表,长度应与提示词列表一致,None为随机
:return: 生成的图像列表
"""
if len(prompts) != len(control_image_paths):
raise ValueError("提示词数量必须与控制图像数量一致")
if seeds and len(seeds) != len(prompts):
raise ValueError("种子数量必须与提示词数量一致")
keyframes = []
for i in range(len(prompts)):
seed = seeds[i] if seeds else None
keyframe = self.generate_keyframe(
prompt=prompts[i],
control_image_path=control_image_paths[i],
seed=seed
)
keyframes.append(keyframe)
print(f"已生成关键帧 {i+1}/{len(prompts)}")
return keyframes
# 使用示例
if __name__ == "__main__":
# 初始化生成器(Canny边缘控制模式)
generator = KeyframeGenerator(control_mode=0, device="cuda")
# 生成单张关键帧
prompt = "一位穿着未来科技感服装的女性,站在充满霓虹灯光的城市街道上,雨水打湿的地面反射着灯光,超现实主义风格,8K分辨率"
keyframe = generator.generate_keyframe(
prompt=prompt,
control_image_path="./images/canny.jpg",
seed=42
)
keyframe.save("keyframe_single.png")
# 生成关键帧序列
prompts = [
"一位穿着未来科技感服装的女性,站在充满霓虹灯光的城市街道左侧,雨水打湿的地面",
"一位穿着未来科技感服装的女性,站在充满霓虹灯光的城市街道中央,雨水打湿的地面",
"一位穿着未来科技感服装的女性,站在充满霓虹灯光的城市街道右侧,雨水打湿的地面"
]
control_images = ["./images/canny_1.jpg", "./images/canny_2.jpg", "./images/canny_3.jpg"]
seeds = [42, 43, 44] # 连续种子确保一致性
keyframes = generator.generate_keyframe_sequence(
prompts=prompts,
control_image_paths=control_images,
seeds=seeds
)
for i, kf in enumerate(keyframes):
kf.save(f"keyframe_{i}.png")
种子同步与帧间一致性控制
实现视频流畅性的核心在于保持帧间一致性,种子同步技术是关键。以下为三种种子策略的对比:
表2:种子策略对比
| 策略类型 | 实现方法 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|---|
| 完全同步 | 所有帧使用相同种子 | 最高一致性 | 缺乏变化性 | 静态场景 |
| 增量同步 | 种子=基础种子+帧索引 | 中等一致性,有变化 | 可能出现跳变 | 缓慢变化场景 |
| 混合同步 | 关键帧固定种子,插值帧随机 | 平衡一致性与变化性 | 实现复杂 | 动态场景 |
推荐实现代码:
def generate_consistent_sequence(num_frames=10, base_seed=42, variation_strength=0.1):
"""
生成具有帧间一致性的种子序列
:param num_frames: 帧数
:param base_seed: 基础种子
:param variation_strength: 变化强度(0-1),值越小一致性越高
:return: 种子列表
"""
seeds = []
for i in range(num_frames):
# 基础种子 + 帧索引 * 变化因子
seed = int(base_seed + i * (100 * variation_strength))
seeds.append(seed)
return seeds
帧间插值技术实现
关键帧生成后,需要通过插值技术填充中间帧。以下为三种主流插值算法的实现与对比:
1. 线性插值(基础方法)
import torch
import numpy as np
from PIL import Image
def linear_interpolation(keyframes, num_inter_frames=5):
"""
线性插值生成中间帧
:param keyframes: 关键帧列表(PIL.Image对象)
:param num_inter_frames: 每对关键帧间的插值帧数
:return: 完整帧序列
"""
sequence = []
for i in range(len(keyframes) - 1):
# 添加当前关键帧
sequence.append(keyframes[i])
# 获取前后关键帧的numpy数组
frame1 = np.array(keyframes[i]).astype(np.float32)
frame2 = np.array(keyframes[i+1]).astype(np.float32)
# 生成中间帧
for t in range(1, num_inter_frames + 1):
# 计算插值权重
alpha = t / (num_inter_frames + 1)
# 线性插值
inter_frame = (1 - alpha) * frame1 + alpha * frame2
inter_frame = np.clip(inter_frame, 0, 255).astype(np.uint8)
# 添加到序列
sequence.append(Image.fromarray(inter_frame))
# 添加最后一个关键帧
sequence.append(keyframes[-1])
return sequence
2. 双向光流插值(进阶方法)
def optical_flow_interpolation(keyframes, num_inter_frames=5):
"""
使用光流进行帧间插值(需要安装cv2和flow_vis)
:param keyframes: 关键帧列表(PIL.Image对象)
:param num_inter_frames: 每对关键帧间的插值帧数
:return: 完整帧序列
"""
try:
import cv2
from flow_vis import flow_visualize
except ImportError:
raise ImportError("需要安装opencv-python和flow_vis: pip install opencv-python flow_vis")
sequence = []
for i in range(len(keyframes) - 1):
# 添加当前关键帧
sequence.append(keyframes[i])
# 转换为OpenCV格式
frame1 = cv2.cvtColor(np.array(keyframes[i]), cv2.COLOR_RGB2BGR)
frame2 = cv2.cvtColor(np.array(keyframes[i+1]), cv2.COLOR_RGB2BGR)
# 转换为灰度图
gray1 = cv2.cvtColor(frame1, cv2.COLOR_BGR2GRAY)
gray2 = cv2.cvtColor(frame2, cv2.COLOR_BGR2GRAY)
# 计算光流
flow = cv2.calcOpticalFlowFarneback(
gray1, gray2, None,
pyr_scale=0.5, levels=3, winsize=15,
iterations=3, poly_n=5, poly_sigma=1.2, flags=0
)
# 生成中间帧
for t in range(1, num_inter_frames + 1):
alpha = t / (num_inter_frames + 1)
# 创建网格
h, w = flow.shape[:2]
grid_x, grid_y = np.meshgrid(np.arange(w), np.arange(h))
# 计算新位置
new_x = grid_x - flow[..., 0] * alpha
new_y = grid_y - flow[..., 1] * alpha
# 规范化坐标到[-1, 1]
new_x = (new_x / w - 0.5) * 2
new_y = (new_y / h - 0.5) * 2
# 堆叠网格
grid = np.stack((new_x, new_y), axis=-1)
# 转换为PyTorch张量并进行采样
frame1_tensor = torch.from_numpy(frame1).permute(2, 0, 1).float() / 255.0
grid_tensor = torch.from_numpy(grid).float().unsqueeze(0)
# 使用grid_sample进行插值
with torch.no_grad():
warped = torch.nn.functional.grid_sample(
frame1_tensor.unsqueeze(0),
grid_tensor,
mode='bilinear',
padding_mode='border',
align_corners=True
)
# 转换回PIL图像
inter_frame = (warped.squeeze().permute(1, 2, 0).numpy() * 255).astype(np.uint8)
inter_frame = cv2.cvtColor(inter_frame, cv2.COLOR_BGR2RGB)
sequence.append(Image.fromarray(inter_frame))
# 添加最后一个关键帧
sequence.append(keyframes[-1])
return sequence
3. AI插值(高级方法)
def ai_based_interpolation(keyframes, num_inter_frames=5, model_name="stabilityai/stable-video-diffusion-img2vid-xt"):
"""
使用AI模型进行帧间插值
:param keyframes: 关键帧列表(PIL.Image对象)
:param num_inter_frames: 每对关键帧间的插值帧数
:param model_name: AI模型名称
:return: 完整帧序列
"""
try:
import torch
from diffusers import StableVideoDiffusionPipeline
except ImportError:
raise ImportError("需要安装diffusers和torch: pip install diffusers torch")
# 加载模型
pipe = StableVideoDiffusionPipeline.from_pretrained(
model_name,
torch_dtype=torch.float16,
variant="fp16"
)
pipe = pipe.to("cuda" if torch.cuda.is_available() else "cpu")
sequence = []
for i in range(len(keyframes) - 1):
# 添加当前关键帧
sequence.append(keyframes[i])
# 准备输入
image = keyframes[i].resize((1024, 576)) # SVD模型期望的输入尺寸
# 生成视频帧
generator = torch.manual_seed(42)
frames = pipe(
image,
decode_chunk_size=8,
generator=generator,
num_frames=num_inter_frames+1, # 包括起始帧
motion_bucket_id=127,
noise_aug_strength=0.02
).frames[0]
# 添加中间帧(跳过第一帧,因为它是输入图像的复制)
sequence.extend(frames[1:])
# 添加最后一个关键帧
sequence.append(keyframes[-1])
return sequence
表3:插值算法性能对比
| 算法 | 速度 | 质量 | 显存占用 | 适用场景 | 实现复杂度 |
|---|---|---|---|---|---|
| 线性插值 | ★★★★★ | ★★☆☆☆ | 低 | 快速预览 | 简单 |
| 光流插值 | ★★★☆☆ | ★★★★☆ | 中 | 中等质量视频 | 中等 |
| AI插值 | ★☆☆☆☆ | ★★★★★ | 高 | 高质量视频 | 复杂 |
批量处理与显存优化
对于长视频生成,批量处理与显存优化至关重要。batch_processor.py提供了基础框架,以下为优化版本:
import torch
import json
import os
import glob
import numpy as np
from PIL import Image
from tqdm import tqdm
from diffusers import FluxControlNetPipeline, FluxControlNetModel
class OptimizedBatchProcessor:
def __init__(self, config_path="config.json", device="cuda"):
"""
优化的批量处理器
:param config_path: 配置文件路径
:param device: 运行设备
"""
# 加载配置
with open(config_path, "r") as f:
self.config = json.load(f)
self.device = device
self.dtype = torch.bfloat16 if device == "cuda" and torch.cuda.is_bf16_supported() else torch.float16
# 初始化模型
self._init_model()
# 显存优化参数
self.max_batch_size = self._determine_batch_size()
self.gradient_checkpointing = True
def _init_model(self):
"""初始化模型并应用优化"""
self.base_model = "black-forest-labs/FLUX.1-dev"
self.controlnet_model = "InstantX/FLUX.1-dev-Controlnet-Union"
# 加载控制网络
self.controlnet = FluxControlNetModel.from_pretrained(
self.controlnet_model,
torch_dtype=self.dtype
)
# 加载主管道
self.pipe = FluxControlNetPipeline.from_pretrained(
self.base_model,
controlnet=self.controlnet,
torch_dtype=self.dtype
)
# 应用优化
self._apply_optimizations()
# 移动到设备
self.pipe.to(self.device)
def _apply_optimizations(self):
"""应用显存优化"""
# 启用梯度检查点
if self.gradient_checkpointing:
self.pipe.enable_gradient_checkpointing()
# 启用模型并行(如果支持)
if torch.cuda.device_count() > 1:
self.pipe.enable_model_cpu_offload()
else:
# 单GPU优化
self.pipe.enable_sequential_cpu_offload()
# 启用内存高效注意力(如果可用)
try:
self.pipe.enable_xformers_memory_efficient_attention()
except ImportError:
print("xFormers未安装,无法启用内存高效注意力")
def _determine_batch_size(self):
"""根据显存自动确定最大批量大小"""
if self.device != "cuda":
return 1
# 获取GPU显存信息
total_memory = torch.cuda.get_device_properties(0).total_memory / (1024 ** 3) # GB
# 根据显存大小设置批量大小
if total_memory >= 24:
return 8
elif total_memory >= 16:
return 4
elif total_memory >= 10:
return 2
else:
return 1
def preprocess_images(self, image_paths):
"""预处理图像批次"""
images = []
for path in image_paths:
img = Image.open(path).convert("RGB")
# 调整大小(保持纵横比)
max_size = 1024
w, h = img.size
if max(w, h) > max_size:
ratio = max_size / max(w, h)
img = img.resize((int(w * ratio), int(h * ratio)), Image.LANCZOS)
images.append(img)
return images
def batch_process(self, input_dir, output_dir, prompt_file=None, num_inter_frames=5):
"""
批量处理图像并生成视频帧序列
:param input_dir: 输入图像目录
:param output_dir: 输出目录
:param prompt_file: 提示词文件
:param num_inter_frames: 每对关键帧间的插值帧数
"""
# 创建输出目录
os.makedirs(output_dir, exist_ok=True)
os.makedirs(os.path.join(output_dir, "keyframes"), exist_ok=True)
os.makedirs(os.path.join(output_dir, "sequence"), exist_ok=True)
# 加载提示词
prompts = []
if prompt_file:
with open(prompt_file, "r") as f:
prompts = [line.strip() for line in f if line.strip()]
# 获取所有图像文件
image_extensions = ["jpg", "jpeg", "png", "webp"]
image_paths = []
for ext in image_extensions:
image_paths.extend(glob.glob(os.path.join(input_dir, f"*.{ext}")))
# 按文件名排序
image_paths.sort()
if not image_paths:
print("未找到图像文件")
return
print(f"发现{len(image_paths)}张图像,开始批量处理...")
# 分批次处理关键帧
keyframes = []
for i in tqdm(range(0, len(image_paths), self.max_batch_size), desc="处理关键帧"):
batch_paths = image_paths[i:i+self.max_batch_size]
batch_images = self.preprocess_images(batch_paths)
batch_prompts = prompts[i:i+self.max_batch_size] if prompts else ["高质量图像生成"]*len(batch_paths)
# 生成关键帧(此处省略实际生成代码,参考前面的关键帧生成器)
# keyframes.extend(generated_images)
# 保存关键帧
for j, img in enumerate(batch_images): # 这里用输入图像代替生成的关键帧
keyframe_path = os.path.join(output_dir, "keyframes", f"keyframe_{i+j}.png")
img.save(keyframe_path)
keyframes.append(img)
# 生成完整序列(插值)
print(f"生成完整序列,共{len(keyframes)}个关键帧,每对之间生成{num_inter_frames}个中间帧")
sequence = []
# 使用光流插值生成中间帧(实际应用中可选择最合适的插值方法)
for i in tqdm(range(len(keyframes) - 1), desc="生成中间帧"):
# 添加当前关键帧
sequence.append(keyframes[i])
# 生成中间帧(此处省略实际插值代码,参考前面的插值方法)
# inter_frames = optical_flow_interpolation([keyframes[i], keyframes[i+1]], num_inter_frames)
# sequence.extend(inter_frames[1:-1]) # 排除重复的关键帧
# 添加最后一个关键帧
sequence.append(keyframes[-1])
# 保存完整序列
print(f"生成完整序列共{len(sequence)}帧,保存到{output_dir}/sequence")
for i, frame in enumerate(tqdm(sequence, desc="保存序列")):
frame_path = os.path.join(output_dir, "sequence", f"frame_{i:06d}.png")
frame.save(frame_path)
print("批量处理完成")
if __name__ == "__main__":
processor = OptimizedBatchProcessor(config_path="config.json", device="cuda")
processor.batch_process(
input_dir="./input_images",
output_dir="./output_sequence",
prompt_file="./prompts.txt",
num_inter_frames=5
)
显存优化的五大关键技术:
- 梯度检查点:牺牲少量计算时间换取显存使用降低50%
- 模型并行:多GPU分摊模型权重存储
- CPU卸载:仅在需要时将模型部分加载到GPU
- 内存高效注意力:使用xFormers或FlashAttention减少注意力计算显存占用
- 动态批量大小:根据GPU显存自动调整批量大小
完整工作流与最佳实践
以下是从控制视频到最终输出的完整工作流程:
常见问题与解决方案
表4:常见问题排查指南
| 问题 | 可能原因 | 解决方案 | 难度级别 |
|---|---|---|---|
| 帧间闪烁 | 光照不一致 | 1. 使用相同的光照提示词 2. 降低控制强度 3. 增加色彩一致性后处理 | ★★☆☆☆ |
| 物体变形 | 控制信号不稳定 | 1. 提高控制强度 2. 使用更精确的控制图 3. 减少插值帧数 | ★★★☆☆ |
| 生成速度慢 | 批量大小过大 | 1. 减小批量大小 2. 启用CPU卸载 3. 使用更小分辨率 | ★☆☆☆☆ |
| 显存溢出 | 分辨率或批量过大 | 1. 降低分辨率 2. 启用梯度检查点 3. 使用fp16/bf16精度 | ★★☆☆☆ |
| 控制效果弱 | 控制权重不足 | 1. 提高controlnet_conditioning_scale 2. 调整引导尺度 3. 使用更清晰的控制图 | ★☆☆☆☆ |
性能优化检查表
- 使用bf16精度(显存减少50%,质量损失极小)
- 启用xFormers内存高效注意力(显存减少30-40%)
- 设置合理的控制强度(0.5-0.8之间,根据模式调整)
- 使用种子同步策略(保持帧间一致性)
- 关键帧间隔不超过10帧(平衡质量与效率)
- 预计算控制图(节省重复计算时间)
- 分阶段处理(先低分辨率预览,再高分辨率生成)
总结与未来展望
FLUX.1-dev-Controlnet-Union通过多模态控制能力为视频生成提供了新的可能性,本文详细介绍了从关键帧生成、帧间插值到批量处理的完整工作流。核心要点包括:
- 选择合适的控制模式(Canny和Tile模式在视频生成中表现最佳)
- 实现种子同步策略以保持帧间一致性
- 根据需求选择合适的插值算法(光流插值提供最佳性价比)
- 应用显存优化技术以处理大规模视频序列
未来发展方向:
- 多ControlNet协同控制(同时使用Canny+Depth提升控制精度)
- 基于视频理解的动态控制权重调整
- 实时视频生成与直播应用
- 3D场景理解与摄像机轨迹控制
通过本文介绍的技术,你可以将FLUX.1-dev-Controlnet-Union的能力从静态图像扩展到动态视频领域,创造出更加生动、连贯的AI生成内容。
立即行动:
- 克隆项目仓库:
git clone https://gitcode.com/mirrors/InstantX/FLUX.1-dev-Controlnet-Union - 按照示例代码准备控制图像和提示词
- 从简单的3关键帧序列开始尝试
- 逐步优化参数并扩展到更长序列
祝你的视频生成之旅顺利!如有任何问题,欢迎在项目仓库提交issue或参与讨论。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



