Wan2.1 文生视频 支持批量生成、参数化配置和多语言提示词管理

Wan2.1 文生视频 支持批量生成、参数化配置和多语言提示词管理

flyfish

设计

一个基于 Wan2.1 文本到视频模型的自动化视频生成系统。

文件关系图

script.py
├── 读取 → config.json
│   ├── 模型配置 → 加载AI模型
│   ├── 生成参数 → 控制生成质量
│   └── 文件路径 → 定位其他文件
│
├── 读取 → prompt.json → 正向提示词
│
├── 读取 → negative_prompt_*.txt → 负向提示词
│
└── 输出 → 视频文件(如video_1.mp4)

1. script.py`(主程序)

  • 功能:执行AI视频生成的核心逻辑
  • 作用
    • 读取配置文件和提示词
    • 加载AI模型和参数
    • 控制视频生成流程
    • 统计生成时间和输出结果
  • 依赖:需要与配置文件和提示词文件配合使用

2. config.json(配置文件)

  • 功能:集中管理所有可配置参数
  • 作用
    • 模型配置(使用哪个模型、数据类型)
    • 生成参数(分辨率、帧数、引导强度、采样步数)
    • 文件路径(提示词文件、输出文件名格式)
  • 示例内容
    {"model": {"id": "Wan-AI/Wan2.1-T2V-1.3B-Diffusers","torch_dtype": "bfloat16"},"generation": {"height": 480,"width": 832,"num_inference_steps": 30}
    }
    

3. prompt.json(正向提示词库)

  • 功能:存储需要生成视频的文字描述
  • 作用
    • 支持批量生成多个视频
    • 每个描述对应一个输出视频
  • 示例内容
    [{ "prompt": "一只猫在草地上行走,写实风格" },{ "prompt": "一个人在海边跑步,日落场景" }
    ]
    

4. negative_prompt_cn.txt(中文负向提示词)

  • 功能:定义不希望出现在生成结果中的元素
  • 作用
    • 提高生成质量,避免常见瑕疵
    • 语言版本与正向提示词匹配
  • 示例内容
    明亮色调,过曝,静态,细节模糊,低质量
    

5. negative_prompt_en.txt(英文负向提示词)

  • 功能:与中文负向提示词相同,提供英文版本
  • 作用
    • 适配英文正向提示词
    • 通过配置文件切换使用语言
  • 示例内容
    Bright tones, overexposed, static, blurred details, low quality
    

完整内容

import torch
import json
import os
import time
from diffusers import AutoencoderKLWan, WanPipeline
from diffusers.utils import export_to_video# ----------------------
# 读取配置文件
# ----------------------
try:with open("config.json", "r", encoding="utf-8") as f:config = json.load(f)print("已加载配置文件")
except FileNotFoundError:print("错误: 未找到config.json文件,请确保该文件与脚本在同一目录下")exit(1)
except json.JSONDecodeError:print("错误: config.json文件格式不正确,请检查JSON语法")exit(1)
except Exception as e:print(f"错误: 读取配置文件时发生异常: {e}")exit(1)# ----------------------
# 解析配置参数
# ----------------------
# 模型相关配置
model_config = config.get("model", {})
model_id = model_config.get("id", "Wan-AI/Wan2.1-T2V-1.3B-Diffusers")
vae_subfolder = model_config.get("vae_subfolder", "vae")
torch_dtype = model_config.get("torch_dtype", "bfloat16")
device = model_config.get("device", "cuda")  # 支持"cuda"或"cpu"# 生成参数配置
generation_config = config.get("generation", {})
height = generation_config.get("height", 480)
width = generation_config.get("width", 832)
num_frames = generation_config.get("num_frames", 81)
guidance_scale = generation_config.get("guidance_scale", 5.0)
fps = generation_config.get("fps", 15)
output_prefix = generation_config.get("output_prefix", "output_")
num_inference_steps = generation_config.get("num_inference_steps", 50)  # 新增采样步数# 负向提示词配置
negative_config = config.get("negative_prompt", {})
default_negative_lang = negative_config.get("default_lang", "cn")  # 支持"cn"或"en"
negative_file_map = {"cn": negative_config.get("cn_file", "negative_prompt_cn.txt"),"en": negative_config.get("en_file", "negative_prompt_en.txt")
}# 正向提示词配置
prompt_config = config.get("prompts", {})
prompt_file = prompt_config.get("file", "prompt.json")
prompt_key = prompt_config.get("key", "prompt")  # JSON中提示词字段名# ----------------------
# 读取负向提示词
# ----------------------
def read_negative_prompt(lang):filename = negative_file_map[lang]try:with open(filename, "r", encoding="utf-8") as f:return f.read().strip()except FileNotFoundError:print(f"错误: 未找到负向提示词文件 {filename}")exit(1)except Exception as e:print(f"错误: 读取负向提示词文件时发生异常: {e}")exit(1)try:negative_prompt = read_negative_prompt(default_negative_lang)print(f"已加载{default_negative_lang.upper()}负向提示词")
except:print("错误: 负向提示词加载失败")exit(1)# ----------------------
# 读取正向提示词
# ----------------------
try:with open(prompt_file, "r", encoding="utf-8") as f:prompts_data = json.load(f)print(f"已加载 {len(prompts_data)} 个正向提示词")
except FileNotFoundError:print(f"错误: 未找到正向提示词文件 {prompt_file}")exit(1)
except json.JSONDecodeError:print(f"错误: {prompt_file}文件格式不正确,请确保是有效的JSON数组")exit(1)# ----------------------
# 模型初始化
# ----------------------
start_time = time.time()# 转换torch dtype
try:dtype = getattr(torch, torch_dtype)
except AttributeError:print(f"错误: 不支持的torch dtype: {torch_dtype}")exit(1)# 加载VAE
vae = AutoencoderKLWan.from_pretrained(model_id,subfolder=vae_subfolder,torch_dtype=dtype
)# 加载管道
pipe = WanPipeline.from_pretrained(model_id,vae=vae,torch_dtype=dtype
)
pipe.to(device)model_load_time = time.time() - start_time
print(f"模型加载完成,耗时: {model_load_time:.2f} 秒")# ----------------------
# 批量生成视频
# ----------------------
total_generation_time = 0
success_count = 0for i, item in enumerate(prompts_data, 1):try:prompt = item.get(prompt_key, "")if not prompt:print(f"警告: 第 {i} 个提示词字段为空,跳过")continueprint(f"\n---- 生成第 {i} 个视频 ----")print(f"正向提示词: {prompt[:50]}...")print(f"负向提示词: {negative_prompt[:50]}...")print(f"采样步数: {num_inference_steps}")  # 新增提示# 生成时间统计gen_start = time.time()# 生成视频output = pipe(prompt=prompt,negative_prompt=negative_prompt,height=height,width=width,num_frames=num_frames,guidance_scale=guidance_scale,num_inference_steps=num_inference_steps  ).frames[0]gen_time = time.time() - gen_starttotal_generation_time += gen_timesuccess_count += 1# 保存视频output_path = f"{output_prefix}{i}.mp4"export_to_video(output, output_path, fps=fps)print(f"✅ 视频保存至: {output_path}")print(f"⏱️ 生成耗时: {gen_time:.2f} 秒")except Exception as e:print(f"❌ 生成失败: {str(e)[:100]}...")continue# ----------------------
# 生成统计
# ----------------------
print("\n==================== 生成完成 ====================")
print(f"模型信息: {model_id}")
print(f"设备: {device}")
print(f"生成参数: {height}x{width}, {num_frames}帧, 引导尺度{guidance_scale}, 采样步数{num_inference_steps}")if success_count > 0:avg_time = total_generation_time / success_countprint(f"\n📊 统计结果:")print(f"   - 模型加载时间: {model_load_time:.2f} 秒")print(f"   - 成功生成: {success_count}/{len(prompts_data)}")print(f"   - 总生成时间: {total_generation_time:.2f} 秒")print(f"   - 平均耗时: {avg_time:.2f} 秒/视频")
else:print("\n⚠️ 没有成功生成任何视频")

config.json配置文件

{"model": {"id": "/media/models/Wan-AI/Wan2___1-T2V-14B-Diffusers/","vae_subfolder": "vae","torch_dtype": "bfloat16","device": "cuda" },"generation": {"height": 640,"width": 480, "num_frames": 81,"guidance_scale": 5.0,"fps": 15, "output_prefix": "video_","num_inference_steps": 150},"negative_prompt": {"default_lang": "cn","cn_file": "negative_prompt_cn.txt","en_file": "negative_prompt_en.txt"},"prompts": {"file": "prompt.json", "key": "prompt"}
}

negative_prompt_cn.txt

明亮色调,过曝,静态,细节模糊,字幕,风格,作品,绘画,图像,静态,整体灰暗,最差质量,低质量,JPEG压缩残留,丑陋,不完整,多余手指,绘制不佳的手,绘制不佳的脸,变形,毁容,畸形肢体,融合手指,静态图片,杂乱背景,三条腿,背景中有很多人,倒退行走

negative_prompt_en.txt

Vivid tones, overexposed, static, blurry details, subtitles, style, work, painting, image, still, overall grayish, worst quality, low quality, JPEG compression artifacts, ugly, incomplete, extra fingers, poorly drawn hands, poorly drawn faces, deformed, disfigured, morphologically deformed limbs, fused fingers, still image, cluttered background, three legs, many people in the background, walking backwards

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/80928.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Flannel后端为UDP模式下,分析数据包的发送方式——tun设备(三)

在分析 Kubernetes 环境中 Flannel UDP 模式的数据包转发时,我们提到 flannel.1 是一个 TUN 设备,它在数据包处理中起到了关键作用。 什么是 TUN 设备? TUN 设备(Tunnel 设备)是 Linux 系统中一种虚拟网络接口&#x…

Java中创建线程的几种方式

目录 Java 创建线程的几种方式 一、继承 Thread 类 核心原理 实现步骤 代码示例 简化写法(Lambda 表达式) 优缺点 二、实现 Runnable 接口 核心原理 实现步骤 代码示例 简化写法(Lambda 表达式) 优缺点分析 三、实现…

[Git] 基本操作及用户配置

文章目录 现在所讲,全部是本地Git仓库,不是远程仓库!Git是版本控制工具,而并非只能用远程仓库的版本控制工具! 什么是“仓库”(Repository)?创建一个 Git 本地仓库:git i…

layui 介绍

layui(谐音:类 UI) 是一套开源的 Web UI 解决方案,采用自身经典的模块化规范,并遵循原生 HTML/CSS/JS 的开发方式,极易上手,拿来即用。其风格简约轻盈,而组件优雅丰盈,从源代码到使用…

笔记:NAT

一、NAT 的基本概念 NAT(Network Address Translation,网络地址转换) 是一种在 IP 网络中重新映射 IP 地址的技术,主要用于解决 IPv4 地址短缺问题,同时提供一定的网络安全防护作用。 功能: 将内部网络&am…

cursor/vscode启动项目connect ETIMEDOUT 127.0.0.1:xx

现象: 上午正常使用cursor/vscode,因为需要写前端安装了nodejs16.20和vue2,结果下午启动前端服务无法访问,浏览器一直转圈。接着测试运行最简单的flask服务,vscode报错connect ETIMEDOUT 127.0.0.1:xx,要么…

EXO分布式部署deepseek r1

EXO 是一个支持分布式 AI 计算的框架,可以用于在多个设备(包括 Mac Studio)上运行大语言模型(LLM)。以下是联调 Mac Studio 512GB 的步骤: 安装 EXO • 从 EXO GitHub 仓库 下载源码或使用 git clone 获取…

python训练营打卡第30天

模块和库的导入 知识点回顾: 导入官方库的三种手段导入自定义库/模块的方式导入库/模块的核心逻辑:找到根目录(python解释器的目录和终端的目录不一致) 一、导入官方库 1.标准导入:导入整个库 import mathprint(&quo…

Unity 多时间源Timer定时器实战分享:健壮性、高效性、多线程安全与稳定性能全面解析

简介 Timer 是一个 Unity 环境下高效、灵活的定时任务调度系统,支持以下功能: •支持多种时间源(游戏时间 / 非缩放时间 / 真实时间) •支持一次性延迟执行和重复执行 •提供 ID、回调、目标对象等多种查询和销毁方式 •内建…

深入理解Docker和K8S

深入理解Docker和K8S Docker 是大型架构的必备技能,也是云原生核心。Docker 容器化作为一种轻量级的虚拟化技术,其核心思想:将应用程序及其所有依赖项打包在一起,形成一个可移植的单元。 容器的本质是进程: 容器是在…

docker中使用openresty

1.为什么要使用openresty 我这边是因为要使用1Panel,第一个最大的原因,就是图方便,比较可以一键安装。但以前一直都是直接安装nginx。所以需要一个过度。 2.如何查看openResty使用了nginx哪个版本 /usr/local/openresty/nginx/sbin/nginx …

CSS【详解】弹性布局 flex

适用场景 一维(行或列)布局 基本概念 包裹所有被布局元素的父元素为容器 所有被布局的元素为项目 项目的排列方向(垂直/水平)为主轴 与主轴垂直的方向交交叉轴 容器上启用 flex 布局 将容器的 display 样式设置为 flex 或 i…

全能视频处理工具介绍说明

软件介绍 本文介绍的软件是FFmpeg小白助手,它是一款视频处理工具。 使用便捷性 这款FFmpeg小白助手无需安装,解压出来就能够直接投入使用。 主要功能概述 该工具主要具备格式转换、文件裁剪、文件压缩、文件合并这四大功能。 格式转换能力 软件支持…

Linux中的DNS的安装与配置

DNS简介 DNS(DomainNameSystem)是互联网上的一项服务,它作为将域名和IP地址相互映射的一个分布式数据库,能够使人更方便的访问互联网。 DNS使用的是53端口 通常DNS是以UDP这个较快速的数据传输协议来查询的,但是没有查…

tshark的使用技巧(wireshark的命令行,类似tcpdump):转换格式,设置filter

tshark的使用技巧(wireshark的命令行,类似tcpdump):转换格式,设置filter tshark一般在 C:\Program Files\Wireshark 使用管理员权限 打开cmd tshark -D 列出支持抓包的接口: c:\Program Files\Wiresh…

vscode打开的文件被覆盖/只能打开两个文件(Visual Studio Code)

vscode打开的文件被覆盖/只能打开两个文件(Visual Studio Code) 单击代码文件:是预览模式,只会显示有限的一两个文件,在一个tab里更新显示 双击代码文件:是编辑模式,可以同时显示多个代码文件…

唯创安全优化纸业车间安全环境:门口盲区预警报警器的应用与成效

一、客户现场 客户主要从事于卷烟纸、成型纸、烟草制造业用纸及其他特定用途纸类制品的加工、生产与销售。在其厂区内,叉车频繁作业,车间环境复杂。经实地查看,发现几大安全隐患: 门口拐角隐患:门口拐角处因卷帘门阻…

Debezium快照事件监听器系统设计

Debezium快照事件监听器系统设计 1. 系统概述 1.1 设计目标 为 Debezium 的快照过程提供可扩展的事件监听机制允许外部系统在快照过程中执行自定义逻辑提供线程安全的事件分发机制确保监听器的异常不会影响主快照流程1.2 核心功能 表快照开始事件监听表快照完成事件监听行数据…

Ubuntu 20.04安装及配置docker

在安装docker的过程中主要参考博客:ubuntu20.04 安装docker (详细版) 但是在测试: sudo docker run hello-world 时报错: docker: Error response from daemon: Get "https://registry-1.docker.io/v2/": net/http: request ca…

第23天-Python Flet 开发指南

环境准备 pip install flet 示例1:基础计数器应用 import flet as ftdef main(page: ft.Page):page.title = "计数器"page.vertical_alignment = ft.MainAxisAlignment.CENTERtxt_number = ft.TextField(value="0", text_align=ft.TextAlign.RIGHT, wid…