来开发者空间手搓一个迷你版大模型
曾几何时,也想自己训练一个大模型,即使不能像deepseek一样一鸣惊人,也希望能把大模型从0到1的训练过程弄清楚。于是首先想到的是transformer论文《Attention is all you need》,其主要技术架构图如下:

看到这张图,不得不放弃了,不仅是因为步骤太多,关键是有几步理解起来就很困难,编码实现更困难,比如多头注意力。不过好在我们有开发者空间 vibe coding 的辅助,让AI帮我们把这个图转化为代码。打开VS code,搜索安装 huawei developer space插件,创建 CDE并点击开机连接上,就可以在云开发环境里编程了。


然后在vs code里搜索安装kilo或cline等vibe coding 开源插件,在开发者空间首页的权益栏目里领取MaaS token给插件配置上api key,就可以无限使用AI 辅助编程了。

给kilo一段提示词,让其用pytorch生成一个大模型训练的简单示例代码,我们在本文末尾再详细解释代码,这里先直接运行看看结果。
import torch
import torch.nn as nn
import torch.optim as optim
# -----------------------------
# 1. 超参数设置(极小规模)
# -----------------------------
vocab_size = 100 # 词表大小(我们用数字代替单词)
d_model = 32 # 词向量维度(原版 Transformer 是 512+,这里缩小)
n_heads = 4 # 注意力头数(必须能整除 d_model)
n_layers = 2 # Transformer 层数
max_seq_len = 16 # 最大序列长度
batch_size = 8
learning_rate = 0.001
epochs = 100
# -----------------------------
# 2. 构造极小的训练数据(玩具级)
# -----------------------------
# 假设我们的“语言”只有数字 0~99,构造简单模式:如 [1,2,3,...] → 预测下一个
data = []
for i in range(100):
seq = list(range(i, min(i + max_seq_len + 1, 100))) # 生成递增序列
if len(seq) > 1:
data.append(seq)
# 将数据转为张量,并截断到统一长度
from torch.nn.utils.rnn import pad_sequence
data = [torch.tensor(s[:max_seq_len + 1]) for s in data if len(s) > 1]
data = pad_sequence(data, batch_first=True, padding_value=0)
# data shape: (num_samples, max_seq_len+1)
# 创建输入和目标(标准语言模型:输入是前 T 个词,目标是后 T 个词)
inputs = data[:, :-1] # shape: (N, T)
targets = data[:, 1:] # shape: (N, T)
# 构建 DataLoader(极简,直接切片)
dataset_size = inputs.size(0)
train_loader = [(inputs[i:i + batch_size], targets[i:i + batch_size])
for i in range(0, dataset_size, batch_size)]
# -----------------------------
# 3. 定义极简 Transformer 解码器层
# -----------------------------
class MiniGPT(nn.Module):
def __init__(self):
super().__init__()
self.token_embedding = nn.Embedding(vocab_size, d_model)
self.pos_embedding = nn.Embedding(max_seq_len, d_model)
# 使用多头注意力 + 前馈网络堆叠 n_layers 次
self.layers = nn.ModuleList([
# Use EncoderLayer for decoder-only self-attention (no external memory)
nn.TransformerEncoderLayer(
d_model=d_model,
nhead=n_heads,
dim_feedforward=d_model * 2, # 小型前馈网络
dropout=0.1,
batch_first=True
) for _ in range(n_layers)
])
self.lm_head = nn.Linear(d_model, vocab_size) # 输出词表 logits
def forward(self, x):
# x: (batch, seq_len)
B, T = x.shape
token_emb = self.token_embedding(x) # (B, T, d_model)
# make sure position indices are on the same device as token_emb
pos_idx = torch.arange(T, device=token_emb.device)
pos_emb = self.pos_embedding(pos_idx).unsqueeze(0).expand(B, T, -1) # (B, T, d_model)
x = token_emb + pos_emb # (B, T, d_model)
# 因为是 decoder-only,memory=None,只做 self-attention
# Each TransformerEncoderLayer performs self-attention (no external memory)
for layer in self.layers:
x = layer(x)
logits = self.lm_head(x) # (B, T, vocab_size)
return logits
# -----------------------------
# 4. 初始化模型、损失函数、优化器
# -----------------------------
model = MiniGPT()
criterion = nn.CrossEntropyLoss(ignore_index=0) # 忽略填充的 0
optimizer = optim.Adam(model.parameters(), lr=learning_rate)
# -----------------------------
# 5. 训练循环
# -----------------------------
model.train()
for epoch in range(epochs):
total_loss = 0
for x, y in train_loader:
optimizer.zero_grad()
# 前向传播
logits = model(x) # (B, T, vocab_size)
# 计算损失:将 logits 和 target 展平
B, T, V = logits.shape
# use reshape instead of view to support non-contiguous tensors
loss = criterion(logits.reshape(B * T, V), y.reshape(B * T))
# 反向传播
loss.backward()
optimizer.step()
total_loss += loss.item()
if epoch % 20 == 0:
print(f"Epoch {epoch}, Loss: {total_loss / len(train_loader):.4f}")
print("✅ 极简 LLM 训练完成!")
# -----------------------------
# 6. 简单推理示例(生成下一个词)
# -----------------------------
model.eval()
with torch.no_grad():
prompt = torch.tensor([[1, 2, 3]]) # 输入 "1 2 3"
logits = model(prompt)
next_token = logits[0, -1].argmax().item() # 取最后一个位置预测
print(f"输入: [1, 2, 3] → 预测下一个词: {next_token}")
我们先运行一下它,从结果来看,这段代码训练了100轮,生成了一个minigpt大模型,然后用其预测[1,2,3] 的下一个词,能正确输出4. 至此,用开发者空间成功训练出了一个大模型,接下来我们剖析一下大模型训练过程。

首先看文件头,比较好理解。引入了pytorch框架,它已经封装了很多机器学习、深度学习、神经网络、大模型、transformer原理操作,这对于非AI研究类人员来说是非常好的,它造好了武器,我们扣扳机开枪就行。从超参数设置里可以看到,这是一个100个词表的数据集,可谓是一个超级mini数据集,真实数据集可能要几十T大小。其它层数、注意力头数、批次大小、学习率、学习轮次等参数,都是训练大模型不可缺少的。如果对这些参数不理解,也很简单,让编程助手不断的添加更详细的注释就行。
再看其构造出来的数据集,用的方法也很简单,就是生成一堆连续的数字,例如 [1,2,3,4,5...], [2,3,4,5,6.....],真实大模型的数据集可能是1万本小说里的一段段文字,但原理其实是一样的,大模型就是从这一个个样本中找规律(这些词在向量空间里的相邻关系)。
接下来是transformer技术架构图的代码实现,首先是对输入进行词嵌入(token embedding)和位置嵌入(pos embedding),然后进行encoding编码,再进行前向传播,与技术架构图所画的流程是一样的。
接下来设置好损失函数和优化器,开始训练。训练过程就是不停的计算损失函数,把损失情况反向传播给优化器,优化器按梯度下降的方向去修改优化权重参数,随着训练轮次加多,可以看到损失函数越来越小,这表明模型的权重参数已经越来越好了。
最后我们看一下大模型推理过程,先把模型设置为评估模式 model.eval(),然后构造一个提示词[1,2,3],把这个提示词给到大模型,获得大模型返回的 next token
再次回顾一下大模型的训练和推理输出结果,可以看到随着训练轮次增加,损失loss越来越小,预测[1,2,3],能正确返回4,至此,一个迷你版的大模型诞生了!

- 点赞
- 收藏
- 关注作者
评论(0)