AttributeError: type object ‘OutputKeys‘ has no attribute ‘OUTPUT_VIDEO_PATH‘

Traceback (most recent call last):
  File "text-to-video.py", line 17, in
    video_path = output[OutputKeys.OUTPUT_VIDEO_PATH]
AttributeError: type object 'OutputKeys' has no attribute 'OUTPUT_VIDEO_PATH'

import subprocess
import sys
subprocess.check_call([sys.executable, "-m", "pip", "install", "datasets==2.16.1", "-i", "https://mirrors.aliyun.com/pypi/simple"])
import os
from modelscope.pipelines import pipeline
from modelscope.outputs import OutputKeys
pipeline = pipeline("text-to-video-synthesis", "damo/text-to-video-synthesis", device="cpu")
prompts = [
    "A cat walking in a garden under sunlight, 0-6 seconds",
    "A cat walking in a garden under sunlight, 6-12 seconds",
    "A cat walking in a garden under sunlight, 12-18 seconds",
    "A cat walking in a garden under sunlight, 18-24 seconds",
    "A cat walking in a garden under sunlight, 24-30 seconds"
]
for i, prompt in enumerate(prompts):
    output = pipeline(prompt, num_frames=48, fps=8)
    video_path = output[OutputKeys.OUTPUT_VIDEO_PATH]
    os.rename(video_path, f"/app/output/video_{i}.mp4")
    print(f"Video saved to /app/output/video_{i}.mp4")

AttributeError: type object 'OutputKeys' has no attribute 'OUTPUT_VIDEO_PATH'

以及之前的错误日志(如 PyAV 缺失、attn_mask 形状问题、CUDA 相关问题),可以确认当前问题出在 modelscope.outputs.OutputKeys.OUTPUT_VIDEO_PATH 不存在,导致代码在以下行报错:

python

CollapseWrapRun

Copy

video_path = output[OutputKeys.OUTPUT_VIDEO_PATH]

这表明你使用的 modelscope 版本中,OutputKeys 类没有定义 OUTPUT_VIDEO_PATH 属性,可能是因为:

  • API 变化:modelscope 更新了输出键名。
  • 版本不兼容:当前版本不支持 OUTPUT_VIDEO_PATH。
  • 文档或代码错误:代码使用了错误的键名。

以下是问题的详细分析和解决步骤,基于你的代码和上下文。


问题分析

  1. 错误原因
    • OutputKeys 是一个枚举类,用于定义 modelscope 管道输出字典的键名。
    • OUTPUT_VIDEO_PATH 在你的 modelscope 版本中未定义,说明管道输出使用了不同的键名(如 video_path 或其他)。
    • 错误发生在后处理阶段,pipeline 已生成输出,但无法提取视频路径。
  2. 代码上下文

    python

    CollapseWrapRun

    Copy

    output = pipeline(prompt, num_frames=48, fps=8) video_path = output[OutputKeys.OUTPUT_VIDEO_PATH]

    • 你直接传递 prompt(字符串)到 pipeline,而之前的建议是使用 {"text": prompt}。虽然代码可能运行到输出阶段,但输入格式可能影响输出结构。
    • output 是一个字典,包含管道生成的视频路径,但键名与 OutputKeys.OUTPUT_VIDEO_PATH 不匹配。
  3. 之前的修复
    • 你已解决 PyAV 缺失问题(通过安装 av)。
    • attn_mask 形状问题((77, 77) vs (1, 1))已修复。
    • CUDA 问题(self.device 和 to(self.device))已通过设置为 cpu 解决。
    • torch.cuda.amp.autocast 警告可能仍存在,但不影响运行。
  4. 可能的根本原因
    • 键名变化:modelscope 的 text-to-video-synthesis 管道可能使用新的键名(如 video_path 或 output_video)。
    • 输入格式:直接传递 prompt 而非 {"text": prompt} 可能导致输出结构不一致。
    • 版本问题:modelscope 版本过旧或过新,导致 OutputKeys 属性不同。

解决方法

方法1:调试 pipeline 输出

打印 pipeline 的输出字典,确认实际键名。

  1. 修改 text-to-video.py: 在报错行前添加打印:

    python

    CollapseWrapRun

    Copy

    import subprocess import sys subprocess.check_call([sys.executable, "-m", "pip", "install", "datasets==2.16.1", "-i", "https://mirrors.aliyun.com/pypi/simple"]) import os from modelscope.pipelines import pipeline from modelscope.outputs import OutputKeys pipeline = pipeline("text-to-video-synthesis", "damo/text-to-video-synthesis", device="cpu") prompts = [ "A cat walking in a garden under sunlight, 0-6 seconds", "A cat walking in a garden under sunlight, 6-12 seconds", "A cat walking in a garden under sunlight, 12-18 seconds", "A cat walking in a garden under sunlight, 18-24 seconds", "A cat walking in a garden under sunlight, 24-30 seconds" ] for i, prompt in enumerate(prompts): output = pipeline(prompt, num_frames=48, fps=8) print(f"Pipeline output: {output}") # 添加调试打印 video_path = output[OutputKeys.OUTPUT_VIDEO_PATH] os.rename(video_path, f"/app/output/video_{i}.mp4") print(f"Video saved to /app/output/video_{i}.mp4")

  2. 运行脚本

    bash

    CollapseWrapRun

    Copy

    python text-to-video.py

  3. 检查输出
    • 查看 Pipeline output: {...},找到包含视频路径的键名(例如 video_path, output_video, 或 output_video_path)。
    • 示例输出可能为:

      text

      CollapseWrap

      Copy

      Pipeline output: {'video_path': '/tmp/video.mp4'}

  4. 更新代码: 根据打印结果,替换键名。例如,如果键名是 video_path:

    python

    CollapseWrapRun

    Copy

    video_path = output['video_path']

方法2:检查 OutputKeys 定义

查看 OutputKeys 的可用属性,找到正确的键名。

  1. 检查 OutputKeys: 运行:

    bash

    CollapseWrapRun

    Copy

    python -c "from modelscope.outputs import OutputKeys; print(dir(OutputKeys))"

  2. 查找替代键名
    • 寻找类似 VIDEO_PATH, OUTPUT_VIDEO, 或 OUTPUT_PATH 的属性。
    • 如果没有相关属性,依赖方法1的打印结果。
  3. 修改代码: 假设发现键名是 VIDEO_PATH,更新:

    python

    CollapseWrapRun

    Copy

    video_path = output[OutputKeys.VIDEO_PATH]

方法3:使用字符串键名绕过 OutputKeys

直接使用字符串键名,假设常见的键名。

  1. 修改 text-to-video.py: 替换:

    python

    CollapseWrapRun

    Copy

    video_path = output[OutputKeys.OUTPUT_VIDEO_PATH]

    为:

    python

    CollapseWrapRun

    Copy

    video_path = output['output_video_path'] # 尝试小写

  2. 尝试其他键名: 如果报错,依次尝试:

    python

    CollapseWrapRun

    Copy

    video_path = output['video_path'] video_path = output['output_video']

  3. 完整代码

    python

    CollapseWrapRun

    Copy

    import subprocess import sys subprocess.check_call([sys.executable, "-m", "pip", "install", "datasets==2.16.1", "-i", "https://mirrors.aliyun.com/pypi/simple"]) import os from modelscope.pipelines import pipeline from modelscope.outputs import OutputKeys pipeline = pipeline("text-to-video-synthesis", "damo/text-to-video-synthesis", device="cpu") prompts = [ "A cat walking in a garden under sunlight, 0-6 seconds", "A cat walking in a garden under sunlight, 6-12 seconds", "A cat walking in a garden under sunlight, 12-18 seconds", "A cat walking in a garden under sunlight, 18-24 seconds", "A cat walking in a garden under sunlight, 24-30 seconds" ] for i, prompt in enumerate(prompts): output = pipeline(prompt, num_frames=48, fps=8) video_path = output['output_video_path'] # 替换为假设键名 os.rename(video_path, f"/app/output/video_{i}.mp4") print(f"Video saved to /app/output/video_{i}.mp4")

  4. 运行脚本

    bash

    CollapseWrapRun

    Copy

    python text-to-video.py

方法4:修正输入格式

你的代码直接传递 prompt(字符串)到 pipeline,而 text-to-video-synthesis 管道可能期望字典输入 {"text": prompt}。这可能影响输出结构。

  1. 修改 text-to-video.py: 更新:

    python

    CollapseWrapRun

    Copy

    output = pipeline(prompt, num_frames=48, fps=8)

    为:

    python

    CollapseWrapRun

    Copy

    output = pipeline({"text": prompt}, num_frames=48, fps=8)

  2. 完整代码

    python

    CollapseWrapRun

    Copy

    import subprocess import sys subprocess.check_call([sys.executable, "-m", "pip", "install", "datasets==2.16.1", "-i", "https://mirrors.aliyun.com/pypi/simple"]) import os from modelscope.pipelines import pipeline from modelscope.outputs import OutputKeys pipeline = pipeline("text-to-video-synthesis", "damo/text-to-video-synthesis", device="cpu") prompts = [ "A cat walking in a garden under sunlight, 0-6 seconds", "A cat walking in a garden under sunlight, 6-12 seconds", "A cat walking in a garden under sunlight, 12-18 seconds", "A cat walking in a garden under sunlight, 18-24 seconds", "A cat walking in a garden under sunlight, 24-30 seconds" ] for i, prompt in enumerate(prompts): output = pipeline({"text": prompt}, num_frames=48, fps=8) print(f"Pipeline output: {output}") # 调试 video_path = output['output_video_path'] # 替换为假设键名 os.rename(video_path, f"/app/output/video_{i}.mp4") print(f"Video saved to /app/output/video_{i}.mp4")

  3. 运行脚本

    bash

    CollapseWrapRun

    Copy

    python text-to-video.py

方法5:更新 modelscope

尝试更新 modelscope 到最新版本,或安装支持 OUTPUT_VIDEO_PATH 的版本。

  1. 更新 modelscope

    bash

    CollapseWrapRun

    Copy

    pip install --upgrade modelscope -i https://mirrors.aliyun.com/pypi/simple --root-user-action=ignore

  2. 检查版本

    bash

    CollapseWrapRun

    Copy

    pip show modelscope

  3. 运行脚本

    bash

    CollapseWrapRun

    Copy

    python text-to-video.py

  4. 尝试特定版本: 如果最新版本无效,尝试较旧版本(如 1.7.0):

    bash

    CollapseWrapRun

    Copy

    pip install modelscope==1.7.0 -i https://mirrors.aliyun.com/pypi/simple --root-user-action=ignore

方法6:检查管道源码

查看 text_to_video_synthesis_pipeline.py 的 postprocess 方法,确认输出键名。

  1. 编辑文件

    bash

    CollapseWrapRun

    Copy

    nano /usr/local/lib/python3.8/dist-packages/modelscope/pipelines/multi_modal/text_to_video_synthesis_pipeline.py

  2. 定位 postprocess 方法: 找到第84行附近(torchvision.io.write_video 调用处),检查返回的字典。例如:

    python

    CollapseWrapRun

    Copy

    return {'video_path': video_path}

  3. 更新代码: 根据源码,替换 text-to-video.py 中的键名。

额外注意

  • 持久化更改: 将修改写入 Dockerfile:

    dockerfile

    CollapseWrap

    Copy

    RUN pip install av modelscope -i https://mirrors.aliyun.com/pypi/simple --root-user-action=ignore RUN sed -i 's/OutputKeys.OUTPUT_VIDEO_PATH/"output_video_path"/' /app/text-to-video.py RUN sed -i 's/pipeline(prompt/pipeline({"text": prompt}/' /app/text-to-video.py

    重新构建:

    bash

    CollapseWrapRun

    Copy

    docker build -t your_image_name .

  • 环境验证: 检查依赖:

    bash

    CollapseWrapRun

    Copy

    pip show modelscope torch torchvision av

  • 日志警告
    • 忽略 FutureWarning 和预处理器警告。
    • 如果仍有 torch.cuda.amp.autocast 警告,确认已修改:

      bash

      CollapseWrapRun

      Copy

      sed -i 's/with amp.autocast(enabled=True):/with torch.amp.autocast(device_type='"'"'cpu'"'"', enabled=True):/' /usr/local/lib/python3.8/dist-packages/modelscope/models/multi_modal/video_synthesis/text_to_video_synthesis_model.py


推荐步骤

  1. 优先:方法4(修正输入格式为 {"text": prompt})+ 方法1(打印 pipeline 输出)。
  2. 方法2(检查 OutputKeys)。
  3. 方法3(更新 modelscope)。
  4. 方法5(使用字符串键名)。

下一步

请提供:

  • 方法1的打印结果(Pipeline output: {output})。
  • python -c "from modelscope.outputs import OutputKeys; print(dir(OutputKeys))" 输出。
  • modelscope 版本:

    bash

    CollapseWrapRun

    Copy

    pip show modelscope

  • 最新错误日志(如果有)。 我可以进一步协助

你可能感兴趣的:(java,前端,javascript,python)