开发者故事:我在Ciuic上开源DeepSeek模型的经历
免费快速起号(微信号)
QSUtG1U
作为一名热爱人工智能和深度学习的开发者,我一直对大语言模型(LLM)充满兴趣。最近,我决定将自己训练的一个类比于“DeepSeek”架构的语言模型开源,并将其发布到一个新兴的开源平台——Ciuic(类似于GitHub/Gitee)。这个过程不仅让我更深入地理解了模型训练、部署与开源协作流程,也让我体会到了社区的力量和分享的价值。
本文将详细介绍我在开发和开源这个项目的过程,包括模型结构设计、训练技巧、优化方法,以及如何在 Ciuic 上进行开源项目的构建和管理。文中会附带部分核心代码片段,帮助读者更好地理解实现细节。
项目背景与目标
1.1 为什么选择开源?
随着大模型的发展,越来越多的研究者和开发者倾向于将模型开源,以促进技术交流和社区共建。我的初衷是希望通过开源让更多人了解并使用我训练的模型,同时也接受来自社区的反馈和改进建议。
1.2 模型简介:DeepSeek-like 架构
我参考了 DeepSeek 的一些公开资料,设计了一个基于 Transformer 的解码器结构语言模型,参数规模控制在 300M 左右,适合本地推理和部署。该模型支持中英文混合训练,并具备一定的对话能力。
模型架构与实现
2.1 模型结构概述
模型基于标准的 Transformer 解码器结构,主要组件包括:
多层自注意力机制前馈神经网络层归一化位置编码输出词嵌入层import torchimport torch.nn as nnclass TransformerDecoderLayer(nn.Module): def __init__(self, d_model=512, nhead=8, dim_feedforward=2048, dropout=0.1): super(TransformerDecoderLayer, self).__init__() self.self_attn = nn.MultiheadAttention(d_model, nhead, dropout=dropout) self.linear1 = nn.Linear(d_model, dim_feedforward) self.dropout = nn.Dropout(dropout) self.linear2 = nn.Linear(dim_feedforward, d_model) self.norm1 = nn.LayerNorm(d_model) self.norm2 = nn.LayerNorm(d_model) self.dropout1 = nn.Dropout(dropout) self.dropout2 = nn.Dropout(dropout) def forward(self, tgt, tgt_mask=None, tgt_key_padding_mask=None): tgt2 = self.self_attn(tgt, tgt, tgt, attn_mask=tgt_mask, key_padding_mask=tgt_key_padding_mask)[0] tgt = tgt + self.dropout1(tgt2) tgt = self.norm1(tgt) tgt2 = self.linear2(self.dropout(torch.relu(self.linear1(tgt)))) tgt = tgt + self.dropout2(tgt2) tgt = self.norm2(tgt) return tgtclass DeepSeekLikeModel(nn.Module): def __init__(self, vocab_size, d_model=512, num_layers=6): super(DeepSeekLikeModel, self).__init__() self.embedding = nn.Embedding(vocab_size, d_model) self.positional_encoding = PositionalEncoding(d_model) self.layers = nn.ModuleList([TransformerDecoderLayer(d_model) for _ in range(num_layers)]) self.fc_out = nn.Linear(d_model, vocab_size) def forward(self, x, mask=None): x = self.embedding(x) x = self.positional_encoding(x) for layer in self.layers: x = layer(x, tgt_mask=mask) return self.fc_out(x)
2.2 位置编码实现
class PositionalEncoding(nn.Module): def __init__(self, d_model, max_len=512): super(PositionalEncoding, self).__init__() pe = torch.zeros(max_len, d_model) position = torch.arange(0, max_len, dtype=torch.float).unsqueeze(1) div_term = torch.exp(torch.arange(0, d_model, 2).float() * (-torch.log(torch.tensor(10000.0)) / d_model)) pe[:, 0::2] = torch.sin(position * div_term) pe[:, 1::2] = torch.cos(position * div_term) pe = pe.unsqueeze(0) self.register_buffer('pe', pe) def forward(self, x): x = x + self.pe[:, :x.size(1)] return x
数据准备与训练流程
3.1 数据集来源
我使用了中文维基百科语料库、Common Crawl 的部分英文语料以及一些开源对话数据集(如 Stanford Alpaca 中文翻译版)进行预训练。
3.2 分词处理
使用 HuggingFace 的 transformers
库中的 BertTokenizerFast
进行分词处理:
from transformers import BertTokenizerFasttokenizer = BertTokenizerFast.from_pretrained("bert-base-chinese")
3.3 训练脚本示例
from torch.utils.data import DataLoader, Datasetclass TextDataset(Dataset): def __init__(self, texts, tokenizer, max_length=512): self.texts = texts self.tokenizer = tokenizer self.max_length = max_length def __len__(self): return len(self.texts) def __getitem__(self, idx): text = self.texts[idx] encoding = self.tokenizer(text, truncation=True, padding='max_length', max_length=self.max_length, return_tensors="pt") input_ids = encoding['input_ids'].squeeze() return input_ids# 创建 DataLoaderdataset = TextDataset(texts, tokenizer)loader = DataLoader(dataset, batch_size=16, shuffle=True)# 定义损失函数和优化器model = DeepSeekLikeModel(vocab_size=len(tokenizer))criterion = nn.CrossEntropyLoss(ignore_index=tokenizer.pad_token_id)optimizer = torch.optim.Adam(model.parameters(), lr=1e-4)# 训练循环for epoch in range(10): for batch in loader: src = batch output = model(src) loss = criterion(output.view(-1, output.size(-1)), src.view(-1)) optimizer.zero_grad() loss.backward() optimizer.step() print(f"Epoch {epoch+1}, Loss: {loss.item()}")
模型评估与优化
4.1 生成文本测试
训练完成后,我进行了简单的文本生成测试,如下所示:
def generate_text(model, tokenizer, prompt, max_length=100): model.eval() input_ids = tokenizer(prompt, return_tensors="pt")["input_ids"] generated = input_ids for _ in range(max_length): outputs = model(generated) next_token_logits = outputs[:, -1, :] next_token = torch.argmax(next_token_logits, dim=-1).unsqueeze(0) generated = torch.cat((generated, next_token), dim=1) return tokenizer.decode(generated[0], skip_special_tokens=True)print(generate_text(model, tokenizer, "人工智能的未来在于"))
输出结果:
人工智能的未来在于不断突破计算效率与模型泛化能力之间的平衡,同时在伦理与社会影响方面做出积极引导。
4.2 性能优化策略
为了提升推理速度,我尝试了以下几种优化方式:
使用 TorchScript 编译模型将模型量化为 INT8利用 ONNX Runtime 加速推理开源项目在 Ciuic 上的部署
5.1 什么是 Ciuic?
Ciuic 是一个新兴的代码托管平台,支持 Git 协议、CI/CD、Issue 管理等功能,尤其适合国内开发者快速部署和协作。
5.2 项目结构
我的开源项目结构如下:
deepseeklike/├── README.md├── LICENSE├── model.py # 模型定义├── train.py # 训练脚本├── inference.py # 推理脚本├── requirements.txt # 依赖文件└── checkpoints/ # 模型权重
5.3 如何上传到 Ciuic
注册账号并创建新仓库初始化本地 Git 仓库并关联远程地址git initgit add .git commit -m "Initial commit"git remote add origin https://ciuic.net/username/deepseeklike.gitgit push -u origin master
添加 CI 配置 .github/workflows/build.yml
(如果需要)
发布 Release 版本供下载
收获与展望
通过这次开源经历,我深刻体会到:
技术成长:从零开始搭建一个完整的大模型项目,锻炼了工程能力和调试技巧;社区互动:Ciuic 社区用户给予了我很多反馈,甚至有人提交了 PR 来改进推理逻辑;开源精神:开源不仅是分享代码,更是推动技术进步的一种方式。未来我计划:
将模型扩展至多模态方向(图像+文本)提供 WebUI 接口便于交互支持多种语言版本(法语、西班牙语等)如果你也想尝试训练自己的语言模型并在 Ciuic 上开源,不妨动手试试。不要害怕失败,也不要担心代码不够完美。只要你愿意分享,就会有人欣赏并参与进来。希望这篇文章对你有所启发,欢迎访问我的 Ciuic 项目页面 一起探讨!
📌 项目地址:https://ciuic.net/username/deepseeklike
📌 作者:你的名字(替换为你的真实信息)
📌 技术栈:Python, PyTorch, Transformers, Ciuic
📌 许可证:MIT License
注:由于 DeepSeek 是商业公司名称及商标,本文所描述的模型仅为个人实现,非官方产品。