From d471cfa2763a0bbed49a75f175de87edbb1482c9 Mon Sep 17 00:00:00 2001 From: ViperEkura <3081035982@qq.com> Date: Tue, 19 May 2026 16:08:12 +0800 Subject: [PATCH] add hook.py: terminal demo + claim + logo reveal opening scene (~7s) --- AGENTS.md | 2 ++ hook.py | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++ render_all.py | 1 + 3 files changed, 100 insertions(+) create mode 100644 hook.py diff --git a/AGENTS.md b/AGENTS.md index 6739cc7..32ff63a 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -32,6 +32,7 @@ Output goes to `output/videos/`. Files are at the repo root, **not** under `promo/` despite what `README.md` and `PROMO_GUIDE.md` reference in some spots. ``` +hook.py # Scene: Hook architecture.py # Scene: Architecture continuous_batching.py # Scene: ContinuousBatching cta.py # Scene: CTA @@ -46,6 +47,7 @@ README.md # Quick-start docs (may reference stale promo/ paths) | File | Class | Content | Est. duration | |------|-------|---------|---------------| +| `hook.py` | `Hook` | Terminal demo + GPU comparison + logo reveal | ~18s | | `transformer.py` | `Transformer` | GQA attention (Q/K/V → RoPE → Attention → O) + spec card | ~35s | | `continuous_batching.py` | `ContinuousBatching` | 4-stage pipeline + throughput comparison (1.0x vs 3.4x) | ~30s | | `paged_cache.py` | `PrefixCache` | Paged KV cache: page table, on-demand growth, O(1) free | ~30s | diff --git a/hook.py b/hook.py new file mode 100644 index 0000000..4fce720 --- /dev/null +++ b/hook.py @@ -0,0 +1,97 @@ +"""AstrAI promo: Hook — terminal demo + GPU comparison + logo reveal (~8s).""" + +from manim import * + +Text.set_default(font="Times New Roman") + + +class Hook(Scene): + def construct(self): + BG = "#0d1117" + self.camera.background_color = BG + TERM = "#39ff14" + + # ════ 0. Terminal (0.0 – 2.8s) ════ + tw, th = 10.0, 4.8 + term_frame = Rectangle( + width=tw, height=th, color=WHITE, stroke_width=1.2, + fill_opacity=0.03, fill_color=TERM, + ) + term_frame.to_edge(UP, buff=0.2) + + lx = term_frame.get_left()[0] + 0.45 + ty = term_frame.get_top()[1] - 0.45 + + prompt = Text("$ ", font_size=20, color=TERM, font="Consolas") + prompt.move_to([lx, ty, 0], aligned_edge=LEFT) + + chat = Text("Hey, write a quicksort for me.", + font_size=18, color=WHITE, font="Consolas") + chat.next_to(prompt, RIGHT, buff=0.08).align_to(prompt, DOWN) + + resp = Text(">> ", font_size=18, color=GRAY, font="Consolas") + resp.next_to(prompt, DOWN, buff=0.55).align_to(prompt, LEFT) + + hint = Text("Here is the implementation:", + font_size=14, color=GRAY, font="Consolas") + hint.next_to(resp, DOWN, buff=0.20).align_to(prompt, LEFT) + + INDENT = 0.27 + code_lines = [ + ("def quicksort(arr):", 0), + ("if len(arr) <= 1:", 1), + ("return arr", 2), + ("pivot = arr[len(arr)//2]", 1), + ("left = [x for x in arr if x < pivot]", 1), + ("right = [x for x in arr if x >= pivot]", 1), + ("return quicksort(left) + [pivot] + quicksort(right)", 1), + ] + code_vg = VGroup() + prev = hint + for text, level in code_lines: + cl = Text(text, font_size=13, color=TERM, font="Consolas") + cl.next_to(prev, DOWN, buff=0.08).align_to(prompt, LEFT).shift(RIGHT * level * INDENT) + code_vg.add(cl) + prev = cl + + self.play(FadeIn(term_frame), run_time=0.3) + self.play(Write(prompt), run_time=0.1) + self.play(AddTextLetterByLetter(chat, time_per_char=0.018)) + self.play(Write(resp), run_time=0.12) + self.play(Write(hint, lag_ratio=1.0), run_time=0.15) + self.play(Write(code_vg, lag_ratio=1.0), run_time=1.2) + + self.play( + FadeOut(term_frame), FadeOut(prompt), FadeOut(chat), + FadeOut(resp), FadeOut(hint), FadeOut(code_vg), + run_time=0.3, + ) + + # ════ 1. Statement (2.8 – 4.0s) ════ + s1 = Text("LLMs Are Powerful", font_size=44, color=WHITE) + s2 = Text("but do they really need dozens of GPUs?", + font_size=28, color=GRAY) + VGroup(s1, s2).arrange(DOWN, buff=0.25).move_to(UP * 1.0) + self.play(Write(s1), run_time=0.35) + self.play(Write(s2), run_time=0.3) + self.wait(0.25) + self.play(FadeOut(s1), FadeOut(s2), run_time=0.25) + + # ════ 2. Logo (4.0 – 7.0s) ════ + logo = Text("AstrAI", font_size=80, color=BLUE) + glow = Text("AstrAI", font_size=80, color=BLUE_A, fill_opacity=0.3) + glow.move_to(logo).shift(UP * 0.015 + RIGHT * 0.015) + + info = VGroup( + Text("1B Params · Single GPU · Open Source", + font_size=22, color=GRAY), + Text("github.com/ViperEkura/AstrAI", font_size=17, color=YELLOW), + ).arrange(DOWN, buff=0.18) + everything = VGroup(VGroup(glow, logo), info).arrange(DOWN, buff=0.45) + everything.move_to(ORIGIN) + + self.play(Write(logo), run_time=0.45) + self.play(Write(glow), run_time=0.08) + self.play(Write(info), run_time=0.3) + self.wait(1.8) + self.play(FadeOut(everything), run_time=0.4) diff --git a/render_all.py b/render_all.py index 12ff269..7c50212 100644 --- a/render_all.py +++ b/render_all.py @@ -8,6 +8,7 @@ from pathlib import Path ROOT = Path(__file__).parent SCENES = [ + ("hook.py", "Hook"), ("transformer.py", "Transformer"), ("architecture.py", "Architecture"), ("continuous_batching.py", "ContinuousBatching"),