fusion-llm-demo / deployment /export_ggml.py
zhan1206
fix: comprehensive audit fixes - CRITICAL/HIGH/MEDIUM/LOW
a959e9a
Raw
History Blame
5.3 kB
"""
GGML 部署选项 - 将模型导出为 GGML 格式(用于 llama.cpp)
"""
import sys
import torch
import json
from pathlib import Path
sys.path.insert(0, '.')
def export_to_ggml(model, tokenizer, output_path, vocab_size=32000):
"""
将模型导出为 GGML 格式(简化版)
注意:这是简化版实现,用于演示目的
实际使用时应该使用 llama.cpp 官方工具:
- python convert.py models/your_model/
- 然后使用 llama.cpp 进行量化和推理
Args:
model: PyTorch 模型
tokenizer: 分词器
output_path: 输出路径(.ggml 文件)
vocab_size: 词汇表大小
"""
# TODO: This is a simplified/stub export. For production use,
# use llama.cpp's convert.py and quantize tools instead.
print("[EXPORT] 导出模型到 GGML 格式(简化版 - 仅保存配置,非可用 GGML 权重)...")
# 获取模型配置
if hasattr(model.config, 'vocab_size'):
vocab_size = model.config.vocab_size
elif hasattr(model.config, 'vocab_size_or_config_json_file'):
vocab_size = model.config.vocab_size_or_config_json_file
else:
print(f" 使用默认 vocab_size: {vocab_size}")
# 获取模型参数
hidden_size = model.config.hidden_size
num_layers = model.config.num_hidden_layers
num_heads = model.config.num_attention_heads
# 创建 GGML 格式(简化版)
# 实际 GGML 格式很复杂,这里只创建一个示例文件
ggml_data = {
"format": "ggml",
"version": "1.0",
"model": {
"vocab_size": vocab_size,
"hidden_size": hidden_size,
"num_layers": num_layers,
"num_heads": num_heads,
},
"weights": {},
}
# 添加权重(简化版:只保存权重名称,不保存实际数据)
for name, param in model.named_parameters():
if param.requires_grad:
ggml_data["weights"][name] = {
"shape": list(param.shape),
"dtype": str(param.dtype),
# 注意:实际 GGML 格式会保存量化后的权重
# 这里只保存元数据
}
# 保存为 JSON(简化版)
# 实际 GGML 格式是二进制格式
output_path = Path(output_path)
output_path.parent.mkdir(parents=True, exist_ok=True)
with open(output_path.with_suffix('.json'), "w", encoding="utf-8") as f:
json.dump(ggml_data, f, indent=2, ensure_ascii=False)
print(f" 模型已导出到: {output_path.with_suffix('.json')}")
print(" [注意] 这是简化版实现,实际使用时请使用 llama.cpp 官方工具")
print()
# 创建使用说明
readme_path = output_path.parent / "README_GGML.md"
with open(readme_path, "w", encoding="utf-8") as f:
f.write("# GGML 部署指南\n\n")
f.write("## 1. 安装 llama.cpp\n\n")
f.write("```bash\n")
f.write("git clone https://github.com/ggerganov/llama.cpp.git\n")
f.write("cd llama.cpp\n")
f.write("make\n")
f.write("```\n\n")
f.write("## 2. 转换模型\n\n")
f.write("```bash\n")
f.write("python convert.py models/fusion-llm/\n")
f.write("```\n\n")
f.write("## 3. 量化模型\n\n")
f.write("```bash\n")
f.write("./quantize models/fusion-llm/ggml-model-f16.bin models/fusion-llm/ggml-model-q4_0.bin q4_0\n")
f.write("```\n\n")
f.write("## 4. 运行推理\n\n")
f.write("```bash\n")
f.write("./main -m models/fusion-llm/ggml-model-q4_0.bin -p 'Once upon a time' -n 128\n")
f.write("```\n")
print(f" GGML 部署指南已保存到: {readme_path}")
print()
if __name__ == "__main__":
print("=" * 60)
print("Fusion-LLM GGML 部署选项")
print("=" * 60)
print()
# 创建示例模型
print("[1] 创建示例模型...")
from models.fusion_mini import FusionMini, FusionMiniConfig
config = FusionMiniConfig(
vocab_size=100,
hidden_size=32,
num_hidden_layers=1,
)
model = FusionMini(config)
print(" 示例模型已创建")
print()
# 创建示例分词器
print("[2] 创建示例分词器...")
from transformers import AutoTokenizer
# 使用真实分词器(如果可用)
try:
tokenizer = AutoTokenizer.from_pretrained("gpt2")
print(" 使用 GPT-2 分词器")
except:
# 创建模拟分词器
class MockTokenizer:
def __init__(self, vocab_size=100):
self.vocab_size = vocab_size
def __call__(self, text, **kwargs):
return {"input_ids": [[1, 2, 3]]}
def decode(self, ids, **kwargs):
return "Generated text"
tokenizer = MockTokenizer()
print(" 使用模拟分词器")
print()
# 导出到 GGML
print("[3] 导出到 GGML 格式...")
output_path = Path("output/ggml/model.ggml")
export_to_ggml(model, tokenizer, output_path, vocab_size=100)
print()
print("[PASS] GGML 部署选项测试通过")
sys.exit(0)