Repository Reading Site
AI SaaS 平台 — 产品设计文档
**一句话:** 大模型训练与推理的 SaaS 平台,为企业和开发者提供"开箱即用"的 AI 能力。 **对标产品:** **核心价值:** --- | 角色 | 需求 | 使用方式 | |------|------|---------| | **开发者** | 调 API 做 AI 应用 | API Key + /v1/chat/completions |
AI SaaS 平台 — 产品设计文档
一、产品定位
一句话: 大模型训练与推理的 SaaS 平台,为企业和开发者提供"开箱即用"的 AI 能力。
对标产品:
- 国外:OpenAI API、AWS Bedrock、Google Vertex AI、Replicate、RunPod
- 国内:硅基流动、智谱开放平台、百度千帆、火山方舟
核心价值:
- 用户不需要自己搭 GPU 集群
- 用户不需要懂 K8s/Docker/分布式训练
- 调个 API 就能用大模型,按 Token 付费
- 想微调自己的模型?上传数据集,点一下开始
二、用户角色
| 角色 | 需求 | 使用方式 |
|---|---|---|
| 开发者 | 调 API 做 AI 应用 | API Key + /v1/chat/completions |
| 数据科学家 | 微调模型 | 上传数据集 → 选基座模型 → LoRA 微调 → 部署 |
| 企业管理员 | 管理团队用量和费用 | 控制台:成员管理、预算上限、用量报表 |
| 平台运维 | 管理 GPU 集群和模型 | 管理后台:节点管理、模型上架、计费配置 |
三、核心功能模块
3.1 模型推理服务(核心营收)
用户视角:
curl https://api.example.com/v1/chat/completions \
-H "Authorization: Bearer sk-xxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"model": "llama-3.2-3b",
"messages": [{"role": "user", "content": "你好"}],
"max_tokens": 100
}'
支持的协议: 完全兼容 OpenAI API 格式(这样用户现有代码改个 base_url 就能用)
功能清单:
| 功能 | 说明 | 优先级 |
|---|---|---|
| Chat Completions | /v1/chat/completions,支持流式 SSE | P0 |
| Completions | /v1/completions,文本补全 | P1 |
| Embeddings | /v1/embeddings,向量化 | P1 |
| Models | /v1/models,列出可用模型 | P0 |
| 流式输出 | stream: true,Server-Sent Events | P0 |
| 多模型选择 | 同一 API,model 参数切换不同模型 | P0 |
| 并发限制 | 按租户配置 RPM(每分钟请求数) | P0 |
| 超时控制 | 请求级别超时,长文本生成超时 | P1 |
3.2 模型管理
预置模型(平台提供):
| 模型 | 参数量 | 显存需求 | 场景 | 定价参考 |
|---|---|---|---|---|
| Llama 3.2 1B | 1B | 2GB | 轻量对话、分类 | ¥0.5/百万 Token |
| Llama 3.2 3B | 3B | 6GB | 通用对话 | ¥1/百万 Token |
| Qwen2.5 7B | 7B | 14GB | 中文对话、代码 | ¥2/百万 Token |
| Qwen2.5 14B | 14B | 28GB | 高质量中文 | ¥5/百万 Token |
| DeepSeek V3 | 671B MoE | 多卡 | 顶级推理 | ¥10/百万 Token |
私有模型(用户自己的):
- 用户上传 GGUF/SafeTensors 模型
- 或基于预置模型做 LoRA 微调
- 部署为独享推理实例
- 按 GPU 时长计费
3.3 模型微调(训练服务)
用户流程:
1. 选择基座模型(如 Qwen2.5 7B)
2. 上传训练数据集(JSONL 格式,每行一个对话)
3. 配置训练参数(epochs、learning_rate、LoRA rank)
4. 提交训练任务 → 等待完成
5. 查看训练指标(loss 曲线、评估结果)
6. 一键部署为推理服务
数据集格式(兼容 OpenAI fine-tuning):
{"messages":[{"role":"system","content":"你是客服助手"},{"role":"user","content":"退货流程是什么?"},{"role":"assistant","content":"退货流程如下:..."}]}
{"messages":[{"role":"user","content":"发票怎么开?"},{"role":"assistant","content":"开票步骤:..."}]}
功能清单:
| 功能 | 说明 | 优先级 |
|---|---|---|
| 数据集上传 | 支持 JSONL、CSV、JSON | P0 |
| 数据集预览 | 前 N 条预览 + 统计(条数、Token 分布) | P1 |
| 数据校验 | 格式检查、Token 长度检查、异常检测 | P1 |
| LoRA 微调 | 参数高效微调,只训练少量参数 | P0 |
| 全量微调 | 需大显存,按需开放 | P2 |
| 训练监控 | 实时 loss 曲线、ETA | P0 |
| Checkpoint 管理 | 自动保存、断点续训 | P1 |
| 评估 | 自动在验证集上评估 | P1 |
| 一键部署 | 训练完直接变成推理服务 | P0 |
3.4 租户与认证
租户体系:
组织 (Organization)
├── 成员 (Member) — 管理员/开发者/只读
├── API Key — 多个,可设置权限和有效期
├── 预算上限 — 月度消费上限
└── 项目 (Project) — 隔离不同业务的用量统计
认证方式:
| 方式 | 场景 | 实现 |
|---|---|---|
| API Key (Bearer Token) | API 调用 | Authorization: Bearer sk-xxxx |
| 用户名/密码 + JWT | Web 控制台 | 登录 → JWT → 后续请求带 Token |
| OAuth2 | 第三方登录 | GitHub/Google/微信 |
API Key 设计:
格式: sk-{org_id_prefix}{random_32_chars}
示例: sk-a1b2c3xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
属性:
- name: "生产环境 Key"
- permissions: ["chat", "embeddings"] (不含 "fine-tune")
- rate_limit: 100 RPM
- expires_at: 2027-01-01
- last_used_at: 2026-04-09
3.5 计费系统
计费模型:
| 计费方式 | 适用 | 计算方式 |
|---|---|---|
| Token 计量 | 推理 API | input_tokens × 单价 + output_tokens × 单价 |
| GPU 时长 | 训练/微调 | GPU型号 × 时长(秒) × 单价 |
| 存储 | 数据集/模型 | GB × 天 × 单价 |
| 独享实例 | 私有部署 | GPU型号 × 实例数 × 时长 |
Token 计量细节:
每次 API 调用:
prompt_tokens = tokenize(messages) 的 Token 数
completion_tokens = 生成文本的 Token 数
total_tokens = prompt + completion
cost = prompt_tokens * input_price + completion_tokens * output_price
示例 (Qwen2.5 7B):
input_price = ¥0.002 / 1K tokens
output_price = ¥0.006 / 1K tokens
一次对话 (prompt=500 tokens, completion=200 tokens):
cost = 500 * 0.002/1000 + 200 * 0.006/1000 = ¥0.0022
账户体系:
充值方式:
- 在线支付(支付宝/微信/Stripe)
- 企业转账
- 赠送额度(新用户)
余额管理:
- 预付费:余额不足时拒绝请求(返回 402 Payment Required)
- 后付费(企业客户):月底结算
- 用量告警:余额低于阈值时邮件/Webhook 通知
账单:
2026 年 4 月账单 — 组织: AcmeCorp
────────────────────────────────────
推理消耗:
Qwen2.5 7B: 1,250,000 input tokens × ¥0.002/1K = ¥2.50
380,000 output tokens × ¥0.006/1K = ¥2.28
Llama 3.2 3B: 500,000 input tokens × ¥0.001/1K = ¥0.50
150,000 output tokens × ¥0.003/1K = ¥0.45
训练消耗:
LoRA 微调 Qwen2.5 7B: A10 × 2.5小时 × ¥5/小时 = ¥12.50
存储:
数据集 2.3GB × 30天 × ¥0.01/GB/天 = ¥0.69
模型 4.1GB × 30天 × ¥0.01/GB/天 = ¥1.23
总计: ¥20.15
────────────────────────────────────
3.6 资源管理(运维视角)
GPU 资源池:
| 节点 | GPU 型号 | 显存 | 状态 | 分配给 |
|---|---|---|---|---|
| gpu-01 | A10 24G × 2 | 48GB | 在用 | 租户A 推理 + 租户B 微调 |
| gpu-02 | A100 80G × 4 | 320GB | 在用 | 平台公共推理池 |
| gpu-03 | A100 80G × 4 | 320GB | 空闲 | — |
| gpu-04 | H100 80G × 8 | 640GB | 在用 | 大模型训练 |
调度策略:
| 策略 | 说明 |
|---|---|
| 推理共享池 | 多租户共享 GPU,按请求路由,利用率高 |
| 推理独享 | 企业客户独占 GPU 实例,保证延迟 SLA |
| 训练队列 | FIFO 排队,高优先级客户插队 |
| GPU 型号匹配 | 小模型用 A10,大模型用 A100/H100 |
| 显存装箱 | 一张 A100 80G 可以同时跑 7B + 7B 两个模型 |
四、技术架构
4.1 整体架构
┌─────────────────────────────────────────────────────────────┐
│ 客户端层 │
│ Web 控制台 (React/Vue) │ CLI Tool │ SDK (Python/Go) │
└────────────────────────────┬────────────────────────────────┘
│ HTTPS
┌────────────────────────────▼────────────────────────────────┐
│ API Gateway (Go) │
│ 认证 → 租户识别 → 限流 → Token计量 → 路由 → 日志 │
│ 兼容 OpenAI 协议: /v1/chat/completions │
└──┬──────────┬──────────┬──────────┬──────────┬──────────────┘
│ │ │ │ │
▼ ▼ ▼ ▼ ▼
┌──────┐ ┌───────┐ ┌────────┐ ┌────────┐ ┌─────────┐
│ 用户 │ │ 计费 │ │ 模型 │ │ 训练 │ │ 数据集 │
│ 服务 │ │ 服务 │ │ 服务 │ │ 服务 │ │ 服务 │
│ (Go) │ │ (Go) │ │ (Go) │ │ (Go) │ │ (Go) │
└──┬───┘ └──┬────┘ └──┬─────┘ └──┬─────┘ └──┬──────┘
│ │ │ │ │
▼ ▼ ▼ ▼ ▼
┌──────────────────────────────────────────────────────────┐
│ PostgreSQL (元数据) │
│ users, orgs, api_keys, billing, models, datasets, jobs │
└──────────────────────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────────────┐
│ K8s 集群 (调度与执行) │
│ │
│ ┌─────────────────┐ ┌──────────────────┐ │
│ │ 推理 Operator │ │ 训练 Operator │ │
│ │ InferenceService │ │ TrainingJob CRD │ │
│ │ → Deployment │ │ → Job + GPU │ │
│ │ → Service │ │ → Checkpoint │ │
│ │ → HPA │ │ → 断点续训 │ │
│ └─────────────────┘ └──────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ GPU 节点池 │ │
│ │ A10 × N │ A100 × N │ H100 × N │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ ┌──────────┐ ┌───────────┐ ┌───────────┐ ┌───────────┐ │
│ │ Harbor │ │ NFS/S3 │ │Prometheus │ │ Loki │ │
│ │ 镜像仓库 │ │ 模型/数据 │ │ 监控 │ │ 日志 │ │
│ └──────────┘ └───────────┘ └───────────┘ └───────────┘ │
└──────────────────────────────────────────────────────────┘
4.2 服务拆分
| 服务 | 职责 | 数据 | K8s 部署 |
|---|---|---|---|
| api-gateway | 认证、限流、路由、Token 计量 | Redis (限流计数) | Deployment + Ingress |
| user-service | 用户/组织/API Key/权限 | PostgreSQL | Deployment |
| billing-service | 余额/扣费/账单/套餐 | PostgreSQL + Redis | Deployment |
| model-service | 模型注册/部署/下线 | PostgreSQL + S3(模型文件) | Deployment |
| training-service | 训练任务/数据集/评估 | PostgreSQL + S3(数据) | Deployment |
| inference-operator | 管理推理 Deployment | K8s API | Deployment (Operator) |
| training-operator | 管理训练 Job | K8s API | Deployment (Operator) |
4.3 核心数据模型
-- 组织
CREATE TABLE organizations (
id UUID PRIMARY KEY,
name VARCHAR(100) NOT NULL,
plan VARCHAR(20) DEFAULT 'free', -- free/pro/enterprise
balance DECIMAL(12,4) DEFAULT 0, -- 账户余额(元)
created_at TIMESTAMP DEFAULT NOW()
);
-- 用户
CREATE TABLE users (
id UUID PRIMARY KEY,
org_id UUID REFERENCES organizations(id),
email VARCHAR(255) UNIQUE NOT NULL,
role VARCHAR(20) DEFAULT 'developer', -- admin/developer/viewer
password_hash VARCHAR(255),
created_at TIMESTAMP DEFAULT NOW()
);
-- API Key
CREATE TABLE api_keys (
id UUID PRIMARY KEY,
org_id UUID REFERENCES organizations(id),
key_hash VARCHAR(64) NOT NULL, -- SHA256(sk-xxxx),不存明文
key_prefix VARCHAR(8) NOT NULL, -- sk-a1b2 用于显示
name VARCHAR(100),
permissions JSONB DEFAULT '["chat","embeddings"]',
rate_limit INT DEFAULT 60, -- RPM
expires_at TIMESTAMP,
last_used TIMESTAMP,
created_at TIMESTAMP DEFAULT NOW()
);
-- 模型
CREATE TABLE models (
id UUID PRIMARY KEY,
name VARCHAR(100) NOT NULL, -- "qwen2.5-7b"
display_name VARCHAR(200), -- "通义千问 2.5 7B"
type VARCHAR(20), -- "chat" / "embedding" / "completion"
provider VARCHAR(20), -- "platform" / "user"
org_id UUID, -- NULL=平台模型, 非NULL=用户私有
gpu_memory INT, -- 推理需要的显存(MB)
input_price DECIMAL(10,6), -- 元/千Token
output_price DECIMAL(10,6),
status VARCHAR(20) DEFAULT 'active',
config JSONB, -- 模型特定配置
created_at TIMESTAMP DEFAULT NOW()
);
-- 使用记录(高频写入,按天分区)
CREATE TABLE usage_logs (
id BIGSERIAL,
org_id UUID NOT NULL,
api_key_id UUID,
model_id UUID NOT NULL,
request_type VARCHAR(20), -- "chat" / "embedding" / "fine-tune"
prompt_tokens INT NOT NULL,
completion_tokens INT DEFAULT 0,
total_tokens INT NOT NULL,
cost DECIMAL(10,6), -- 本次消费(元)
latency_ms INT,
created_at TIMESTAMP DEFAULT NOW()
) PARTITION BY RANGE (created_at);
-- 训练任务
CREATE TABLE training_jobs (
id UUID PRIMARY KEY,
org_id UUID REFERENCES organizations(id),
base_model VARCHAR(100), -- "qwen2.5-7b"
dataset_id UUID,
method VARCHAR(20), -- "lora" / "full"
config JSONB, -- {"epochs":3, "lr":2e-5, "lora_rank":16}
status VARCHAR(20), -- "queued"/"running"/"completed"/"failed"
gpu_type VARCHAR(20), -- "A10" / "A100"
gpu_hours DECIMAL(8,2),
cost DECIMAL(10,4),
output_model_id UUID, -- 训练产出的模型
started_at TIMESTAMP,
completed_at TIMESTAMP,
created_at TIMESTAMP DEFAULT NOW()
);
-- 数据集
CREATE TABLE datasets (
id UUID PRIMARY KEY,
org_id UUID REFERENCES organizations(id),
name VARCHAR(200),
format VARCHAR(20), -- "jsonl" / "csv"
file_path VARCHAR(500), -- S3/NFS 路径
size_bytes BIGINT,
num_samples INT,
token_stats JSONB, -- {"avg":256, "max":2048, "total":512000}
status VARCHAR(20) DEFAULT 'uploaded',
created_at TIMESTAMP DEFAULT NOW()
);
4.4 Token 计量流程(关键路径)
用户请求 → API Gateway
│
├── 1. 验证 API Key (Redis 缓存 Key→Org 映射)
├── 2. 检查余额 (Redis 缓存,异步刷新到 DB)
├── 3. 检查限流 (Redis 滑动窗口)
│
├── 4. 转发到推理服务
│ ├── 计算 prompt_tokens (tokenizer)
│ ├── 模型推理
│ └── 计算 completion_tokens
│
├── 5. 扣费 (异步写入 usage_logs + 更新余额)
│ └── Redis DECRBY balance → 定期批量同步到 PostgreSQL
│
└── 6. 返回响应 (含 usage 字段)
{
"usage": {
"prompt_tokens": 52,
"completion_tokens": 128,
"total_tokens": 180
}
}
为什么余额用 Redis? 每次 API 调用都要检查和扣减余额。如果每次都写 PostgreSQL,高并发下数据库扛不住。Redis 做实时扣减,定期(如每分钟)批量同步到 PostgreSQL。
风险控制: Redis 挂了怎么办?
- 方案 A:拒绝请求(安全但影响可用性)
- 方案 B:降级为只检查 PostgreSQL 缓存的最近余额(有超额风险但保可用)
- 生产推荐:Redis Sentinel/Cluster 做高可用
4.5 推理服务架构
共享推理池(低成本,适合小用户):
┌──────────────────────────────┐
│ Deployment: qwen25-7b-pool │
│ Replicas: 3 (自动伸缩 1-10) │
│ 每个 Pod: 1 × A10 GPU │
│ 服务所有租户的 qwen2.5-7b 请求│
└──────────────────────────────┘
独享推理实例(高 SLA,适合企业客户):
┌──────────────────────────────┐
│ Deployment: acmecorp-qwen7b │
│ Replicas: 2 │
│ 只服务 AcmeCorp 的请求 │
│ 保证延迟 SLA: P95 < 500ms │
└──────────────────────────────┘
4.6 CRD 设计
# 推理服务 CRD
apiVersion: ai.platform.io/v1
kind: InferenceService
metadata:
name: qwen25-7b-shared
spec:
model: qwen2.5-7b
runtime: vllm # vLLM / TGI / llama.cpp
gpu:
type: A10
count: 1
memory: 24Gi
scaling:
minReplicas: 1
maxReplicas: 10
targetConcurrency: 8 # 每 Pod 8 并发时扩容
tenantMode: shared # shared / dedicated
dedicatedTo: "" # 独享时填 org_id
---
# 训练任务 CRD
apiVersion: ai.platform.io/v1
kind: TrainingJob
metadata:
name: acmecorp-finetune-001
spec:
baseModel: qwen2.5-7b
method: lora
dataset: s3://datasets/acmecorp/customer-service.jsonl
config:
epochs: 3
learningRate: "2e-5"
loraRank: 16
batchSize: 4
gpu:
type: A100
count: 1
checkpoint:
enabled: true
interval: 500steps
path: s3://checkpoints/acmecorp-finetune-001/
outputModel: acmecorp-cs-v1
五、API 设计
5.1 推理 API(兼容 OpenAI)
POST /v1/chat/completions 对话补全
POST /v1/completions 文本补全
POST /v1/embeddings 向量化
GET /v1/models 模型列表
5.2 平台管理 API
# 认证
POST /api/v1/auth/register 注册
POST /api/v1/auth/login 登录 → JWT
POST /api/v1/auth/refresh 刷新 Token
# API Key 管理
GET /api/v1/keys 列出 API Key
POST /api/v1/keys 创建 API Key
DELETE /api/v1/keys/:id 删除 API Key
# 用量与计费
GET /api/v1/usage 用量统计(按时间、模型、Key 筛选)
GET /api/v1/billing/balance 余额查询
POST /api/v1/billing/recharge 充值
GET /api/v1/billing/invoices 账单列表
# 模型管理
GET /api/v1/models 可用模型列表
POST /api/v1/models/deploy 部署私有模型
# 微调训练
POST /api/v1/fine-tuning/jobs 创建微调任务
GET /api/v1/fine-tuning/jobs 列出任务
GET /api/v1/fine-tuning/jobs/:id 任务详情
DELETE /api/v1/fine-tuning/jobs/:id 取消任务
# 数据集
POST /api/v1/datasets 上传数据集
GET /api/v1/datasets 列出数据集
GET /api/v1/datasets/:id 数据集详情
DELETE /api/v1/datasets/:id 删除数据集
六、部署架构
6.1 K8s Namespace 划分
system/ → 平台服务(Gateway, User, Billing, ...)
inference-shared/ → 共享推理池
inference-{org}/ → 独享推理实例(每个企业一个 NS)
training/ → 训练任务
monitoring/ → 监控(已有)
storage/ → 存储服务(MinIO/PostgreSQL/Redis)
6.2 节点分组
平台节点(无 GPU):
→ 平台服务、数据库、监控
推理节点(有 GPU):
label: node-type=inference
taint: nvidia.com/gpu=true:NoSchedule
→ 只跑推理 Pod
训练节点(有 GPU,大显存):
label: node-type=training
taint: nvidia.com/gpu=true:NoSchedule
→ 只跑训练 Job
弹性节点:
→ 推理/训练都可调度,按需分配
七、分阶段实施路线
Phase 1: MVP(最小可用产品)— 4 周
目标: 一个人注册→充值→调 API→扣费 的闭环跑通
| 周 | 做什么 | 产出 |
|---|---|---|
| W1 | 用户服务 + API Key + PostgreSQL | 注册/登录/创建 Key |
| W2 | API Gateway + Token 计量 + 计费 | 调 API 能扣钱 |
| W3 | 推理服务(llama.cpp CPU) | 真实对话能力 |
| W4 | 控制台前端 MVP | 用量看板 + Key 管理 |
可用但简陋: 单模型、无微调、无独享、CPU 推理
Phase 2: 核心能力 — 4 周
| 做什么 | 产出 |
|---|---|
| 多模型支持 | 模型注册、动态路由 |
| 推理 Operator | 自动部署/伸缩推理服务 |
| GPU 推理 | 接入 GPU 节点,vLLM 推理 |
| 流式输出 | SSE 流式返回 |
| 充值系统 | 支付宝/微信/Stripe |
Phase 3: 训练平台 — 4 周
| 做什么 | 产出 |
|---|---|
| 数据集管理 | 上传/校验/预览 |
| 训练 Operator | LoRA 微调 Job 管理 |
| Checkpoint 管理 | 断点续训、模型版本 |
| 训练监控 | 实时 loss 曲线 |
| 一键部署 | 微调模型 → 推理服务 |
Phase 4: 商业化 — 4 周
| 做什么 | 产出 |
|---|---|
| 独享实例 | 企业客户专属推理 |
| SLA 保障 | 延迟监控、可用性报表 |
| 多集群 | 跨地域 GPU 调度 |
| 模型市场 | 公开/私有模型交易 |
| 企业功能 | SSO、审计日志、合规 |
八、成本估算(参考)
GPU 服务器成本
| GPU | 月租(国内) | 月租(海外) | 推理能力 |
|---|---|---|---|
| A10 24G | ¥2,000-3,000 | $200-400 | 7B 模型 ~30 token/s |
| A100 40G | ¥5,000-8,000 | $800-1,500 | 70B 模型 ~15 token/s |
| A100 80G | ¥8,000-12,000 | $1,500-2,500 | 支持更大模型 |
| H100 80G | ¥15,000-25,000 | $2,500-4,000 | 顶级性能 |
盈利模型
收入 = API 调用收入 + 训练收入 + 存储收入 + 独享实例收入
成本 = GPU 服务器 + 网络/存储 + 开发运维人力
毛利率参考(行业):
- 共享推理: 60-80% 毛利(GPU 利用率高)
- 独享实例: 30-50% 毛利(利用率由客户决定)
- 训练任务: 50-70% 毛利(突发性高,GPU 可复用)
九、与现有 K8s Lab 的关系
我们已经搭建的:
- ✅ K8s 集群(5 节点)
- ✅ NFS 动态存储
- ✅ Harbor 镜像仓库
- ✅ Prometheus + Grafana 监控
- ✅ ArgoCD GitOps
- ✅ ML Operator (MLModel CRD)
- ✅ 真实模型训练+推理管线
还需要新建的:
- ❏ PostgreSQL(租户/计费元数据)
- ❏ Redis(限流/余额缓存)
- ❏ API Gateway(Go)
- ❏ 用户/计费/模型/训练服务(Go)
- ❏ 推理运行时(llama.cpp/vLLM)
- ❏ 前端控制台
- ❏ GPU 节点(租用)
核心代码全部用 Go 实现。 前端看需求再定技术栈。