使用 modal 运行 manim 代码
一 CPU 版本
manim_a_plus_b.py
from manim import *
class BinomialSquare(Scene):
def construct(self):
# Define constants
a = 2
b = 1
square_side = a + b
# Create the main square
main_square = Square(side_length=square_side).set_color(BLUE)
# Add labels (a+b) on sides
label_a_top = Text("a", font_size=24).next_to(main_square, UP).shift(LEFT * b / 2)
label_b_top = Text("b", font_size=24).next_to(main_square, UP).shift(RIGHT * a / 2)
label_a_left = Text("a", font_size=24).next_to(main_square, LEFT).shift(UP * b / 2)
label_b_left = Text("b", font_size=24).next_to(main_square, LEFT).shift(DOWN * a / 2)
# Create dividing lines
v_line = Line(main_square.get_corner(UP) + DOWN * a,
main_square.get_corner(DOWN) + UP * b)
h_line = Line(main_square.get_corner(LEFT) + RIGHT * a,
main_square.get_corner(RIGHT) + LEFT * b)
# Create smaller squares and rectangles
a_square = Square(side_length=a).set_color(RED).move_to(main_square.get_corner(UP + LEFT))
b_square = Square(side_length=b).set_color(YELLOW).move_to(main_square.get_corner(DOWN + RIGHT))
ab_rect1 = Rectangle(width=a, height=b).set_color(GREEN).next_to(a_square, RIGHT)
ab_rect2 = Rectangle(width=b, height=a).set_color(GREEN).next_to(a_square, DOWN)
# Animation sequence
self.play(Create(main_square))
self.play(Write(label_a_top), Write(label_b_top),
Write(label_a_left), Write(label_b_left))
self.play(Create(v_line), Create(h_line))
self.play(FadeIn(a_square), FadeIn(b_square),
FadeIn(ab_rect1), FadeIn(ab_rect2))
# Formula text
formula = MathTex(r"(a+b)^2 = a^2 + 2ab + b^2").to_edge(DOWN)
self.play(Write(formula))
self.wait(2)
if __name__ == "__main__":
# Basic configuration
config.pixel_height = 1080 # Set resolution height
config.pixel_width = 1920 # Set resolution width
config.frame_rate = 30 # Set frame rate
config.output_file = "CombinedScene" # Specify output filename
config.disable_caching = True # Disable caching
# Set output directory using placeholder for Java replacement
config.media_dir = "#(output_path)" # IMPORTANT: Use the placeholder
# Create and render the scene
sence = BinomialSquare()
sence.render()
print(f"Scene rendering finished. Output in: {config.media_dir}")
modal_run_with_manim.py
import modal
# 构建镜像:
# - apt_install 安装 TeX Live、FFmpeg、pkg-config、cairo 开发包以及 pango 开发包
# - pip_install 安装 Python 包(numpy、manim、manimpango、latex、moviepy、requests)
# - add_local_dir 将本地 "scripts" 目录挂载到容器的 /scripts 目录
image = (
modal.Image.debian_slim()
.apt_install("texlive-full", "ffmpeg", "pkg-config", "libcairo2-dev", "libpango1.0-dev")
.pip_install("numpy", "manim", "manimpango", "latex", "moviepy", "requests")
.add_local_dir("scripts", "/scripts")
)
app = modal.App("example-run-local-script", image=image)
@app.function()
def run_script():
with open("/scripts/manim_a_plus_b.py", "r", encoding="utf-8") as f:
script_content = f.read()
print(script_content)
exec(script_content, {'__name__': '__main__'})
print("exec finished")
二 GPU 版本
import subprocess
import modal
image = (
modal.Image.from_registry("nvidia/cuda:12.2.0-devel-ubuntu22.04", add_python="3.10")
.env({"DEBIAN_FRONTEND": "noninteractive", "TZ": "Asia/Shanghai"})
.apt_install("tzdata")
.run_commands("ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo 'Asia/Shanghai' > /etc/timezone")
.apt_install("build-essential", "ffmpeg", "ghostscript", "dvisvgm", "texlive-full")
.apt_install("python3-dev", "pkg-config")
.apt_install("libcairo2-dev", "libpango1.0-dev", "clang")
.run_commands("pip install --upgrade pip setuptools wheel")
.pip_install("numpy", "manim", "latex", "moviepy", "requests")
.pip_install("manimpango")
.add_local_dir("scripts", "/scripts")
)
app = modal.App("example-run-local-script", image=image)
@app.function(gpu="A10G")
def run_script():
result = subprocess.run("ffmpeg -encoders | grep nven", shell=True, capture_output=True, text=True)
print(result.stdout)
with open("/scripts/manim_a_plus_b.py", "r", encoding="utf-8") as f:
script_content = f.read()
print(script_content)
exec(script_content, {'__name__': '__main__'})
print("exec finished")
四、下载文件
五、常见问题:
Q:GPU 型号如何选择?
- T4:性价比最高,适合常规视频动画加速。
- A100 或 V100:更高性能,价格较贵,适合特别复杂的场景。
Q:如何调整分辨率?
修改 Manim 的-ql
(480p)、-qm
(720p)、-qh
(1080p)参数即可。
例如 1080p:
manim -qh --renderer=opengl scene.py CombinedScene
六、费用及效率
- 费用:按秒计费,用完即停,非常节省。
- 效率:GPU 渲染通常比本地 CPU 快数倍至数十倍,取决于复杂度。
总结:
整合 Modal GPU 的方案能够快速有效地提高 Manim 渲染效率,是目前最直接、可靠且性价比高的 GPU 渲染方案之一,建议你直接尝试。