Source snapshot: 97d7f0fae96dc04b7ddad56fc1db6a108ed662cc [SEC-CLEAN] · pre-push-clean v1.0 · 109处敏感信息已自动转乱码
364 lines
10 KiB
Markdown
364 lines
10 KiB
Markdown
# Phase 0 · 执行手册 · 一步步跑通「一句话→分镜图片」
|
||
|
||
## 🎯 目标
|
||
|
||
> 在CVM服务器上跑通最小闭环:**输入一句话 → 光湖编排层自动拆剧本+分镜 → 调用免费API生成图片 → 输出一组分镜图片**
|
||
不需要训练模型。不需要租GPU。用现有服务器 + 免费API,先证明编排核心能跑。
|
||
>
|
||
|
||
---
|
||
|
||
## Step 0 · 登录服务器 · 确认环境
|
||
|
||
先SSH登录CVM服务器,确认基础环境:
|
||
|
||
```bash
|
||
# 登录服务器(把IP换成你的CVM公网IP)
|
||
ssh root@你的CVM公网IP
|
||
|
||
# 确认操作系统
|
||
cat /etc/os-release
|
||
|
||
# 确认Python版本(需要3.8+)
|
||
python3 --version
|
||
|
||
# 如果没有Python3,安装它:
|
||
# Ubuntu/Debian:
|
||
sudo apt update && sudo apt install -y python3 python3-pip python3-venv
|
||
# CentOS:
|
||
# sudo yum install -y python3 python3-pip
|
||
```
|
||
|
||
<aside>
|
||
📋
|
||
|
||
**妈妈操作:** 把上面的命令一条条复制粘贴到终端,把每条的输出结果告诉我,我来判断环境是否OK。
|
||
|
||
</aside>
|
||
|
||
---
|
||
|
||
## Step 1 · 创建光湖项目目录
|
||
|
||
```bash
|
||
# 创建项目根目录
|
||
mkdir -p /opt/guanghu
|
||
cd /opt/guanghu
|
||
|
||
# 创建子目录
|
||
mkdir -p core # 编排核心代码
|
||
mkdir -p output # 生成结果输出
|
||
mkdir -p config # 配置文件
|
||
mkdir -p logs # 日志
|
||
|
||
# 创建Python虚拟环境
|
||
python3 -m venv venv
|
||
source venv/bin/activate
|
||
|
||
# 安装基础依赖
|
||
pip install requests pillow
|
||
```
|
||
|
||
---
|
||
|
||
## Step 2 · 注册免费API · 获取密钥
|
||
|
||
我们需要两个免费API:
|
||
|
||
- **语言模型API**(拆剧本+分镜)→ 用硅基流动(SiliconFlow)的免费DeepSeek
|
||
- **图片生成API**(画分镜图片)→ 用硅基流动的免费FLUX
|
||
|
||
### 2.1 注册硅基流动
|
||
|
||
1. 打开 [siliconflow.cn](http://siliconflow.cn)
|
||
2. 注册账号(免费)
|
||
3. 进入控制台 → API密钥 → 创建一个密钥
|
||
4. 复制密钥(长得像 `sk-xxxxxxxxxxxxxxxx`)
|
||
|
||
### 2.2 写入配置文件
|
||
|
||
```bash
|
||
# 把你的API密钥写入配置文件(把sk-xxx换成你的真实密钥)
|
||
cat > /opt/guanghu/config/api_keys.py << 'EOF'
|
||
SILICONFLOW_API_KEY = "sk-你的硅基流动密钥"
|
||
EOF
|
||
```
|
||
|
||
<aside>
|
||
💡
|
||
|
||
**为什么用硅基流动?**
|
||
- 国内访问快,不用翻墙
|
||
- 免费额度足够开发调试
|
||
- 同时提供DeepSeek(语言)和FLUX(图片)两个模型的API
|
||
- 后面随时可以换成本地部署,编排层不用改
|
||
|
||
</aside>
|
||
|
||
---
|
||
|
||
## Step 3 · 编排核心v0.1 · 光湖的第一个大脑
|
||
|
||
这是光湖编排层的第一个版本——最简但完整的编排逻辑:
|
||
|
||
```bash
|
||
cat > /opt/guanghu/core/guanghu_brain.py << 'PYEOF'
|
||
#!/usr/bin/env python3
|
||
"""
|
||
光湖编排核心 v0.1 · Phase 0 最小闭环
|
||
一句话 → 拆剧本 → 拆分镜 → 生成图片 → 输出
|
||
"""
|
||
import json
|
||
import os
|
||
import sys
|
||
import requests
|
||
import time
|
||
from pathlib import Path
|
||
|
||
# === 配置 ===
|
||
sys.path.insert(0, "/opt/guanghu/config")
|
||
from api_keys import SILICONFLOW_API_KEY
|
||
|
||
API_BASE = "https://api.siliconflow.cn/v1"
|
||
LLM_MODEL = "deepseek-ai/DeepSeek-V3" # 免费语言模型
|
||
IMAGE_MODEL = "black-forest-labs/FLUX.1-schnell" # 免费图片模型
|
||
OUTPUT_DIR = Path("/opt/guanghu/output")
|
||
|
||
HEADERS = {
|
||
"Authorization": f"Bearer {SILICONFLOW_API_KEY}",
|
||
"Content-Type": "application/json"
|
||
}
|
||
|
||
# === 第一层:剧本引擎 ===
|
||
def generate_script(user_input: str) -> dict:
|
||
"""用户一句话 → 完整剧本(标题+场景列表)"""
|
||
print("\n🧠 [编排层] 正在理解你的意图,生成剧本...")
|
||
|
||
prompt = f"""你是一个专业的短剧编剧。用户给你一句话,你需要生成一个4-6个场景的短剧剧本。
|
||
|
||
用户输入:{user_input}
|
||
|
||
请严格按以下JSON格式输出(不要输出其他内容):
|
||
{{
|
||
"title": "短剧标题",
|
||
"style": "画面风格描述(如:2.5D偏写实韩系精致风格)",
|
||
"scenes": [
|
||
|
||
"scene_id": 1,
|
||
"description": "这个场景发生了什么(一句话)",
|
||
"image_prompt": "详细的英文画面描述,用于AI绘图。包含人物外观、表情、动作、场景、光线、构图。风格统一为2.5D semi-realistic Korean drama style。",
|
||
"dialogue": "这个场景的台词(中文)"
|
||
|
||
]
|
||
}}"""
|
||
|
||
resp = requests.post(f"{API_BASE}/chat/completions", headers=HEADERS, json={
|
||
"model": LLM_MODEL,
|
||
"messages": [{"role": "user", "content": prompt}],
|
||
"temperature": 0.7,
|
||
"max_tokens": 2000
|
||
})
|
||
|
||
result = resp.json()["choices"][0]["message"]["content"]
|
||
|
||
# 提取JSON(处理可能的markdown代码块包裹)
|
||
if "```json" in result:
|
||
result = result.split("```json")[1].split("```")[0]
|
||
elif "```" in result:
|
||
result = result.split("```")[1].split("```")[0]
|
||
|
||
script = json.loads(result.strip())
|
||
print(f" ✅ 剧本生成完成:《{script['title']}》共 {len(script['scenes'])} 个场景")
|
||
return script
|
||
|
||
# === 第二层:图片生成引擎 ===
|
||
def generate_image(prompt: str, scene_id: int, output_dir: Path) -> str:
|
||
"""根据画面描述生成图片"""
|
||
print(f" 🎨 [图片引擎] 正在生成场景 {scene_id} 的画面...")
|
||
|
||
resp = requests.post(f"{API_BASE}/images/generations", headers=HEADERS, json={
|
||
"model": IMAGE_MODEL,
|
||
"prompt": prompt,
|
||
"image_size": "1024x576", # 16:9 横版
|
||
"num_inference_steps": 4 # FLUX.1-schnell 用4步就够
|
||
})
|
||
|
||
data = resp.json()
|
||
image_url = data["images"][0]["url"]
|
||
|
||
# 下载图片
|
||
img_data = requests.get(image_url).content
|
||
img_path = output_dir / f"scene_{scene_id:02d}.png"
|
||
img_path.write_bytes(img_data)
|
||
|
||
print(f" ✅ 场景 {scene_id} 图片已保存: {img_path}")
|
||
return str(img_path)
|
||
|
||
# === 第三层:编排主控 ===
|
||
def run_pipeline(user_input: str):
|
||
"""光湖编排主流程:一句话 → 分镜图片"""
|
||
print("="*60)
|
||
print("🌊 光湖编排核心 v0.1 · Phase 0")
|
||
print(f"📝 用户输入:{user_input}")
|
||
print("="*60)
|
||
|
||
# 创建本次输出目录
|
||
timestamp = time.strftime("%Y%m%d_%H%M%S")
|
||
run_dir = OUTPUT_DIR / f"run_{timestamp}"
|
||
run_dir.mkdir(parents=True, exist_ok=True)
|
||
|
||
# Step 1: 生成剧本
|
||
script = generate_script(user_input)
|
||
|
||
# 保存剧本
|
||
script_path = run_dir / "script.json"
|
||
script_path.write_text(json.dumps(script, ensure_ascii=False, indent=2))
|
||
print(f"\n📄 剧本已保存: {script_path}")
|
||
|
||
# 打印剧本
|
||
print(f"\n📖 《{script['title']}》")
|
||
print(f" 风格:{script.get('style', '2.5D韩系精致风格')}")
|
||
for scene in script["scenes"]:
|
||
print(f" 场景{scene['scene_id']}: {scene['description']}")
|
||
if scene.get("dialogue"):
|
||
print(f" 💬 {scene['dialogue']}")
|
||
|
||
# Step 2: 逐场景生成图片
|
||
print(f"\n🎬 开始生成 {len(script['scenes'])} 个场景的图片...\n")
|
||
|
||
image_paths = []
|
||
for scene in script["scenes"]:
|
||
img_path = generate_image(
|
||
prompt=scene["image_prompt"],
|
||
scene_id=scene["scene_id"],
|
||
output_dir=run_dir
|
||
)
|
||
image_paths.append(img_path)
|
||
time.sleep(1) # 避免API限流
|
||
|
||
# 完成
|
||
print("\n" + "="*60)
|
||
print("🎉 光湖编排完成!")
|
||
print(f"📁 所有文件保存在: {run_dir}")
|
||
print(f" 📄 剧本: script.json")
|
||
for i, path in enumerate(image_paths, 1):
|
||
print(f" 🖼️ 场景{i}: {Path(path).name}")
|
||
print("="*60)
|
||
|
||
return {"script": script, "images": image_paths, "output_dir": str(run_dir)}
|
||
|
||
# === 入口 ===
|
||
if __name__ == "__main__":
|
||
if len(sys.argv) > 1:
|
||
user_input = " ".join(sys.argv[1:])
|
||
else:
|
||
user_input = input("\n🌊 光湖 · 说一句话,开始创作:")
|
||
|
||
run_pipeline(user_input)
|
||
PYEOF
|
||
|
||
chmod +x /opt/guanghu/core/guanghu_brain.py
|
||
```
|
||
|
||
<aside>
|
||
🧠
|
||
|
||
**这就是光湖的第一个大脑。** 虽然只有100多行代码,但它已经具备了编排层的核心逻辑:
|
||
- 🧠 理解用户意图(调LLM拆剧本)
|
||
- 🎬 拆分镜(LLM自动分场景+生成画面描述)
|
||
- 🎨 调引擎生图(调FLUX生成每个分镜的画面)
|
||
- 📁 组装输出(所有结果保存在一个目录)
|
||
|
||
后面所有的升级(加视频、加语音、加质量校验)都是在这个骨架上加东西。骨架不变。
|
||
|
||
</aside>
|
||
|
||
---
|
||
|
||
## Step 4 · 跑起来!
|
||
|
||
```bash
|
||
# 确保在虚拟环境里
|
||
cd /opt/guanghu
|
||
source venv/bin/activate
|
||
|
||
# 第一次运行!输入一句话试试
|
||
python3 core/guanghu_brain.py "一个穿白裙子的女孩在樱花树下回头微笑"
|
||
```
|
||
|
||
如果一切正常,你会看到:
|
||
|
||
1. 🧠 编排层生成剧本(4-6个场景)
|
||
2. 🎨 逐个场景生成图片
|
||
3. 📁 所有文件保存在 `/opt/guanghu/output/run_时间戳/` 目录
|
||
|
||
```bash
|
||
# 查看生成的文件
|
||
ls -la /opt/guanghu/output/run_*/
|
||
|
||
# 查看剧本内容
|
||
cat /opt/guanghu/output/run_*/script.json | python3 -m json.tool
|
||
```
|
||
|
||
<aside>
|
||
🎯
|
||
|
||
**Phase 0 通过标准:**
|
||
输入一句话 → 编排层自动拆出4-6个分镜 → 每个分镜生成一张图片 → 保存到output目录。
|
||
|
||
**看到图片就算成功!** 哪怕图片不够好看也没关系,那是后面优化的事。Phase 0只需要证明:编排核心能跑通。
|
||
|
||
</aside>
|
||
|
||
---
|
||
|
||
## Step 5 · 把图片下载到本地看
|
||
|
||
```bash
|
||
# 在你的本地电脑(不是服务器)打开终端,把图片下载下来
|
||
# 把IP和时间戳换成你的
|
||
scp -r root@你的CVM公网IP:/opt/guanghu/output/run_* ~/Desktop/光湖输出/
|
||
```
|
||
|
||
或者如果妈妈不方便用scp,可以在服务器上临时开一个HTTP服务看图:
|
||
|
||
```bash
|
||
# 在服务器上(临时用,看完关掉)
|
||
cd /opt/guanghu/output
|
||
python3 -m http.server 8080
|
||
# 然后浏览器打开 http://你的CVM公网IP:8080 就能看到图片了
|
||
# 看完按 Ctrl+C 关掉
|
||
```
|
||
|
||
---
|
||
|
||
## 📋 执行清单
|
||
|
||
- [ ] Step 0 · 登录服务器,确认Python3可用
|
||
- [ ] Step 1 · 创建光湖项目目录 + 虚拟环境
|
||
- [ ] Step 2 · 注册硅基流动,获取免费API密钥
|
||
- [ ] Step 3 · 创建编排核心脚本
|
||
- [ ] Step 4 · 运行!一句话→分镜图片
|
||
- [ ] Step 5 · 下载图片到本地看效果
|
||
|
||
---
|
||
|
||
## ⚠️ 可能遇到的问题
|
||
|
||
- **报错:ModuleNotFoundError: No module named 'requests'**
|
||
|
||
说明依赖没装好。运行:
|
||
|
||
`pip install requests pillow`
|
||
|
||
- **报错:API返回401或403**
|
||
|
||
说明API密钥不对。检查 `/opt/guanghu/config/api_keys.py` 里的密钥是否正确。
|
||
|
||
- **报错:JSON解析失败**
|
||
|
||
说明LLM返回的格式不太标准。再跑一次就行,或者告诉我具体报错,我帮你改脚本。
|
||
|
||
- **图片生成很慢**
|
||
|
||
正常。FLUX.1-schnell已经是最快的了(4步推理),但通过API还要排队。一张图大概10-30秒。6张图1-3分钟。 |