Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
T
test
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
童国杉
test
Commits
203cb567
Commit
203cb567
authored
Jul 15, 2026
by
tgs
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Upload 模型仓库设计v1.txt
parent
0c2dcff6
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
576 additions
and
0 deletions
+576
-0
模型仓库设计v1.txt
模型仓库设计v1.txt
+576
-0
No files found.
模型仓库设计v1.txt
0 → 100644
View file @
203cb567
# 基于 CDC/Xet 的模型仓库多版本管理——完整设计方案
## 一、设计目标
| 目标 | 说明 |
|------|------|
| **高效版本管理** | 支持模型文件的无限版本迭代,`git log`、`git diff`、`git tag` 等操作保持毫秒级响应 |
| **块级去重** | 文件修改后仅上传变化的数据块(约 64KB 粒度),而非整个文件 |
| **存储空间节省** | 多版本共享相同数据块,避免冗余存储 |
| **传输效率** | 上传/下载仅传输新增/变化的数据块,典型场景下速度提升 2-3 倍 |
| **向下兼容** | 同时支持原生 Git 客户端和 Xet 增强客户端 |
| **水平扩展** | 存储层和服务层均可独立扩展 |
## 二、整体架构
```
┌─────────────────────────────────────────────────────────────────────────────┐
│ 客户端层 (Client Layer) │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────────┐ │
│ │ git-xet │ │huggingface- │ │ Web UI │ │ MLOps 工具链 │ │
│ │ (CLI增强) │ │ cli/SDK │ │ (浏览) │ │ (MLflow/Kubeflow)│ │
│ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ └────────┬────────┘ │
└─────────┼────────────────┼────────────────┼───────────────────┼────────────┘
│ │ │ │
▼ ▼ ▼ ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│ 网关与服务层 (Service Layer) │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ API 网关 (Hub Gateway) │ │
│ │ 认证、鉴权、限流、路由、请求转发 │ │
│ └───────────────────────────────┬─────────────────────────────────────┘ │
│ │ │
│ ┌──────────────────────────────┼─────────────────────────────────────┐ │
│ │ ▼ │ │
│ │ ┌──────────────────────────────────────────────────────────────┐ │ │
│ │ │ 版本管理服务 (Version Manager) │ │ │
│ │ │ - 仓库创建/删除 - Commit 管理 - Tag/Branch 管理 │ │ │
│ │ └──────────────────────────────────────────────────────────────┘ │ │
│ │ │ │ │
│ │ ┌──────────────────────────┼──────────────────────────────────┐ │ │
│ │ │ ▼ │ │ │
│ │ │ ┌──────────────────────────────────────────────────────┐ │ │ │
│ │ │ │ 映射服务 (Mapping Service) │ │ │ │
│ │ │ │ - Commit → 文件清单映射 - 块哈希 → 存储位置查询 │ │ │ │
│ │ │ │ - 全局块去重查询 - 文件重建元数据管理 │ │ │ │
│ │ │ └──────────────────────────────────────────────────────┘ │ │ │
│ │ └──────────────────────────────────────────────────────────────┘ │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────────┘
│ │ │
▼ ▼ ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│ 存储层 (Storage Layer) │
│ │
│ ┌─────────────────────────────┐ ┌─────────────────────────────────────┐ │
│ │ 元数据仓库 (Git Repo) │ │ 内容寻址存储 (CAS) │ │
│ │ │ │ │ │
│ │ - 指针文件 (.ptr) │ │ ┌─────────────────────────────┐ │ │
│ │ - 配置文件 (config.json) │ │ │ Xorb 聚合层 │ │ │
│ │ - 模型卡片 (README.md) │ │ │ (64MB/8,192个块) │ │ │
│ │ - .gitattributes │ │ └──────────┬──────────────────┘ │ │
│ │ - 完整 Git 历史 │ │ │ │ │
│ │ │ │ ┌──────────▼──────────────────┐ │ │
│ │ 托管: GitHub/GitLab/自建 │ │ │ 数据块 (Chunks) │ │ │
│ │ │ │ │ 目标 64KB, 范围 8-128KB │ │ │
│ └─────────────────────────────┘ │ │ 标识: Blake3 MerkleHash│ │
│ │ └──────────┬──────────────────┘ │ │
│ │ │ │
│ │ ┌──────────▼──────────────────┐ │ │
│ │ │ 对象存储 (S3/MinIO/Ceph) │ │ │
│ │ │ 持久化所有数据块和元数据 │ │ │
│ │ └─────────────────────────────┘ │ │
│ │ │
│ │ LFS 桥接层 (向下兼容) │ │
│ └─────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────────┘
```
## 三、核心组件详解
### 3.1 客户端 (Xet-Enabled Client)
客户端的核心职责是在 `git push` 时拦截并执行块级去重上传。
```
┌──────────────────────────────────────────────────────┐
│ Xet 客户端架构 │
├──────────────────────────────────────────────────────┤
│ ┌────────────────────────────────────────────────┐ │
│ │ Git 钩子拦截器 (pre-push) │ │
│ │ 检测 push 事件,接管大文件处理 │ │
│ └──────────────────┬─────────────────────────────┘ │
│ ▼ │
│ ┌────────────────────────────────────────────────┐ │
│ │ CDC 分块引擎 (Chunker) │ │
│ │ - 读取文件流 - GearHash 滚动哈希 │ │
│ │ - 确定块边界 - 输出可变大小块 (8-128KB) │ │
│ └──────────────────┬─────────────────────────────┘ │
│ ▼ │
│ ┌────────────────────────────────────────────────┐ │
│ │ 哈希计算与去重引擎 │ │
│ │ - Blake3 MerkleHash 计算 - 本地缓存查询 │ │
│ │ - 与服务端全局索引比对 - 识别新增块 │ │
│ └──────────────────┬─────────────────────────────┘ │
│ ▼ │
│ ┌────────────────────────────────────────────────┐ │
│ │ Xorb 聚合器 (Aggregator) │ │
│ │ 将多个小块聚合成 64MB 的 Xorb 对象 │ │
│ └──────────────────┬─────────────────────────────┘ │
│ ▼ │
│ ┌────────────────────────────────────────────────┐ │
│ │ 上传调度器 (Uploader) │ │
│ │ - 并发上传 Xorb - 断点续传 - 校验重试 │ │
│ └────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────┘
```
**参考实现**:Hugging Face 的参考实现使用 Rust 编写,位于 [xet-core](https://github.com/huggingface/xet-core)。
### 3.2 元数据仓库 (Git Repository)
存放所有**文本形态**的元数据,保持轻量高效:
| 文件类型 | 示例 | 大小 |
|----------|------|------|
| 指针文件 | `model.safetensors.ptr` | ~200 字节 |
| 模型配置 | `config.json` | ~几 KB |
| 模型卡片 | `README.md` | ~几 KB |
| 属性配置 | `.gitattributes` | ~几十字节 |
**指针文件格式示例**(伪代码):
```
version https://xet-spec.com/v1.0
oid sha256:3b8a5921e2c... (文件内容哈希)
size 10737418240
xet_file_id xet_abc123def456
```
指针文件仅记录文件的逻辑标识(`xet_file_id`),不包含任何块级别的映射信息。真正的块映射存储在映射服务中。
### 3.3 内容寻址存储 (CAS)
CAS 是 Xet 系统的核心存储基础设施:
**核心特性**:
- **内容寻址**:所有对象通过其加密哈希进行存储和检索
- **不可变性**:内容一旦存储即不可更改
- **自动去重**:相同内容在存储级别自动去重
**存储层级**:
```
┌─────────────────────────────────────────────────────────┐
│ CAS 存储层级 │
├─────────────────────────────────────────────────────────┤
│ │
│ Level 1: 数据块 (Chunk) │
│ ├─ 大小: 8KB ~ 128KB (目标 64KB) │
│ ├─ 标识: Blake3 MerkleHash │
│ └─ 内容: 原始文件数据片段 │
│ │
│ Level 2: Xorb (聚合块) │
│ ├─ 最大大小: 64MB │
│ ├─ 最大块数: 8,192 个 │
│ └─ 作用: 减少元数据和网络开销 │
│ │
│ Level 3: Shard (碎片) │
│ ├─ 最大大小: 64MB │
│ └─ 内容: Xorb 列表 + 文件重建元数据 │
│ │
│ Level 4: 对象存储 (S3/MinIO) │
│ └─ 最终持久化层 │
│ │
└─────────────────────────────────────────────────────────┘
```
### 3.4 映射服务 (Mapping Service)
维护 **Commit → 文件 → 块列表** 的三级映射关系:
**数据模型**:
```sql
-- 仓库表
CREATE TABLE repositories (
repo_id UUID PRIMARY KEY,
repo_name VARCHAR(255) UNIQUE,
created_at TIMESTAMP
);
-- Commit 映射表
CREATE TABLE commit_mappings (
commit_hash CHAR(40) PRIMARY KEY, -- Git commit SHA
repo_id UUID REFERENCES repositories,
parent_hash CHAR(40), -- 父 commit
file_manifest_id UUID, -- 指向文件清单
created_at TIMESTAMP
);
-- 文件清单表
CREATE TABLE file_manifests (
manifest_id UUID PRIMARY KEY,
file_path VARCHAR(512),
file_size BIGINT,
xet_file_id VARCHAR(64), -- Xet 文件唯一标识
chunk_list JSONB, -- [offset, hash, size]
-- 示例: [{"offset":0, "hash":"abc...", "size":65536}, ...]
);
-- 全局块索引表 (用于去重查询)
CREATE TABLE global_chunks (
chunk_hash CHAR(64) PRIMARY KEY, -- Blake3 哈希
storage_location VARCHAR(255), -- S3 路径或 CAS 引用
size INT,
ref_count INT DEFAULT 1 -- 引用计数
);
```
**关键操作**:
1. **去重查询**:客户端上传时,将块哈希列表发送给映射服务,服务返回哪些块已存在
2. **映射注册**:新 commit 创建时,注册文件→块的映射关系
3. **文件重建**:下载时,根据 commit_hash 查询完整的块列表和存储位置
## 四、CDC 分块算法
### 4.1 算法选择:GearHash
Xet 协议规范中指定使用 **GearHash** 算法进行内容定义分块。
**核心原理**:
CDC 的关键属性是**边界稳定性**:分块边界由数据内容通过滚动哈希确定,而非固定的字节偏移量。
```
原始数据: ···AAAAAA|BBBBBBBB|CCCCCCCC|DDDDDDDD|EEEEEEEE···
chunk0 chunk1 chunk2 chunk3 chunk4
在 chunk2 中插入 "XX":
···AAAAAA|BBBBBBBB|CCCCXXCCCC|DDDDDDDD|EEEEEEEE···
chunk0 chunk1 chunk2' chunk3 chunk4
(相同) (相同) (变化) (相同) (相同)
```
**固定大小分块的问题**(对比):
```
固定大小分块 - 在 chunk2 中插入 "XX":
···AAAAAA|BBBBBBBB|CCCCXXCC|CCDDDDDD|DDEEEEEE···
chunk0 chunk1 chunk2' chunk3' chunk4'
(相同) (相同) (变化) (变化) (变化)
```
插入操作导致编辑之后的所有边界偏移,所有后续块全部失效。
### 4.2 算法参数
| 参数 | 值 | 说明 |
|------|-----|------|
| 目标块大小 | 64KB | 平衡去重粒度和元数据开销 |
| 最小块大小 | 8KB | 防止块过小导致元数据爆炸 |
| 最大块大小 | 128KB | 防止块过大降低去重效率 |
| 哈希函数 | Blake3 | 用于 MerkleHash 计算 |
| 切割条件 | `hash(window) & mask == 0` | 概率均匀,保证边界分布 |
### 4.3 Python 核心实现
```python
import hashlib
def gear_hash_chunk(data: bytes,
min_size: int = 8 * 1024,
max_size: int = 128 * 1024,
target_size: int = 64 * 1024,
mask: int = 0x0000FFFF) -> list:
"""
基于 GearHash 的 CDC 分块
使用滚动哈希 + 边界条件确定切割点
"""
chunks = []
start = 0
i = 0
h = 0
mod = 1 << 64
base = 257
while i < len(data):
# 滚动哈希更新
h = (h * base + data[i]) % mod
i += 1
# 达到最小块大小后才允许切割
if i - start >= min_size:
# 哈希匹配条件 或 达到最大块大小
if (h & mask) == 0 or (i - start) >= max_size:
chunk = data[start:i]
chunk_hash = hashlib.blake3(chunk).hexdigest()
chunks.append({
'offset': start,
'size': len(chunk),
'hash': chunk_hash,
'data': chunk
})
start = i
# 重置滚动哈希
h = 0
# 处理末尾剩余数据
if start < len(data):
chunk = data[start:]
chunks.append({
'offset': start,
'size': len(chunk),
'hash': hashlib.blake3(chunk).hexdigest(),
'data': chunk
})
return chunks
```
## 五、版本管理机制
### 5.1 版本标识体系
| 层级 | 标识方式 | 作用 | 可变性 |
|------|----------|------|--------|
| **Commit** | SHA-1 哈希 | 唯一标识一次提交的快照 | 不可变 |
| **Tag** | 语义化名称 (v1.0, v2.1) | 用户可读的版本号 | 不可变(指向固定 Commit) |
| **Branch** | 分支名 (main, dev) | 开发线标识 | 可变(指向最新 Commit) |
**映射关系**:
```
用户输入: git checkout v1.0
↓
Git 解析: v1.0 → commit_hash = a3f2c7d9...
↓
映射服务: commit_hash → file_manifest_id → chunk_list
↓
CAS 存储: 根据 chunk_list 从对象存储拉取数据块
↓
客户端: 按 offset 顺序拼接 → 完整文件
```
### 5.2 版本存储示意
```
时间线 (Commits):
────────────────────────────────────────────────────────────►
commit: a3f2c7d ←── b8e9f1a ←── c4d5e2b
│ │ │
▼ ▼ ▼
文件清单: [块A,块B,块C] [块A,块D,块C] [块A,块E,块C]
│ │ │
└────────────────────┼────────────────────┘
▼
对象存储实际占用:
块A (复用) + 块B + 块C + 块D + 块E
(5个块 vs 3个完整文件副本)
```
**存储节省原理**:3 个版本共享块 A 和块 C,仅存储各自独有的块。
## 六、核心流程
### 6.1 上传流程(git push)
```
┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
│ 用户 │ │ 客户端 │ │ 映射服务 │ │ CAS存储 │
└────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘
│ │ │ │
│ git push │ │ │
│───────────────>│ │ │
│ │ │ │
│ │ 1. 读取文件 │ │
│ │ 2. CDC分块 │ │
│ │ 3. 计算哈希 │ │
│ │ │ │
│ │ 4. 发送哈希列表 │ │
│ │───────────────>│ │
│ │ │ │
│ │ 5. 返回已存在块 │ │
│ │<───────────────│ │
│ │ │ │
│ │ 6. 仅上传新块 │ │
│ │───────────────────────────────>│
│ │ │ │
│ │ 7. 注册映射 │ │
│ │───────────────>│ │
│ │ │ │
│ │ 8. 上传指针文件 │ │
│ │ (Git原生) │ │
│ │───────────────>│ │
│ │ │ │
│ 上传完成 │ │ │
│<───────────────│ │ │
│ │ │ │
```
**关键优化**:典型的 5GB 数据库文件追加 1MB 数据,LFS 需重新上传 5GB(约 13 分钟),Xet 仅需上传变化块(约 0.1 秒)。
### 6.2 下载流程(git clone / git checkout)
```
┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
│ 用户 │ │ 客户端 │ │ 映射服务 │ │ CAS存储 │
└────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘
│ │ │ │
│ git clone │ │ │
│───────────────>│ │ │
│ │ │ │
│ │ 1. 拉取元数据 │ │
│ │ (Git原生) │ │
│ │───────────────>│ │
│ │ │ │
│ │ 2. 获取指针文件 │ │
│ │<───────────────│ │
│ │ │ │
│ │ 3. 请求文件清单 │ │
│ │───────────────>│ │
│ │ │ │
│ │ 4. 返回块列表 │ │
│ │<───────────────│ │
│ │ │ │
│ │ 5. 并行下载块 │ │
│ │───────────────────────────────>│
│ │ │ │
│ │ 6. 校验哈希 │ │
│ │ 7. 按offset拼接│ │
│ │ │ │
│ 文件就绪 │ │ │
│<───────────────│ │ │
│ │ │ │
```
**性能数据**(Hugging Face 实测):
| 指标 | Git LFS | Xet (CDC) |
|------|---------|-----------|
| 平均下载时间 | 51 分钟 | 19 分钟 |
| 平均上传时间 | 47 分钟 | 24 分钟 |
| 存储占用 | 8.9 GB | 3.52 GB |
## 七、性能优化策略
### 7.1 本地缓存
客户端维护本地块缓存,已下载的块在本地保留,后续版本切换时无需重新下载。
### 7.2 并行传输
- 多线程并发下载/上传 Xorb
- 每个 Xorb 最大 64MB,包含最多 8,192 个块
### 7.3 压缩优化
Xorb 对象在存储前进行压缩,减少存储空间和传输带宽。
### 7.4 增量更新
- **上传**:仅传输新增块,已存在块直接复用
- **下载**:仅下载本地缺失的块
### 7.5 全局去重
跨文件、跨仓库的相同内容块自动去重。
## 八、安全与权限
### 8.1 数据完整性
- 每个块使用 Blake3 MerkleHash 标识
- 下载时校验哈希,确保数据完整性
- 文件重建时验证所有块的哈希匹配
### 8.2 访问控制
- 块级权限控制:用户只能读取其有权访问的文件所需的块
- 仓库级别的读写权限继承自 Hugging Face Hub
- Xet 令牌认证机制
### 8.3 隐私保护
- 块内容通过加密哈希保护
- 哈希不可逆,无法从哈希还原原始内容
## 九、部署架构
```
┌──────────────────┐
│ Load Balancer │
│ (Nginx/ALB) │
└────────┬─────────┘
│
┌──────────────┼──────────────┐
│ │ │
┌────▼────┐ ┌────▼────┐ ┌────▼────┐
│ API节点1│ │ API节点2│ │ API节点3│ ← 无状态,水平扩展
│ (服务层)│ │ (服务层)│ │ (服务层)│
└────┬────┘ └────┬────┘ └────┬────┘
│ │ │
└──────────────┼──────────────┘
│
┌──────────────┼──────────────┐
│ │ │
┌────▼────┐ ┌────▼────┐ ┌────▼────┐
│ Git │ │Postgre- │ │ Redis │
│ Server │ │ SQL │ │ (缓存) │
│(元数据) │ │(映射) │ │ │
└─────────┘ └─────────┘ └─────────┘
│
┌────▼────┐
│ MinIO/ │
│ S3集群 │
│(对象存储)│
└─────────┘
```
**扩展性说明**:
- **API 节点**:无状态,可根据流量水平扩展
- **PostgreSQL**:读写分离 + 分库分表
- **Redis**:缓存热点块哈希和映射关系
- **MinIO/S3**:分布式对象存储,支持 PB 级扩展
## 十、与 Git LFS 的对比总结
| 维度 | Git LFS | Xet (CDC) |
|------|---------|-----------|
| **去重粒度** | 文件级 | 块级 (8-128KB) |
| **修改 5GB 文件中的 1MB** | 重新上传 5GB | 仅上传变化的块 |
| **存储效率** | 低(每个版本存完整文件) | 高(块级共享) |
| **上传速度** | 慢(全量传输) | 快(增量传输) |
| **跨文件去重** | 不支持 | 支持 |
| **Git 原生支持** | 是(官方扩展) | 需安装 Xet 客户端 |
| **向下兼容** | 完整 | LFS 桥接层 |
## 十一、实施路线图
### Phase 1: 基础架构搭建
- [ ] 部署 CAS 存储集群(MinIO/S3)
- [ ] 部署映射服务(PostgreSQL + Redis)
- [ ] 搭建 Git 元数据仓库服务
### Phase 2: 客户端开发
- [ ] 实现 CDC 分块引擎(GearHash)
- [ ] 实现 Git pre-push 钩子拦截
- [ ] 实现 Xorb 聚合与上传调度
- [ ] 实现下载与文件重建
### Phase 3: 服务端开发
- [ ] 实现全局块去重查询 API
- [ ] 实现映射注册 API
- [ ] 实现 LFS 桥接层(向下兼容)
- [ ] 实现认证与权限控制
### Phase 4: 测试与优化
- [ ] 单元测试 + 集成测试
- [ ] 大规模性能测试(PB 级数据)
- [ ] CDC 参数调优(块大小、边界条件)
- [ ] 监控与告警体系搭建
### Phase 5: 生产部署
- [ ] 灰度发布
- [ ] 全量迁移
- [ ] 文档与开发者工具完善
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment