feat: 增加不同阶段的基础动画
This commit is contained in:
parent
65c89325fa
commit
09dc6688b0
|
|
@ -0,0 +1,5 @@
|
||||||
|
*
|
||||||
|
|
||||||
|
!.gitignore
|
||||||
|
!*.py
|
||||||
|
!*.md
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
"""
|
"""
|
||||||
AstrAI项目介绍视频 - 第一部分:开场白与项目定位
|
AstrAI项目介绍视频 - Part 1: 开场白与项目定位
|
||||||
"""
|
"""
|
||||||
from manim import *
|
from manim import *
|
||||||
|
|
||||||
|
|
@ -22,14 +22,12 @@ class Part1_Intro(Scene):
|
||||||
|
|
||||||
def play_logo_intro(self):
|
def play_logo_intro(self):
|
||||||
"""Logo动画展示"""
|
"""Logo动画展示"""
|
||||||
# 创建AstrAI Logo样式
|
|
||||||
logo_text = Text(
|
logo_text = Text(
|
||||||
"AstrAI",
|
"AstrAI",
|
||||||
font_size=72,
|
font_size=72,
|
||||||
font="SimHei",
|
font="SimHei",
|
||||||
)
|
)
|
||||||
|
|
||||||
# 创建副标题
|
|
||||||
subtitle = Text(
|
subtitle = Text(
|
||||||
"轻量级 Transformer 训练推理框架",
|
"轻量级 Transformer 训练推理框架",
|
||||||
font_size=28,
|
font_size=28,
|
||||||
|
|
@ -37,40 +35,33 @@ class Part1_Intro(Scene):
|
||||||
color=GRAY
|
color=GRAY
|
||||||
)
|
)
|
||||||
|
|
||||||
# 居中排列
|
|
||||||
logo_text.next_to(subtitle, UP, buff=0.3)
|
logo_text.next_to(subtitle, UP, buff=0.3)
|
||||||
subtitle.next_to(logo_text, DOWN, buff=0.3)
|
subtitle.next_to(logo_text, DOWN, buff=0.3)
|
||||||
|
|
||||||
# 初始状态
|
|
||||||
logo_text.set_opacity(0)
|
logo_text.set_opacity(0)
|
||||||
subtitle.set_opacity(0)
|
subtitle.set_opacity(0)
|
||||||
|
|
||||||
# 动画:淡入Logo
|
|
||||||
self.play(
|
self.play(
|
||||||
FadeIn(logo_text, shift=UP * 0.5, scale=1.2),
|
FadeIn(logo_text, shift=UP * 0.5, scale=1.2),
|
||||||
run_time=1.5
|
run_time=1.5
|
||||||
)
|
)
|
||||||
|
|
||||||
# 动画:淡入副标题
|
|
||||||
self.play(
|
self.play(
|
||||||
FadeIn(subtitle, shift=UP * 0.3),
|
FadeIn(subtitle, shift=UP * 0.3),
|
||||||
run_time=1.0
|
run_time=1.0
|
||||||
)
|
)
|
||||||
|
|
||||||
# 短暂停留
|
|
||||||
self.wait(0.8)
|
self.wait(0.8)
|
||||||
|
|
||||||
# 淡出
|
|
||||||
self.play(
|
self.play(
|
||||||
FadeOut(logo_text),
|
FadeOut(logo_text),
|
||||||
FadeOut(subtitle),
|
FadeOut(subtitle),
|
||||||
run_time=0.8
|
run_time=0.8
|
||||||
)
|
)
|
||||||
self.wait(0.5)
|
self.wait(0.3)
|
||||||
|
|
||||||
def play_opening_speech(self):
|
def play_opening_speech(self):
|
||||||
"""开场白"""
|
"""开场白"""
|
||||||
# 第一段文字
|
|
||||||
line1 = Text(
|
line1 = Text(
|
||||||
"在当下的大语言模型时代,",
|
"在当下的大语言模型时代,",
|
||||||
font_size=32,
|
font_size=32,
|
||||||
|
|
@ -79,9 +70,8 @@ class Part1_Intro(Scene):
|
||||||
line1.to_edge(UP, buff=1.0)
|
line1.to_edge(UP, buff=1.0)
|
||||||
|
|
||||||
self.play(Write(line1), run_time=1.0)
|
self.play(Write(line1), run_time=1.0)
|
||||||
self.wait(0.5)
|
self.wait(0.3)
|
||||||
|
|
||||||
# 第二段文字
|
|
||||||
line2 = Text(
|
line2 = Text(
|
||||||
"我们见证了GPT、LLaMA等庞然大物。",
|
"我们见证了GPT、LLaMA等庞然大物。",
|
||||||
font_size=32,
|
font_size=32,
|
||||||
|
|
@ -90,9 +80,8 @@ class Part1_Intro(Scene):
|
||||||
line2.next_to(line1, DOWN, buff=0.3)
|
line2.next_to(line1, DOWN, buff=0.3)
|
||||||
|
|
||||||
self.play(Write(line2), run_time=1.0)
|
self.play(Write(line2), run_time=1.0)
|
||||||
self.wait(0.5)
|
self.wait(0.3)
|
||||||
|
|
||||||
# 第三段文字
|
|
||||||
line3 = Text(
|
line3 = Text(
|
||||||
"然而,这些模型对硬件要求极高,",
|
"然而,这些模型对硬件要求极高,",
|
||||||
font_size=32,
|
font_size=32,
|
||||||
|
|
@ -101,9 +90,8 @@ class Part1_Intro(Scene):
|
||||||
line3.next_to(line2, DOWN, buff=0.3)
|
line3.next_to(line2, DOWN, buff=0.3)
|
||||||
|
|
||||||
self.play(Write(line3), run_time=1.0)
|
self.play(Write(line3), run_time=1.0)
|
||||||
self.wait(0.5)
|
self.wait(0.3)
|
||||||
|
|
||||||
# 第四段文字(关键问题)
|
|
||||||
line4 = Text(
|
line4 = Text(
|
||||||
"对于普通开发者来说往往遥不可及。",
|
"对于普通开发者来说往往遥不可及。",
|
||||||
font_size=32,
|
font_size=32,
|
||||||
|
|
@ -115,7 +103,6 @@ class Part1_Intro(Scene):
|
||||||
self.play(Write(line4), run_time=1.0)
|
self.play(Write(line4), run_time=1.0)
|
||||||
self.wait(0.8)
|
self.wait(0.8)
|
||||||
|
|
||||||
# 思考问题
|
|
||||||
question = Text(
|
question = Text(
|
||||||
"我们能否创建一个既有用又能运行在普通电脑上的模型?",
|
"我们能否创建一个既有用又能运行在普通电脑上的模型?",
|
||||||
font_size=28,
|
font_size=28,
|
||||||
|
|
@ -127,7 +114,6 @@ class Part1_Intro(Scene):
|
||||||
self.play(Write(question), run_time=1.5)
|
self.play(Write(question), run_time=1.5)
|
||||||
self.wait(1.0)
|
self.wait(1.0)
|
||||||
|
|
||||||
# 清除场景
|
|
||||||
self.play(
|
self.play(
|
||||||
FadeOut(line1),
|
FadeOut(line1),
|
||||||
FadeOut(line2),
|
FadeOut(line2),
|
||||||
|
|
@ -136,11 +122,10 @@ class Part1_Intro(Scene):
|
||||||
FadeOut(question),
|
FadeOut(question),
|
||||||
run_time=0.8
|
run_time=0.8
|
||||||
)
|
)
|
||||||
self.wait(0.5)
|
self.wait(0.3)
|
||||||
|
|
||||||
def play_key_points(self):
|
def play_key_points(self):
|
||||||
"""核心要点展示"""
|
"""核心要点展示"""
|
||||||
# 标题
|
|
||||||
title = Text(
|
title = Text(
|
||||||
"AstrAI 的核心特点",
|
"AstrAI 的核心特点",
|
||||||
font_size=40,
|
font_size=40,
|
||||||
|
|
@ -150,9 +135,8 @@ class Part1_Intro(Scene):
|
||||||
title.to_edge(UP, buff=0.8)
|
title.to_edge(UP, buff=0.8)
|
||||||
|
|
||||||
self.play(Write(title), run_time=1.0)
|
self.play(Write(title), run_time=1.0)
|
||||||
self.wait(0.5)
|
self.wait(0.3)
|
||||||
|
|
||||||
# 要点1:轻量级
|
|
||||||
point1_title = Text(
|
point1_title = Text(
|
||||||
"轻量级",
|
"轻量级",
|
||||||
font_size=36,
|
font_size=36,
|
||||||
|
|
@ -175,9 +159,8 @@ class Part1_Intro(Scene):
|
||||||
Write(point1_content),
|
Write(point1_content),
|
||||||
run_time=1.0
|
run_time=1.0
|
||||||
)
|
)
|
||||||
self.wait(0.8)
|
self.wait(0.5)
|
||||||
|
|
||||||
# 要点2:完全自研
|
|
||||||
point2_title = Text(
|
point2_title = Text(
|
||||||
"完全自研",
|
"完全自研",
|
||||||
font_size=36,
|
font_size=36,
|
||||||
|
|
@ -201,9 +184,8 @@ class Part1_Intro(Scene):
|
||||||
Write(point2_content),
|
Write(point2_content),
|
||||||
run_time=1.0
|
run_time=1.0
|
||||||
)
|
)
|
||||||
self.wait(0.8)
|
self.wait(0.5)
|
||||||
|
|
||||||
# 要点3:训练推理一体化
|
|
||||||
point3_title = Text(
|
point3_title = Text(
|
||||||
"训练推理一体化",
|
"训练推理一体化",
|
||||||
font_size=36,
|
font_size=36,
|
||||||
|
|
@ -229,7 +211,6 @@ class Part1_Intro(Scene):
|
||||||
)
|
)
|
||||||
self.wait(1.0)
|
self.wait(1.0)
|
||||||
|
|
||||||
# 清除场景(保留标题)
|
|
||||||
self.play(
|
self.play(
|
||||||
FadeOut(point1_title),
|
FadeOut(point1_title),
|
||||||
FadeOut(point1_content),
|
FadeOut(point1_content),
|
||||||
|
|
@ -243,7 +224,6 @@ class Part1_Intro(Scene):
|
||||||
|
|
||||||
def play_project_name(self):
|
def play_project_name(self):
|
||||||
"""项目名称与总结"""
|
"""项目名称与总结"""
|
||||||
# 项目名称 - 使用普通颜色避免兼容性问题
|
|
||||||
project_name = Text(
|
project_name = Text(
|
||||||
"AstrAI",
|
"AstrAI",
|
||||||
font_size=80,
|
font_size=80,
|
||||||
|
|
@ -252,14 +232,12 @@ class Part1_Intro(Scene):
|
||||||
)
|
)
|
||||||
project_name.center()
|
project_name.center()
|
||||||
|
|
||||||
# 动画:放大出现
|
|
||||||
self.play(
|
self.play(
|
||||||
project_name.animate.scale(1.2),
|
project_name.animate.scale(1.2),
|
||||||
run_time=1.5
|
run_time=1.5
|
||||||
)
|
)
|
||||||
self.wait(1.0)
|
self.wait(0.8)
|
||||||
|
|
||||||
# 补充说明
|
|
||||||
tagline = Text(
|
tagline = Text(
|
||||||
"1B参数 · 中英双语 · 完全自研 · 训练推理一体化",
|
"1B参数 · 中英双语 · 完全自研 · 训练推理一体化",
|
||||||
font_size=24,
|
font_size=24,
|
||||||
|
|
@ -271,35 +249,9 @@ class Part1_Intro(Scene):
|
||||||
self.play(Write(tagline), run_time=1.0)
|
self.play(Write(tagline), run_time=1.0)
|
||||||
self.wait(1.0)
|
self.wait(1.0)
|
||||||
|
|
||||||
# 淡出结束
|
|
||||||
self.play(
|
self.play(
|
||||||
FadeOut(project_name),
|
FadeOut(project_name),
|
||||||
FadeOut(tagline),
|
FadeOut(tagline),
|
||||||
run_time=1.0
|
run_time=1.0
|
||||||
)
|
)
|
||||||
self.wait(0.5)
|
self.wait(0.3)
|
||||||
|
|
||||||
|
|
||||||
# 配置类
|
|
||||||
class AstrAIVideoConfig:
|
|
||||||
"""视频配置"""
|
|
||||||
video_quality = "high_quality" # high_quality, production_quality
|
|
||||||
preview = True # 是否预览
|
|
||||||
save_last_frame = True # 保存最后一帧
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
# 运行配置
|
|
||||||
config = AstrAIVideoConfig()
|
|
||||||
|
|
||||||
# 渲染视频
|
|
||||||
if config.preview:
|
|
||||||
# 预览模式
|
|
||||||
from manim import *
|
|
||||||
scene = Part1_Intro()
|
|
||||||
scene.render()
|
|
||||||
else:
|
|
||||||
# 渲染视频文件
|
|
||||||
# manim -pql main.py Part1_Intro
|
|
||||||
# manim -pqh main.py Part1_Intro
|
|
||||||
pass
|
|
||||||
|
|
@ -0,0 +1,470 @@
|
||||||
|
"""
|
||||||
|
AstrAI项目介绍视频 - Part 2: AstrAI的核心设计
|
||||||
|
"""
|
||||||
|
from manim import *
|
||||||
|
|
||||||
|
|
||||||
|
class Part2_CoreDesign(Scene):
|
||||||
|
"""第二部分:AstrAI的核心设计"""
|
||||||
|
|
||||||
|
def construct(self):
|
||||||
|
# 2.1 整体架构
|
||||||
|
self.play_architecture()
|
||||||
|
|
||||||
|
# 2.2 推理流程
|
||||||
|
self.play_inference_flow()
|
||||||
|
|
||||||
|
# 2.3 调度策略
|
||||||
|
self.play_scheduler()
|
||||||
|
|
||||||
|
# 2.4 内存优化
|
||||||
|
self.play_memory_optimization()
|
||||||
|
|
||||||
|
# 2.5 分布式支持
|
||||||
|
self.play_distributed_support()
|
||||||
|
|
||||||
|
def play_architecture(self):
|
||||||
|
"""整体架构展示"""
|
||||||
|
# 标题
|
||||||
|
title = Text(
|
||||||
|
"AstrAI 核心设计",
|
||||||
|
font_size=48,
|
||||||
|
font="SimHei",
|
||||||
|
color=WHITE
|
||||||
|
)
|
||||||
|
title.to_edge(UP, buff=0.8)
|
||||||
|
|
||||||
|
self.play(Write(title), run_time=1.0)
|
||||||
|
self.wait(0.5)
|
||||||
|
|
||||||
|
# 模块表格
|
||||||
|
modules = [
|
||||||
|
("astrai.config", "配置管理"),
|
||||||
|
("astrai.dataset", "数据集加载"),
|
||||||
|
("astrai.model", "神经网络模型"),
|
||||||
|
("astrai.tokenize", "分词器和聊天模板"),
|
||||||
|
("astrai.trainer", "训练工作流管理"),
|
||||||
|
("astrai.inference", "推理调度"),
|
||||||
|
("astrai.parallel", "分布式并行支持"),
|
||||||
|
]
|
||||||
|
|
||||||
|
# 创建模块列表
|
||||||
|
module_objects = []
|
||||||
|
for i, (module, desc) in enumerate(modules):
|
||||||
|
module_text = Text(
|
||||||
|
module,
|
||||||
|
font_size=28,
|
||||||
|
font="SimHei",
|
||||||
|
color=BLUE
|
||||||
|
)
|
||||||
|
desc_text = Text(
|
||||||
|
desc,
|
||||||
|
font_size=20,
|
||||||
|
font="SimHei",
|
||||||
|
color=GRAY
|
||||||
|
)
|
||||||
|
module_text.shift(LEFT * 3)
|
||||||
|
desc_text.next_to(module_text, RIGHT, buff=0.5)
|
||||||
|
|
||||||
|
if i == 0:
|
||||||
|
module_text.to_edge(UP, buff=2.5)
|
||||||
|
else:
|
||||||
|
module_text.next_to(module_objects[-1][0], DOWN, buff=0.4)
|
||||||
|
desc_text.next_to(module_text, RIGHT, buff=0.5)
|
||||||
|
|
||||||
|
self.play(Write(module_text), run_time=0.5)
|
||||||
|
self.play(Write(desc_text), run_time=0.3)
|
||||||
|
module_objects.append((module_text, desc_text))
|
||||||
|
|
||||||
|
if i < len(modules) - 1:
|
||||||
|
self.wait(0.2)
|
||||||
|
|
||||||
|
self.wait(2.0)
|
||||||
|
|
||||||
|
# 淡出
|
||||||
|
self.play(
|
||||||
|
FadeOut(title),
|
||||||
|
*[FadeOut(m) for m, d in module_objects],
|
||||||
|
*[FadeOut(d) for m, d in module_objects],
|
||||||
|
run_time=0.8
|
||||||
|
)
|
||||||
|
self.wait(0.3)
|
||||||
|
|
||||||
|
def play_inference_flow(self):
|
||||||
|
"""推理流程:Prefill → Decode"""
|
||||||
|
title = Text(
|
||||||
|
"推理流程:Prefill → Decode",
|
||||||
|
font_size=40,
|
||||||
|
font="SimHei",
|
||||||
|
color=WHITE
|
||||||
|
)
|
||||||
|
title.to_edge(UP, buff=0.8)
|
||||||
|
|
||||||
|
self.play(Write(title), run_time=1.0)
|
||||||
|
self.wait(0.3)
|
||||||
|
|
||||||
|
# Pre-fill阶段
|
||||||
|
prefill_box = RoundedRectangle(
|
||||||
|
width=3.5,
|
||||||
|
height=1.5,
|
||||||
|
corner_radius=0.2,
|
||||||
|
color=BLUE,
|
||||||
|
fill_opacity=0.3
|
||||||
|
)
|
||||||
|
prefill_box.to_edge(LEFT, buff=2.0)
|
||||||
|
|
||||||
|
prefill_title = Text(
|
||||||
|
"Pre-fill",
|
||||||
|
font_size=28,
|
||||||
|
font="SimHei",
|
||||||
|
color=BLUE
|
||||||
|
)
|
||||||
|
prefill_title.next_to(prefill_box, UP, buff=0.2)
|
||||||
|
|
||||||
|
prefill_desc = Text(
|
||||||
|
"一次性处理输入序列\n计算所有Token的K和V",
|
||||||
|
font_size=16,
|
||||||
|
font="SimHei",
|
||||||
|
color=GRAY
|
||||||
|
)
|
||||||
|
prefill_desc.move_to(prefill_box)
|
||||||
|
|
||||||
|
self.play(
|
||||||
|
Create(prefill_box),
|
||||||
|
Write(prefill_title),
|
||||||
|
Write(prefill_desc),
|
||||||
|
run_time=1.0
|
||||||
|
)
|
||||||
|
self.wait(0.5)
|
||||||
|
|
||||||
|
# Decode阶段
|
||||||
|
decode_box = RoundedRectangle(
|
||||||
|
width=3.5,
|
||||||
|
height=1.5,
|
||||||
|
corner_radius=0.2,
|
||||||
|
color=GREEN,
|
||||||
|
fill_opacity=0.3
|
||||||
|
)
|
||||||
|
decode_box.to_edge(RIGHT, buff=2.0)
|
||||||
|
|
||||||
|
decode_title = Text(
|
||||||
|
"Decode",
|
||||||
|
font_size=28,
|
||||||
|
font="SimHei",
|
||||||
|
color=GREEN
|
||||||
|
)
|
||||||
|
decode_title.next_to(decode_box, UP, buff=0.2)
|
||||||
|
|
||||||
|
decode_desc = Text(
|
||||||
|
"生成新Token\n从KV Cache读取K和V",
|
||||||
|
font_size=16,
|
||||||
|
font="SimHei",
|
||||||
|
color=GRAY
|
||||||
|
)
|
||||||
|
decode_desc.move_to(decode_box)
|
||||||
|
|
||||||
|
self.play(
|
||||||
|
Create(decode_box),
|
||||||
|
Write(decode_title),
|
||||||
|
Write(decode_desc),
|
||||||
|
run_time=1.0
|
||||||
|
)
|
||||||
|
self.wait(0.5)
|
||||||
|
|
||||||
|
# 箭头
|
||||||
|
arrow = Arrow(
|
||||||
|
prefill_box.get_right(),
|
||||||
|
decode_box.get_left(),
|
||||||
|
buff=0.5,
|
||||||
|
color=YELLOW
|
||||||
|
)
|
||||||
|
self.play(Create(arrow), run_time=0.5)
|
||||||
|
self.wait(1.5)
|
||||||
|
|
||||||
|
# 关键点说明
|
||||||
|
key_point = Text(
|
||||||
|
"KV Cache:避免重复计算,大幅提升效率",
|
||||||
|
font_size=24,
|
||||||
|
font="SimHei",
|
||||||
|
color=YELLOW
|
||||||
|
)
|
||||||
|
key_point.to_edge(DOWN, buff=1.5)
|
||||||
|
|
||||||
|
self.play(Write(key_point), run_time=1.0)
|
||||||
|
self.wait(2.0)
|
||||||
|
|
||||||
|
# 淡出
|
||||||
|
self.play(
|
||||||
|
FadeOut(title),
|
||||||
|
FadeOut(prefill_box),
|
||||||
|
FadeOut(prefill_title),
|
||||||
|
FadeOut(prefill_desc),
|
||||||
|
FadeOut(decode_box),
|
||||||
|
FadeOut(decode_title),
|
||||||
|
FadeOut(decode_desc),
|
||||||
|
FadeOut(arrow),
|
||||||
|
FadeOut(key_point),
|
||||||
|
run_time=0.8
|
||||||
|
)
|
||||||
|
self.wait(0.3)
|
||||||
|
|
||||||
|
def play_scheduler(self):
|
||||||
|
"""调度策略"""
|
||||||
|
title = Text(
|
||||||
|
"调度策略:高效管理KV Cache",
|
||||||
|
font_size=40,
|
||||||
|
font="SimHei",
|
||||||
|
color=WHITE
|
||||||
|
)
|
||||||
|
title.to_edge(UP, buff=0.8)
|
||||||
|
|
||||||
|
self.play(Write(title), run_time=1.0)
|
||||||
|
self.wait(0.3)
|
||||||
|
|
||||||
|
# 连续批处理说明
|
||||||
|
batch_title = Text(
|
||||||
|
"连续批处理 (Continuous Batching)",
|
||||||
|
font_size=32,
|
||||||
|
font="SimHei",
|
||||||
|
color=BLUE
|
||||||
|
)
|
||||||
|
batch_title.to_edge(LEFT, buff=1.5).shift(UP * 1.5)
|
||||||
|
|
||||||
|
self.play(Write(batch_title), run_time=1.0)
|
||||||
|
self.wait(0.3)
|
||||||
|
|
||||||
|
features = [
|
||||||
|
"动态批处理:新的请求可以随时加入",
|
||||||
|
"立即释放:完成的任务立即释放资源",
|
||||||
|
"大幅提高GPU利用率",
|
||||||
|
]
|
||||||
|
|
||||||
|
feature_texts = []
|
||||||
|
for i, feature in enumerate(features):
|
||||||
|
feature_text = Text(
|
||||||
|
feature,
|
||||||
|
font_size=22,
|
||||||
|
font="SimHei",
|
||||||
|
color=GRAY
|
||||||
|
)
|
||||||
|
feature_text.next_to(batch_title, DOWN, buff=0.4 + i * 0.5)
|
||||||
|
feature_text.align_to(batch_title, LEFT)
|
||||||
|
|
||||||
|
self.play(Write(feature_text), run_time=0.8)
|
||||||
|
self.wait(0.3)
|
||||||
|
feature_texts.append(feature_text)
|
||||||
|
|
||||||
|
self.wait(1.0)
|
||||||
|
|
||||||
|
# 前缀缓存
|
||||||
|
prefix_title = Text(
|
||||||
|
"前缀缓存 (Prefix Caching)",
|
||||||
|
font_size=32,
|
||||||
|
font="SimHei",
|
||||||
|
color=GREEN
|
||||||
|
)
|
||||||
|
prefix_title.to_edge(RIGHT, buff=1.5).shift(UP * 1.5)
|
||||||
|
|
||||||
|
self.play(Write(prefix_title), run_time=1.0)
|
||||||
|
self.wait(0.3)
|
||||||
|
|
||||||
|
prefix_desc = Text(
|
||||||
|
"使用Radix Tree实现\n智能前缀提示加速",
|
||||||
|
font_size=20,
|
||||||
|
font="SimHei",
|
||||||
|
color=GRAY
|
||||||
|
)
|
||||||
|
prefix_desc.next_to(prefix_title, DOWN, buff=0.4)
|
||||||
|
prefix_desc.align_to(prefix_title, LEFT)
|
||||||
|
|
||||||
|
self.play(Write(prefix_desc), run_time=0.8)
|
||||||
|
self.wait(2.0)
|
||||||
|
|
||||||
|
# 淡出 - 简化版本
|
||||||
|
self.play(
|
||||||
|
FadeOut(title),
|
||||||
|
FadeOut(batch_title),
|
||||||
|
FadeOut(prefix_title),
|
||||||
|
FadeOut(prefix_desc),
|
||||||
|
run_time=0.8
|
||||||
|
)
|
||||||
|
|
||||||
|
for ft in feature_texts:
|
||||||
|
self.play(FadeOut(ft), run_time=0.3)
|
||||||
|
|
||||||
|
self.wait(0.3)
|
||||||
|
|
||||||
|
def play_memory_optimization(self):
|
||||||
|
"""内存优化"""
|
||||||
|
title = Text(
|
||||||
|
"内存优化:Radix Tree vs PagedAttention",
|
||||||
|
font_size=40,
|
||||||
|
font="SimHei",
|
||||||
|
color=WHITE
|
||||||
|
)
|
||||||
|
title.to_edge(UP, buff=0.8)
|
||||||
|
|
||||||
|
self.play(Write(title), run_time=1.0)
|
||||||
|
self.wait(0.3)
|
||||||
|
|
||||||
|
# Radix Tree 优势
|
||||||
|
radix_title = Text(
|
||||||
|
"Radix Tree 优势",
|
||||||
|
font_size=28,
|
||||||
|
font="SimHei",
|
||||||
|
color=BLUE
|
||||||
|
)
|
||||||
|
radix_title.to_edge(LEFT, buff=2.0).shift(UP * 1.0)
|
||||||
|
|
||||||
|
self.play(Write(radix_title), run_time=1.0)
|
||||||
|
|
||||||
|
radix_features = [
|
||||||
|
"自动合并共享前缀的请求",
|
||||||
|
"智能复用已计算的KV Cache",
|
||||||
|
"支持前缀提示加速",
|
||||||
|
"基于LRU的缓存淘汰策略",
|
||||||
|
]
|
||||||
|
|
||||||
|
radix_texts = []
|
||||||
|
for i, feature in enumerate(radix_features):
|
||||||
|
feature_text = Text(
|
||||||
|
f"• {feature}",
|
||||||
|
font_size=20,
|
||||||
|
font="SimHei",
|
||||||
|
color=GRAY
|
||||||
|
)
|
||||||
|
feature_text.next_to(radix_title, DOWN, buff=0.3 + i * 0.4)
|
||||||
|
feature_text.align_to(radix_title, LEFT)
|
||||||
|
|
||||||
|
self.play(Write(feature_text), run_time=0.5)
|
||||||
|
radix_texts.append(feature_text)
|
||||||
|
|
||||||
|
self.wait(1.0)
|
||||||
|
|
||||||
|
# 对比vLLM
|
||||||
|
compare_title = Text(
|
||||||
|
"对比 vLLM",
|
||||||
|
font_size=28,
|
||||||
|
font="SimHei",
|
||||||
|
color=GREEN
|
||||||
|
)
|
||||||
|
compare_title.to_edge(RIGHT, buff=2.0).shift(UP * 1.0)
|
||||||
|
|
||||||
|
self.play(Write(compare_title), run_time=1.0)
|
||||||
|
|
||||||
|
compare_text = Text(
|
||||||
|
"vLLM使用PagedAttention\nAstrAI使用Radix Tree\n\n两者都能减少内存碎片\n实现方式不同",
|
||||||
|
font_size=18,
|
||||||
|
font="SimHei",
|
||||||
|
color=GRAY
|
||||||
|
)
|
||||||
|
compare_text.next_to(compare_title, DOWN, buff=0.3)
|
||||||
|
compare_text.align_to(compare_title, LEFT)
|
||||||
|
|
||||||
|
self.play(Write(compare_text), run_time=1.0)
|
||||||
|
self.wait(2.0)
|
||||||
|
|
||||||
|
# 淡出
|
||||||
|
self.play(
|
||||||
|
FadeOut(title),
|
||||||
|
FadeOut(radix_title),
|
||||||
|
FadeOut(compare_title),
|
||||||
|
FadeOut(compare_text),
|
||||||
|
run_time=0.8
|
||||||
|
)
|
||||||
|
|
||||||
|
for rt in radix_texts:
|
||||||
|
self.play(FadeOut(rt), run_time=0.3)
|
||||||
|
|
||||||
|
self.wait(0.3)
|
||||||
|
|
||||||
|
def play_distributed_support(self):
|
||||||
|
"""分布式支持"""
|
||||||
|
title = Text(
|
||||||
|
"分布式支持:多卡推理",
|
||||||
|
font_size=40,
|
||||||
|
font="SimHei",
|
||||||
|
color=WHITE
|
||||||
|
)
|
||||||
|
title.to_edge(UP, buff=0.8)
|
||||||
|
|
||||||
|
self.play(Write(title), run_time=1.0)
|
||||||
|
self.wait(0.3)
|
||||||
|
|
||||||
|
# 并行方式
|
||||||
|
parallel_title = Text(
|
||||||
|
"支持的并行方式",
|
||||||
|
font_size=32,
|
||||||
|
font="SimHei",
|
||||||
|
color=BLUE
|
||||||
|
)
|
||||||
|
parallel_title.to_edge(LEFT, buff=1.5).shift(UP * 1.5)
|
||||||
|
|
||||||
|
self.play(Write(parallel_title), run_time=1.0)
|
||||||
|
|
||||||
|
parallel_methods = [
|
||||||
|
("数据并行", "多卡处理不同数据"),
|
||||||
|
("模型并行", "将模型分片到不同卡"),
|
||||||
|
("流水并行", "按层划分Pipeline"),
|
||||||
|
]
|
||||||
|
|
||||||
|
method_texts = []
|
||||||
|
for i, (method, desc) in enumerate(parallel_methods):
|
||||||
|
method_text = Text(
|
||||||
|
method,
|
||||||
|
font_size=24,
|
||||||
|
font="SimHei",
|
||||||
|
color=GREEN
|
||||||
|
)
|
||||||
|
method_text.next_to(parallel_title, DOWN, buff=0.4 + i * 0.5)
|
||||||
|
method_text.align_to(parallel_title, LEFT)
|
||||||
|
|
||||||
|
desc_text = Text(
|
||||||
|
f" - {desc}",
|
||||||
|
font_size=18,
|
||||||
|
font="SimHei",
|
||||||
|
color=GRAY
|
||||||
|
)
|
||||||
|
desc_text.next_to(method_text, RIGHT, buff=0.3)
|
||||||
|
|
||||||
|
self.play(Write(method_text), Write(desc_text), run_time=0.8)
|
||||||
|
method_texts.append((method_text, desc_text))
|
||||||
|
|
||||||
|
self.wait(1.5)
|
||||||
|
|
||||||
|
# 代码示例
|
||||||
|
code_title = Text(
|
||||||
|
"分布式初始化",
|
||||||
|
font_size=28,
|
||||||
|
font="SimHei",
|
||||||
|
color=ORANGE
|
||||||
|
)
|
||||||
|
code_title.to_edge(RIGHT, buff=1.5).shift(UP * 1.5)
|
||||||
|
|
||||||
|
self.play(Write(code_title), run_time=1.0)
|
||||||
|
|
||||||
|
code_text = Text(
|
||||||
|
"setup_parallel()\nspawn_parallel_fn()\n\n支持NCCL后端",
|
||||||
|
font_size=16,
|
||||||
|
font="SimHei",
|
||||||
|
color=GRAY
|
||||||
|
)
|
||||||
|
code_text.next_to(code_title, DOWN, buff=0.3)
|
||||||
|
code_text.align_to(code_title, LEFT)
|
||||||
|
|
||||||
|
self.play(Write(code_text), run_time=1.0)
|
||||||
|
self.wait(2.0)
|
||||||
|
|
||||||
|
# 淡出
|
||||||
|
self.play(
|
||||||
|
FadeOut(title),
|
||||||
|
FadeOut(parallel_title),
|
||||||
|
FadeOut(code_title),
|
||||||
|
FadeOut(code_text),
|
||||||
|
run_time=0.8
|
||||||
|
)
|
||||||
|
|
||||||
|
for mt, dt in method_texts:
|
||||||
|
self.play(FadeOut(mt), FadeOut(dt), run_time=0.3)
|
||||||
|
|
||||||
|
self.wait(0.5)
|
||||||
Loading…
Reference in New Issue