diff --git a/.gitignore b/.gitignore index 8eb56bc..1b0d11b 100644 --- a/.gitignore +++ b/.gitignore @@ -4,7 +4,9 @@ # Recurse into directories !*/ + # Whitelist: only source code and docs !*.py -!*.md +!README.md +!AGENTS.md !.gitignore diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..6739cc7 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,74 @@ +# AGENTS.md — AstrAI Promo + +## Project + +Manim-driven technical animation project for AstrAI promo videos (1B param, zh/en bilingual LLM). +Python 3.12, Manim (renders MP4 output). + +## Setup + +Requires a conda environment named `manim`. + +```bash +conda run -n manim python -m pip install manim +``` + +The user verbally referred to it as "animin" — the actual name is `manim`. No system Python is available; always use `conda run -n manim`. + +## Commands + +| Action | Command | +|--------|---------| +| Render all (parallel) | `conda run -n manim python render_all.py` | +| Render all (draft 480p) | `conda run -n manim python render_all.py -ql` | +| Render all (4K) | `conda run -n manim python render_all.py -4k` | +| Single scene (1080p) | `conda run -n manim python -m manim -qh` | +| Single scene (draft) | `conda run -n manim python -m manim -ql` | + +Output goes to `output/videos/`. + +## File layout (flat — no subdirectory) + +Files are at the repo root, **not** under `promo/` despite what `README.md` and `PROMO_GUIDE.md` reference in some spots. + +``` +architecture.py # Scene: Architecture +continuous_batching.py # Scene: ContinuousBatching +cta.py # Scene: CTA +paged_cache.py # Scene: PrefixCache +transformer.py # Scene: Transformer +render_all.py # Parallel batch renderer +PROMO_GUIDE.md # Full production guide (storyboard, narration, recording) +README.md # Quick-start docs (may reference stale promo/ paths) +``` + +## Scenes + +| File | Class | Content | Est. duration | +|------|-------|---------|---------------| +| `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 | +| `architecture.py` | `Architecture` | Full-stack: HTTP API → Engine → Paged Cache → Transformer | ~25s | +| `cta.py` | `CTA` | End card: "AstrAI — Single GPU, Open Source, 1B params" | ~3s | + +## Render quirks + +- `render_all.py` runs all 5 scenes **in parallel** via `ThreadPoolExecutor`. Script blocks until all finish. No `-qh` flag in render_all.py means check the default at the top of the file. +- The `output/` directory must exist (script creates it via Manim's `--media_dir`). + +## Chinese text in Manim + +```python +Text.set_default(font="Microsoft YaHei") +``` +This must be set before creating any `Text` objects, otherwise CJK characters render as boxes. + +## No tests / lint / typecheck + +This is a render-only project. No pytest, ruff, mypy, or similar config exists. + +## .gitignore oddity (from parent AstrAI project) + +The repo uses deny-by-default `.gitignore` (`*` then `!*.py`, `!*.sh`, etc.). +New file types at root need an explicit `!` entry — check `.gitignore` before adding assets. diff --git a/PROMO_GUIDE.md b/PROMO_GUIDE.md deleted file mode 100644 index 8f49745..0000000 --- a/PROMO_GUIDE.md +++ /dev/null @@ -1,373 +0,0 @@ -# AstrAI 宣传视频制作指南 - -> 本文档为制作 AstrAI 宣传视频提供完整的技术参考、分镜建议和录制脚本。 -> 目标时长:**2-3 分钟** - ---- - -## 目录 - -1. [项目定位与核心卖点](#1-项目定位与核心卖点) -2. [技术架构速览](#2-技术架构速览) -3. [分镜脚本](#3-分镜脚本) -4. [演示录制指南](#4-演示录制指南) -5. [动画场景说明](#5-动画场景说明) -6. [旁白文案草稿](#6-旁白文案草稿) -7. [素材清单](#7-素材清单) - ---- - -## 1. 项目定位与核心卖点 - -**一句话定位:** -> 一个能在单张消费级 GPU 上训练和推理的 1B 参数中英双语语言模型框架。 - -**核心卖点(视频中需突出):** - -| 卖点 | 说明 | 视觉表达 | -|------|------|---------| -| **单卡可跑** | 1B 参数,RTX 3090/4090 即可运行 | 巨大服务器集群 vs 单张显卡对比 | -| **连续批处理** | 动态合并请求,吞吐量 3x+ | 任务流经 Cleanup→Refill→Prefill→Decode 动画 | -| **分页 KV 缓存** | 固定大小页表 + O(1) 分配,按需扩容 | 页表分配与写入动画 | -| **OpenAI 兼容 API** | 一行代码切换 | curl 命令对比 | -| **流式输出** | 逐 token 返回,低首延迟 | 终端逐字喷出效果 | -| **全过程开源** | 训练+推理+权重全部开源 | GitHub 页面展示 | - ---- - -## 2. 技术架构速览 - -### 整体架构 - -``` -┌──────────────────────────────────────────────────┐ -│ FastAPI Server (OpenAI-Compatible API) │ -├──────────────────────────────────────────────────┤ -│ InferenceEngine (Streaming + Async + Batch) │ -├──────────────────────────────────────────────────┤ -│ Continuous Batching Scheduler │ -│ ┌────────┐ ┌──────┐ ┌────────┐ ┌────────┐ │ -│ │Cleanup │→ │Refill│→ │Prefill │→ │ Decode │ │ -│ └────────┘ └──────┘ └────────┘ └────────┘ │ -├──────────────────────────────────────────────────┤ -│ Paged KV Cache (Page Table + Page Pool) │ -├──────────────────────────────────────────────────┤ -│ Transformer (24层 GQA, RoPE, SwiGLU) │ -└──────────────────────────────────────────────────┘ -``` - -### 关键技术指标 - -| 指标 | 值 | -|------|------| -| 参数量 | ~1.0B | -| 词表大小 | 100,000(中英 BPE) | -| 层数 | 24 | -| 注意力头 | 24 Q-heads / 4 KV-heads(GQA) | -| 最大长度 | 2048 tokens | -| 精度 | bfloat16 | -| 最低显存 | ~6GB(推理)/~12GB(训练) | - ---- - -## 3. 分镜脚本 - -总时长 **2:30**,分为 6 个段落。 - -### Segment 1:Hook + 问题陈述(0:00 - 0:20) - -| 镜头 | 画面 | 旁白 | 时长 | -|------|------|------|------| -| 1.1 | 黑屏,逐字打出"大语言模型很强大" | "大语言模型很强大——" | 3s | -| 1.2 | 切到数据中心照片 / 巨大 GPU 集群 | "——但跑起来需要几十张 GPU,普通人根本碰不到。" | 5s | -| 1.3 | 画面分屏:左边集群,右边一张 RTX 4090 | "但如果我告诉你,只要一张显卡就够了呢?" | 5s | -| 1.4 | Logo 出现:**AstrAI**,下方副标题 "1B 参数单卡推理框架" | "AstrAI——单卡跑大模型。" | 7s | - -**视觉素材**:数据中心图片(可免版权下载)、RTX 4090 产品图、Logo 动画 - ---- - -### Segment 2:模型架构速览(0:20 - 0:45) - -| 镜头 | 画面 | 旁白 | 时长 | -|------|------|------|------| -| 2.1 | Transformer 架构图逐层展开:embed → 24层 decoder → norm → head | "1B 参数,24 层 Transformer,100k 词表的中英 BPE 分词器。" | 8s | -| 2.2 | 高亮 GQA:24个 Q head 映射到 4个 KV head | "GQA 分组查询注意力——24 个查询头只对应 4 个 KV 头,KV 缓存直接减少 83%。" | 10s | -| 2.3 | RoPE 旋转变换可视化 | "RoPE 旋转位置编码,支持动态长度外推。" | 5s | -| 2.4 | fade 到模型 card:vocab=100k, dim=1536, layers=24, heads=24, kv_heads=4 | 静默 | 2s | - -**视觉素材**:`architecture.py` 动画、模型参数 card - ---- - -### Segment 3:连续批处理(0:45 - 1:20) - -| 镜头 | 画面 | 旁白 | 时长 | -|------|------|------|------| -| 3.1 | 3 个请求同时到达服务器 | "当多个请求同时到达时——" | 3s | -| 3.2 | 静态批处理对比:最长补齐,3个请求串行 → 总耗时 max_len × 3 | "传统做法是静态批处理,把请求补齐到相同长度,串行处理,GPU 利用率低下。" | 8s | -| 3.3 | 连续批处理动画:任务流入 Waiting Queue → Cleanup → Refill → Prefill → Decode | "AstrAI 采用连续批处理:任务动态进出,GPU 每一刻都在满负荷运转。" | 10s | -| 3.4 | 放大 Decode 阶段:同一位置的任务合并成一批 | "特别地,只有处于相同 KV 缓存位置的任务才一起解码,从根本上避免了 RoPE 位置错乱的问题。" | 8s | -| 3.5 | 吞吐对比柱状图:Static Batch vs Continuous Batching (3x+) | "实测吞吐量提升 3 倍以上。" | 6s | - -**视觉素材**:`continuous_batching.py` 动画、对比图表 - ---- - -### Segment 4:分页 KV 缓存(1:20 - 1:50) - -| 镜头 | 画面 | 旁白 | 时长 | -|------|------|------|------| -| 4.1 | 展示 KV 缓存是一个固定大小的张量,被划分为多个相同大小的 page | "KV 缓存不再按请求预分配——而是划分为固定大小的页。" | 5s | -| 4.2 | 请求 A 到来,通过页表分配 2 个物理页,写入数据 | "请求到达时,通过页表分配物理页,按需写入。" | 7s | -| 4.3 | 请求 B 到来,分配新页,展示页表将逻辑位置映射到不同物理页 | "页表机制让逻辑位置和物理存储解耦——不同请求的页可以分散排列。" | 8s | -| 4.4 | Decode 阶段,请求继续生成 token,展示按需分配新页(_maybe_alloc_page) | "生成过程中如果当前页写满,自动追加新页——按需扩容,不浪费显存。" | 7s | -| 4.5 | 请求结束时展示页面回收(bitmask 置位) | "请求结束后,页面通过 O(1) 位掩码回收,即刻复用。" | 3s | - -**视觉素材**:`paged_cache.py` 动画、页表分配示意 - ---- - -### Segment 5:Demo 演示(1:50 - 2:15) - -| 镜头 | 画面 | 旁白 | 时长 | -|------|------|------|------| -| 5.1 | 侧录终端:启动 stream_chat.py,逐行输出对话 | "来实际看看效果。" | 10s | -| 5.2 | 多轮对话:中文问答,逐 token 喷出 | 静默 + 打字音效 | 8s | -| 5.3 | 切到 HTTP 模式:服务端 + curl 请求,流式返回 | "也提供 OpenAI 兼容的 HTTP API,一行 curl 就能调用。" | 7s | - -**视觉素材**:终端录屏(OBS 录制) - ---- - -### Segment 6:收尾 + CTA(2:15 - 2:30) - -| 镜头 | 画面 | 旁白 | 时长 | -|------|------|------|------| -| 6.1 | 全栈流程回顾(缩略架构图) | "训练用 SEQ → SFT → DPO/GRPO,推理用连续批处理——" | 5s | -| 6.2 | GitHub 页面 + Star 引导 | "——全部开源。点个 Star,一起让大模型更普惠。" | 7s | -| 6.3 | Logo + URL + "Open Source • Single GPU" | 静默 | 3s | - -**视觉素材**:GitHub 页面录屏、Logo 定版 - ---- - -## 4. 演示录制指南 - -### 4.1 准备工作 - -```bash -# 1. 安装依赖 -pip install -e ".[dev]" - -# 2. 下载模型(约 7GB) -python scripts/demo/download.py - -# 3. 验证模型加载 -python scripts/demo/generate_ar.py -``` - -### 4.2 录制场景 A:交互式对话 - -```bash -# 终端 1:启动交互式对话 -python scripts/demo/stream_chat.py - -# 预期交互 ->> 你好? -AstrAI: 你好!有什么我可以帮你的吗? ->> 请用中文介绍一下你自己 -AstrAI: ...(逐 token 输出) ->> 编一个关于人工智能的短故事 -AstrAI: ...(逐 token 输出) -``` - -**录制重点**: -- 逐 token 流式输出效果(用 OBS 录制终端窗口) -- 多轮对话的记忆能力(跨轮上下文保持) -- 打字音效叠加 - -### 4.3 录制场景 B:HTTP 服务 + 并发 - -```bash -# 终端 1:启动服务器 -python -m scripts.tools.server --port 8000 --device cuda - -# 终端 2:发送请求(非流式) -curl -X POST http://localhost:8000/v1/chat/completions \ - -H "Content-Type: application/json" \ - -d '{"messages":[{"role":"user","content":"Hello!"}],"stream":false}' - -# 终端 3:流式请求 -curl -X POST http://localhost:8000/v1/chat/completions \ - -H "Content-Type: application/json" \ - -d '{"messages":[{"role":"user","content":"Write a poem"}],"stream":true}' - -# 终端 4:并发压测(用 scripts/demo/generate_batch.py) -python scripts/demo/generate_batch.py -``` - -**录制重点**: -- 同时多个 curl 请求展示并发处理 -- 服务端日志显示批处理合并 -- `/stats` 端点展示实时统计 - -### 4.4 录制规格 - -| 参数 | 建议 | -|------|------| -| 分辨率 | 1920×1080 | -| 帧率 | 30fps | -| 终端 | Windows Terminal 或 iTerm2,深色主题 | -| 字号 | 16-18px,等宽字体(JetBrains Mono / Cascadia Code) | -| 录屏工具 | OBS Studio(免费) | -| 音频 | 旁白用 USB 麦克风,音效后期叠加 | - ---- - -## 5. 动画场景说明 - -位于 `promo/` 目录,使用 Manim 引擎。 - -### 安装 Manim - -```bash -# conda 环境内安装 -pip install manim - -# 验证 -python -c "import manim; print(manim.__version__)" -``` - -### 渲染命令 - -```bash -# 单独渲染一个场景 -manim -qh promo/continuous_batching.py ContinuousBatching - -# 全部场景渲染 -python promo/render_all.py - -# 快速草稿(480p,适合调试) -manim -ql promo/continuous_batching.py ContinuousBatching -``` - -输出文件为 `promo/output/videos/` 下的 `.mp4` 文件,可直接导入剪辑软件。 - -### 场景清单 - -| 文件 | 导出场景名 | 内容 | 建议时长 | -|------|-----------|------|---------| -| `transformer.py` | `Transformer` | 模型架构:Embed → GQA → SwiGLU → ×24 → LM Head | ~35s | -| `continuous_batching.py` | `ContinuousBatching` | 4 阶段流水线动画 + 吞吐对比 | ~30s | -| `paged_cache.py` | `PrefixCache` | 分页 KV 缓存:页表分配、按需扩容、回收 | ~30s | -| `architecture.py` | `Architecture` | 全栈架构逐层展开 + 数据流 | ~25s | - -### 自定义动画 - -如需修改动画内容: -- Manim 语法参考:https://docs.manim.community/ -- 所有动画元素(颜色、位置、速度)在场景类中通过参数调整 -- 中文字体渲染需额外配置: - -```python -# 在场景类开头添加 -Text.set_default(font="Microsoft YaHei") -``` - ---- - -## 6. 旁白文案草稿 - -### 中文版(完整 2:30) - -``` -[00:00] 大语言模型很强大—— -[00:03] 但跑起来需要几十张 GPU,普通人根本碰不到。 -[00:08] 但如果我告诉你,只要一张显卡就够了呢? -[00:13] AstrAI——单卡跑大模型。 - -[00:20] 1B 参数,24 层 Transformer,100k 词表的中英 BPE 分词器。 -[00:28] GQA 分组查询注意力——24 个查询头只对应 4 个 KV 头,KV 缓存直接减少 83%。 -[00:38] RoPE 旋转位置编码,支持动态长度外推。 - -[00:45] 当多个请求同时到达时—— -[00:48] 传统做法是静态批处理,把请求补齐到相同长度串行处理,GPU 利用率低下。 -[00:56] AstrAI 采用连续批处理:任务动态进出,GPU 每一刻都在满负荷运转。 -[01:06] 只有处于相同 KV 缓存位置的任务才一起解码,从根本上避免 RoPE 位置错乱。 -[01:14] 实测吞吐量提升 3 倍以上。 - -[01:20] 传统 KV 缓存预分配整段显存,浪费严重。 -[01:25] AstrAI 采用分页 KV 缓存——固定大小的页,通过页表间接寻址,按需分配。 -[01:33] 生成过程中页写满了自动追加,请求结束后 O(1) 回收。 -[01:40] 显存利用率大幅提升,支持更多并发请求。 - -[01:50] 来实际看看效果。 -[01:52] (现场演示部分,自由发挥) - -[02:15] 训练到推理,全流程开源,点个 Star,一起让大模型更普惠。 -[02:25] AstrAI — Open Source, Single GPU. -``` - ---- - -## 7. 素材清单 - -### 视频素材 - -| 素材 | 来源 | 状态 | -|------|------|------| -| 数据中心 / GPU 集群图片 | Pexels / Unsplash 免版权 | 需下载 | -| RTX 4090 产品图 | NVIDIA 官网 / 实物拍摄 | 需准备 | -| AstrAI Logo | `assets/images/logo.png` | ✅ 已有 | -| 终端录屏(对话) | OBS 录制 `scripts/demo/stream_chat.py` | 需录制 | -| 终端录屏(HTTP) | OBS 录制 curl + server | 需录制 | -| 终端录屏(并发) | OBS 录制 `generate_batch.py` | 需录制 | -| GitHub 页面 | 浏览器录屏 | 需录制 | -| Transformer 架构动画 | Manim 渲染 `transformer.py` | ✅ 已渲染 | -| 架构动画 | Manim 渲染 `architecture.py` | ✅ 已渲染 | -| 连续批处理动画 | Manim 渲染 `continuous_batching.py` | ✅ 已渲染 | -| 分页缓存动画 | Manim 渲染 `paged_cache.py` | 需重新渲染 | - -### 音频素材 - -| 素材 | 建议 | -|------|------| -| 旁白 | USB 麦克风录制,男声或女声,中文普通话 | -| 背景音乐 | Epidemic Sound / YouTube Audio Library 搜索 "technology ambient" | -| 音效 | 打字音效(terminal keystrokes)、转场 swoosh、whoosh | - -### 软件工具 - -| 用途 | 推荐工具 | 价格 | -|------|---------|------| -| 录屏 | OBS Studio | 免费 | -| 剪辑 | DaVinci Resolve | 免费 | -| 动画渲染 | Manim (`pip install manim`) | 免费 | -| 音频处理 | Audacity | 免费 | -| 字幕 | DaVinci Resolve 内建 / Aegisub | 免费 | - ---- - -## 附录:关键文件索引 - -| 文件路径 | 说明 | -|---------|------| -| `README.md` | 项目主页 README,含快速开始 | -| `assets/docs/introduction.md` | 模型架构深度介绍 | -| `assets/docs/design.md` | 设计文档 + UML 类图 | -| `astrai/inference/scheduler.py` | 连续批处理调度器核心代码 | -| `astrai/inference/engine.py` | 推理引擎统一接口 | -| `astrai/inference/server.py` | FastAPI 服务器 | -| `astrai/model/transformer.py` | Transformer 模型 | -| `astrai/model/module.py` | GQA、MLA、MLP 等模块 | -| `scripts/demo/stream_chat.py` | 交互式对话演示 | -| `scripts/demo/generate_batch.py` | 批量生成演示 | -| `scripts/tools/server.py` | HTTP 服务启动脚本 | -| `scripts/tools/benchmark.py` | 性能基准测试 | -| `scripts/promo/README.md` | 动画渲染说明(已移至 promo/) | -| `promo/render_all.py` | 一键渲染所有动画 | -| `promo/continuous_batching.py` | 连续批处理 Manim 场景 | -| `promo/paged_cache.py` | 分页 KV 缓存 Manim 场景 | -| `promo/architecture.py` | 架构总览 Manim 场景 | -| `params/config.json` | 模型配置 | diff --git a/README.md b/README.md index d2317ab..678e1fa 100644 --- a/README.md +++ b/README.md @@ -1,44 +1,270 @@ -# AstrAI Promo — 动画渲染 +# AstrAI Promo — 动画渲染 & 视频制作指南 Manim 驱动的技术动画,用于 AstrAI 宣传视频。 +目标时长:**2-3 分钟** -## 依赖 +--- -```bash -pip install manim -# 或: conda install -c conda-forge manim +## 目录 + +1. [项目定位与核心卖点](#1-项目定位与核心卖点) +2. [技术架构速览](#2-技术架构速览) +3. [渲染指南](#3-渲染指南) +4. [场景清单](#4-场景清单) +5. [分镜脚本](#5-分镜脚本) +6. [旁白文案草稿](#6-旁白文案草稿) +7. [素材清单](#7-素材清单) + +--- + +## 1. 项目定位与核心卖点 + +**一句话定位:** +> 一个能在单张消费级 GPU 上训练和推理的 1B 参数中英双语语言模型框架。 + +**核心卖点(视频中需突出):** + +| 卖点 | 说明 | 视觉表达 | +|------|------|---------| +| **单卡可跑** | 1B 参数,RTX 3090/4090 即可运行 | 巨大服务器集群 vs 单张显卡对比 | +| **连续批处理** | 动态合并请求,吞吐量 3x+ | 任务流经 Cleanup→Refill→Prefill→Decode 动画 | +| **分页 KV 缓存** | 固定大小页表 + O(1) 分配,按需扩容 | 页表分配与写入动画 | +| **OpenAI 兼容 API** | 一行代码切换 | curl 命令对比 | +| **流式输出** | 逐 token 返回,低首延迟 | 终端逐字喷出效果 | +| **全过程开源** | 训练+推理+权重全部开源 | GitHub 页面展示 | + +--- + +## 2. 技术架构速览 + +### 整体架构 + +``` +┌──────────────────────────────────────────────────┐ +│ FastAPI Server (OpenAI-Compatible API) │ +├──────────────────────────────────────────────────┤ +│ InferenceEngine (Streaming + Async + Batch) │ +├──────────────────────────────────────────────────┤ +│ Continuous Batching Scheduler │ +│ ┌────────┐ ┌──────┐ ┌────────┐ ┌────────┐ │ +│ │Cleanup │→ │Refill│→ │Prefill │→ │ Decode │ │ +│ └────────┘ └──────┘ └────────┘ └────────┘ │ +├──────────────────────────────────────────────────┤ +│ Paged KV Cache (Page Table + Page Pool) │ +├──────────────────────────────────────────────────┤ +│ Transformer (24层 GQA, RoPE, SwiGLU) │ +└──────────────────────────────────────────────────┘ ``` -## 渲染单个场景 +### 关键技术指标 + +| 指标 | 值 | +|------|------| +| 参数量 | ~1.0B | +| 词表大小 | 100,000(中英 BPE) | +| 层数 | 24 | +| 注意力头 | 24 Q-heads / 4 KV-heads(GQA) | +| 最大长度 | 2048 tokens | +| 精度 | bfloat16 | +| 最低显存 | ~6GB(推理)/~12GB(训练) | + +--- + +## 3. 渲染指南 + +依赖 conda 环境 `manim`: ```bash -# 1080p(推荐) -manim -qh promo/continuous_batching.py ContinuousBatching - -# 480p 草稿 -manim -ql promo/continuous_batching.py ContinuousBatching - -# 4K -manim -4k promo/continuous_batching.py ContinuousBatching +conda run -n manim python -m pip install manim ``` -## 渲染全部 +### 渲染全部(并行) ```bash -python promo/render_all.py +conda run -n manim python render_all.py # 1080p +conda run -n manim python render_all.py -ql # 480p draft +conda run -n manim python render_all.py -4k # 4K ``` -输出到 `promo/output/videos/`。 +### 渲染单个场景 -## 场景清单 +```bash +conda run -n manim python -m manim transformer.py Transformer -qh +``` + +输出到 `output/videos/`,`.mp4` 可直接导入剪辑软件。 + +### 中文字体 + +所有 `Text` 对象创建前需设置: + +```python +Text.set_default(font="Microsoft YaHei") +``` + +详细命令参考 `AGENTS.md`。 + +--- + +## 4. 场景清单 | 文件 | Scene class | 内容 | 建议时长 | |------|-------------|------|---------| -| `transformer.py` | `Transformer` | GQA 注意力机制详解 (Q/K/V→RoPE→Attention→O) + 规格卡 | ~25s | -| `continuous_batching.py` | `ContinuousBatching` | 4 阶段流水线 + 吞吐对比 | ~30s | +| `transformer.py` | `Transformer` | GQA 注意力机制 (Q/K/V→RoPE→Attention→O) + 规格卡 | ~35s | +| `continuous_batching.py` | `ContinuousBatching` | 4 阶段流水线 + 吞吐对比 (1.0x vs 3.4x) | ~30s | | `paged_cache.py` | `PrefixCache` | 分页 KV 缓存:页表分配、按需扩容、回收 | ~30s | -| `architecture.py` | `Architecture` | 全栈架构逐层展开 | ~30s | +| `architecture.py` | `Architecture` | 全栈架构:HTTP API → Engine → Paged Cache → Transformer | ~25s | +| `cta.py` | `CTA` | 结尾卡片:"AstrAI — Single GPU, Open Source, 1B params" | ~3s | -## 导入视频剪辑 +--- -输出的 `.mp4` 直接导入 DaVinci Resolve / Camtasia / Premiere Pro。 +## 5. 分镜脚本 + +总时长 **2:30**,分为 6 个段落。 + +### Segment 1:Hook + 问题陈述(0:00 - 0:20) + +| 镜头 | 画面 | 旁白 | 时长 | +|------|------|------|------| +| 1.1 | 黑屏,逐字打出"大语言模型很强大" | "大语言模型很强大——" | 3s | +| 1.2 | 切到数据中心照片 / 巨大 GPU 集群 | "——但跑起来需要几十张 GPU,普通人根本碰不到。" | 5s | +| 1.3 | 画面分屏:左边集群,右边一张 RTX 4090 | "但如果我告诉你,只要一张显卡就够了呢?" | 5s | +| 1.4 | Logo 出现:**AstrAI**,下方副标题 "1B 参数单卡推理框架" | "AstrAI——单卡跑大模型。" | 7s | + +**视觉素材**:数据中心图片、RTX 4090 产品图、Logo 动画 + +--- + +### Segment 2:模型架构速览(0:20 - 0:45) + +| 镜头 | 画面 | 旁白 | 时长 | +|------|------|------|------| +| 2.1 | Transformer 架构图逐层展开:embed → 24层 decoder → norm → head | "1B 参数,24 层 Transformer,100k 词表的中英 BPE 分词器。" | 8s | +| 2.2 | 高亮 GQA:24个 Q head 映射到 4个 KV head | "GQA 分组查询注意力——24 个查询头只对应 4 个 KV 头,KV 缓存直接减少 83%。" | 10s | +| 2.3 | RoPE 旋转变换可视化 | "RoPE 旋转位置编码,支持动态长度外推。" | 5s | +| 2.4 | fade 到模型 card:vocab=100k, dim=1536, layers=24, heads=24, kv_heads=4 | 静默 | 2s | + +**视觉素材**:`transformer.py` 动画、模型参数 card + +--- + +### Segment 3:连续批处理(0:45 - 1:20) + +| 镜头 | 画面 | 旁白 | 时长 | +|------|------|------|------| +| 3.1 | 3 个请求同时到达服务器 | "当多个请求同时到达时——" | 3s | +| 3.2 | 静态批处理对比:最长补齐,3个请求串行 → 总耗时 max_len × 3 | "传统做法是静态批处理,把请求补齐到相同长度,串行处理,GPU 利用率低下。" | 8s | +| 3.3 | 连续批处理动画:任务流入 Waiting Queue → Cleanup → Refill → Prefill → Decode | "AstrAI 采用连续批处理:任务动态进出,GPU 每一刻都在满负荷运转。" | 10s | +| 3.4 | 放大 Decode 阶段:同一位置的任务合并成一批 | "特别地,只有处于相同 KV 缓存位置的任务才一起解码,从根本上避免了 RoPE 位置错乱的问题。" | 8s | +| 3.5 | 吞吐对比柱状图:Static Batch vs Continuous Batching (3x+) | "实测吞吐量提升 3 倍以上。" | 6s | + +**视觉素材**:`continuous_batching.py` 动画、对比图表 + +--- + +### Segment 4:分页 KV 缓存(1:20 - 1:50) + +| 镜头 | 画面 | 旁白 | 时长 | +|------|------|------|------| +| 4.1 | 展示 KV 缓存是一个固定大小的张量,被划分为多个相同大小的 page | "KV 缓存不再按请求预分配——而是划分为固定大小的页。" | 5s | +| 4.2 | 请求 A 到来,通过页表分配 2 个物理页,写入数据 | "请求到达时,通过页表分配物理页,按需写入。" | 7s | +| 4.3 | 请求 B 到来,分配新页,展示页表将逻辑位置映射到不同物理页 | "页表机制让逻辑位置和物理存储解耦——不同请求的页可以分散排列。" | 8s | +| 4.4 | Decode 阶段,请求继续生成 token,展示按需分配新页(_maybe_alloc_page) | "生成过程中如果当前页写满,自动追加新页——按需扩容,不浪费显存。" | 7s | +| 4.5 | 请求结束时展示页面回收(bitmask 置位) | "请求结束后,页面通过 O(1) 位掩码回收,即刻复用。" | 3s | + +**视觉素材**:`paged_cache.py` 动画、页表分配示意 + +--- + +### Segment 5:Demo 演示(1:50 - 2:15) + +| 镜头 | 画面 | 旁白 | 时长 | +|------|------|------|------| +| 5.1 | 侧录终端:启动 stream_chat.py,逐行输出对话 | "来实际看看效果。" | 10s | +| 5.2 | 多轮对话:中文问答,逐 token 喷出 | 静默 + 打字音效 | 8s | +| 5.3 | 切到 HTTP 模式:服务端 + curl 请求,流式返回 | "也提供 OpenAI 兼容的 HTTP API,一行 curl 就能调用。" | 7s | + +**视觉素材**:终端录屏(OBS 录制) + +--- + +### Segment 6:收尾 + CTA(2:15 - 2:30) + +| 镜头 | 画面 | 旁白 | 时长 | +|------|------|------|------| +| 6.1 | 全栈流程回顾(缩略架构图) | "训练用 SEQ → SFT → DPO/GRPO,推理用连续批处理——" | 5s | +| 6.2 | GitHub 页面 + Star 引导 | "——全部开源。点个 Star,一起让大模型更普惠。" | 7s | +| 6.3 | Logo + URL + "Open Source • Single GPU" | 静默 | 3s | + +**视觉素材**:GitHub 页面录屏、Logo 定版 + +--- + +## 6. 旁白文案草稿 + +### 中文版(完整 2:30) + +``` +[00:00] 大语言模型很强大—— +[00:03] 但跑起来需要几十张 GPU,普通人根本碰不到。 +[00:08] 但如果我告诉你,只要一张显卡就够了呢? +[00:13] AstrAI——单卡跑大模型。 + +[00:20] 1B 参数,24 层 Transformer,100k 词表的中英 BPE 分词器。 +[00:28] GQA 分组查询注意力——24 个查询头只对应 4 个 KV 头,KV 缓存直接减少 83%。 +[00:38] RoPE 旋转位置编码,支持动态长度外推。 + +[00:45] 当多个请求同时到达时—— +[00:48] 传统做法是静态批处理,把请求补齐到相同长度串行处理,GPU 利用率低下。 +[00:56] AstrAI 采用连续批处理:任务动态进出,GPU 每一刻都在满负荷运转。 +[01:06] 只有处于相同 KV 缓存位置的任务才一起解码,从根本上避免 RoPE 位置错乱。 +[01:14] 实测吞吐量提升 3 倍以上。 + +[01:20] 传统 KV 缓存预分配整段显存,浪费严重。 +[01:25] AstrAI 采用分页 KV 缓存——固定大小的页,通过页表间接寻址,按需分配。 +[01:33] 生成过程中页写满了自动追加,请求结束后 O(1) 回收。 +[01:40] 显存利用率大幅提升,支持更多并发请求。 + +[01:50] 来实际看看效果。 +[01:52] (现场演示部分,自由发挥) + +[02:15] 训练到推理,全流程开源,点个 Star,一起让大模型更普惠。 +[02:25] AstrAI — Open Source, Single GPU. +``` + +--- + +## 7. 素材清单 + +### 视频素材 + +| 素材 | 来源 | +|------|------| +| 数据中心 / GPU 集群图片 | Pexels / Unsplash 免版权 | +| RTX 4090 产品图 | NVIDIA 官网 / 实物拍摄 | +| AstrAI Logo | 需设计 | +| 终端录屏 | OBS 录制 AstrAI demo 脚本 | +| GitHub 页面 | 浏览器录屏 | +| Transformer 架构动画 | Manim 渲染 `transformer.py` | +| 连续批处理动画 | Manim 渲染 `continuous_batching.py` | +| 分页缓存动画 | Manim 渲染 `paged_cache.py` | +| 全栈架构动画 | Manim 渲染 `architecture.py` | +| 结尾卡片 | Manim 渲染 `cta.py` | + +### 音频素材 + +| 素材 | 建议 | +|------|------| +| 旁白 | USB 麦克风录制,中文普通话 | +| 背景音乐 | Epidemic Sound / YouTube Audio Library 搜索 "technology ambient" | +| 音效 | 打字音效、转场 swoosh | + +### 软件工具 + +| 用途 | 推荐工具 | 价格 | +|------|---------|------| +| 录屏 | OBS Studio | 免费 | +| 剪辑 | DaVinci Resolve | 免费 | +| 动画渲染 | Manim(conda 环境 `manim`) | 免费 | +| 音频处理 | Audacity | 免费 | +| 字幕 | DaVinci Resolve 内建 / Aegisub | 免费 | diff --git a/render_all.py b/render_all.py index 8f26b80..12ff269 100644 --- a/render_all.py +++ b/render_all.py @@ -1,7 +1,8 @@ -"""Render all promo scenes with Manim.""" +"""Render all promo scenes with Manim in parallel.""" import subprocess import sys +from concurrent.futures import ThreadPoolExecutor, as_completed from pathlib import Path ROOT = Path(__file__).parent @@ -28,15 +29,22 @@ def render(file_name, scene_name, quality="-qh"): "--media_dir", str(media_dir), ] - print(f"Rendering {scene_name}...") + print(f"[{scene_name}] Rendering...") subprocess.run(cmd, check=True) - print(f" Done → {media_dir / 'videos' / scene_name.lower()}.mp4") + print(f"[{scene_name}] Done → {media_dir / 'videos' / scene_name.lower()}.mp4") if __name__ == "__main__": quality = "-qh" # 1080p; use -l for draft, -4k for ultra if len(sys.argv) > 1: quality = sys.argv[1] - for f, s in SCENES: - render(f, s, quality) + + max_workers = len(SCENES) + with ThreadPoolExecutor(max_workers=max_workers) as pool: + fut = {pool.submit(render, f, s, quality): s for f, s in SCENES} + for f in as_completed(fut): + exc = f.exception() + if exc: + print(f"[{fut[f]}] Failed: {exc}") + print("All scenes rendered.")