ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

从零构建大语言模型:斯坦福CS336课程实践指南

从零构建大语言模型:斯坦福CS336课程实践指南 这次我们来看一个面向2026年的新版Stanford CS336课程项目——“【极致中配】2026年最新版 Stanford CS336: 从头构建大语言模型”。这不是一个现成的模型推理工具而是一个完整的、从零开始的大语言模型构建教程与实践项目。它源自斯坦福大学的经典课程CS336旨在让你彻底理解LLM的底层原理并亲手搭建一个可运行的模型。对于开发者、算法工程师或任何想深入LLM内部机制的人来说这个项目的价值在于“知其然更知其所以然”。它不追求部署一个功能最全的ChatGPT替代品而是聚焦于构建过程本身从数据准备、模型架构设计、训练循环编写到最终的推理实现。你将获得一套清晰、模块化的代码库以及配套的详细教程能够在一台配置尚可的机器上完成一个真正属于自己的、可训练的Transformer语言模型。本文的核心是带你走通这个构建流程。我们会重点关注几个实操问题需要什么样的硬件环境代码结构如何组织训练数据如何准备训练过程如何监控最终模型如何测试我们将基于项目提供的材料梳理出一套可执行的本地构建与验证方案让你不仅能看懂理论更能动手跑起来。1. 核心能力速览能力项说明项目类型大语言模型LLM教学与构建项目非即用型推理服务。开源来源基于斯坦福大学CS336课程内容社区维护的2026年更新版。核心目标从零开始完整实现Transformer架构并进行数据预处理、模型训练与文本生成。硬件门槛中等配置即可。项目侧重于教学和原理验证对大规模预训练要求不高。使用小规模数据集如WikiText-2时具备8GB以上显存的GPU如RTX 3060/4060即可进行有效训练。CPU模式可用于代码调试和小规模推理。软件环境Python, PyTorch, 标准深度学习库如transformers, datasets用于数据加载。环境依赖清晰。启动方式无一键启动包。需通过命令行按步骤执行数据准备、训练和推理脚本。主要产出1. 可训练的Transformer模型代码。2. 训练好的模型检查点checkpoint。3. 文本生成推理能力。是否支持API原生不支持。但训练出的模型可被封装成简易的本地API服务需自行实现。是否支持批量任务训练和推理均支持批量batch处理这是深度学习框架的基础能力。适合场景1.深度学习/LLM教学与自学深入理解Transformer和LLM训练全流程。2.模型研究与原型验证快速实现和验证新的模型架构改进点子。3.定制化小模型构建基于特定领域文本训练一个专属的小型语言模型。2. 适用场景与使用边界这个项目最适合以下几类人学习者与教育者计算机科学、人工智能专业的学生和老师希望通过实践掌握LLM核心原理。进阶开发者已经会调用Hugging Facetransformers库但想了解背后实现细节的工程师。研究原型开发者需要快速搭建一个干净的、可修改的Transformer代码基底用于算法实验。它能解决什么问题破除黑盒亲手实现注意力机制、前馈网络、层归一化等组件彻底理解模型如何工作。掌握全流程体验从原始文本数据到生成式AI的完整Pipeline包括tokenization、dataloader、loss计算、梯度下降、模型保存与加载。获得可修改的代码课程提供的代码通常结构清晰、注释完整是极佳的学习和二次开发起点。它不适合什么场景追求即开即用的对话AI这不是ChatGPT或Claude。你需要自己准备数据、训练模型且最终模型的对话能力与亿级参数的大模型有数量级差距。缺乏编程基础项目需要你熟悉Python、PyTorch和基本的命令行操作。追求极致性能教学代码优先保证可读性和正确性在计算效率和内存优化上可能不及生产级框架如DeepSpeed, Megatron-LM。合规与伦理边界数据合规训练所使用的文本数据必须确保拥有合法版权或属于开源许可范围。严禁使用未授权的隐私数据、受版权保护的书籍或非法爬取的内容。生成内容责任模型可能生成不合理、有偏见或无意义的内容。这属于当前语言模型的固有局限性在学术研究和学习环境中需客观认识。任何基于此模型的衍生应用开发者需对生成内容负责。学术诚信该项目代码可用于学习但在课程作业或学术研究中应遵守相关的引用和诚信规范。3. 环境准备与前置条件在开始构建之前请确保你的开发环境满足以下要求。一个稳定、版本匹配的环境能避免大部分依赖问题。操作系统推荐Linux (Ubuntu 20.04/22.04 LTS) 或 Windows 10/11 with WSL2。Linux环境在深度学习开发中兼容性最好。macOS支持但仅限CPU或Apple Silicon GPU (MPS) 训练性能有限。Python环境Python版本3.8, 3.9 或 3.10。建议使用conda或venv创建独立的虚拟环境。包管理工具pip。深度学习框架PyTorch 1.12.0。必须安装与你的CUDA版本匹配的PyTorch。安装命令示例CUDA 11.8# 使用conda conda install pytorch torchvision torchaudio pytorch-cuda11.8 -c pytorch -c nvidia # 或使用pip pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118验证安装import torch print(torch.__version__) # 查看PyTorch版本 print(torch.cuda.is_available()) # 查看CUDA是否可用 print(torch.cuda.get_device_name(0)) # 查看GPU型号其他关键依赖项目通常会需要以下库可以在克隆代码后根据requirements.txt安装。# 假设已进入项目目录 pip install -r requirements.txt典型的requirements.txt可能包含transformers4.30.0 # 用于tokenizer和数据集加载 datasets2.12.0 # 用于方便地加载标准数据集 tensorboard # 用于训练可视化 tqdm # 用于显示进度条 numpy scipy硬件检查清单GPU确认有一张NVIDIA GPU并安装了正确版本的驱动和CUDA Toolkit如11.8。使用nvidia-smi命令验证。显存至少8GB。训练微型模型或调试时4GB也可能勉强启动但极易溢出。内存建议16GB以上系统内存用于数据加载和预处理。磁盘预留10-20GB空间用于存放代码、数据集和模型检查点。4. 安装部署与启动方式本项目没有一键启动的WebUI其“启动”意味着按照构建流程依次执行各个阶段的脚本。第一步获取代码# 克隆项目仓库假设仓库地址为示例请替换为实际地址 git clone https://github.com/stanford-cs336/2026-llm-from-scratch.git cd 2026-llm-from-scratch第二步安装依赖# 创建并激活虚拟环境以conda为例 conda create -n cs336 python3.9 conda activate cs336 # 安装项目依赖 pip install -r requirements.txt第三步理解项目结构一个典型的CS336项目目录可能如下2026-llm-from-scratch/ ├── data/ # 数据存放目录需自行下载或准备 ├── src/ # 源代码目录 │ ├── model.py # Transformer模型定义 │ ├── trainer.py # 训练循环逻辑 │ ├── dataset.py # 数据加载与处理 │ ├── tokenizer.py # 分词器实现或封装 │ └── config.py # 模型与训练超参数配置 ├── scripts/ # 执行脚本目录 │ ├── prepare_data.py # 数据预处理脚本 │ ├── train.py # 主训练脚本 │ └── generate.py # 文本生成推理脚本 ├── requirements.txt ├── README.md └── ... (其他配置文件)第四步准备数据项目通常使用小型公开数据集进行教学如WikiText-2。# 运行数据准备脚本 python scripts/prepare_data.py --dataset wikitext-2 --output_dir ./data/wikitext2这个脚本会自动从Hugging Face Datasets下载数据并进行分词、划分训练/验证集等预处理保存为PyTorch可读的格式。第五步启动训练这是核心步骤。你需要通过命令行指定配置。# 一个基础的训练启动命令示例 python scripts/train.py \ --config_path ./configs/base_model.json \ # 模型结构配置 --data_dir ./data/wikitext2 \ # 预处理后的数据路径 --output_dir ./checkpoints \ # 模型检查点保存路径 --batch_size 32 \ # 根据显存调整 --gradient_accumulation_steps 2 \ # 模拟更大batch size --num_epochs 10 \ # 训练轮数 --learning_rate 5e-4 \ --log_dir ./logs \ # TensorBoard日志目录 --save_steps 1000 # 每1000步保存一次模型训练开始后控制台会输出损失loss和评估指标如困惑度perplexity。你可以同时启动TensorBoard来可视化训练过程tensorboard --logdir ./logs然后在浏览器中打开http://localhost:6006查看图表。第六步文本生成测试训练完成后使用生成脚本加载检查点进行测试。python scripts/generate.py \ --model_path ./checkpoints/checkpoint-5000 \ # 加载指定检查点 --tokenizer_path ./data/wikitext2 \ # 分词器路径 --prompt The future of artificial intelligence \ --max_length 50 \ # 生成文本最大长度 --temperature 0.8 \ # 采样温度控制随机性 --top_k 50 # Top-k采样参数如果一切顺利你将看到模型续写的文本。5. 功能测试与效果验证构建LLM的“功能测试”不同于应用测试其核心是验证模型构建的每个环节是否按预期工作。我们将分阶段进行验证。5.1 数据流水线验证测试目的确认数据能被正确加载、分词并转换为模型可接受的输入张量。操作步骤编写一个简单的测试脚本或直接在Python交互环境中执行。# test_data_pipeline.py from src.dataset import create_dataloaders from src.tokenizer import SimpleTokenizer tokenizer SimpleTokenizer.from_file(./data/wikitext2/vocab.json) train_loader, val_loader create_dataloaders( data_dir./data/wikitext2, tokenizertokenizer, batch_size4, max_length128 ) # 取一个batch看看 for batch in train_loader: input_ids, labels batch[input_ids], batch[labels] print(fBatch shape: {input_ids.shape}) # 应为 [batch_size, max_length] print(fSample tokens: {input_ids[0][:10]}) print(fDecoded text: {tokenizer.decode(input_ids[0][:10].tolist())}) break预期结果成功创建train_loader和val_loader无报错。打印出的input_ids是一个整数张量。decode方法能将input_ids转换回可读的文本片段。失败排查FileNotFoundError检查数据路径是否正确预处理脚本是否已成功运行。分词错误检查tokenizer是否与预处理时使用的分词器一致。5.2 模型前向传播验证测试目的确保模型架构正确能够接受输入并产生输出且输出维度符合预期。操作步骤# test_model_forward.py import torch from src.model import TransformerLM from src.config import ModelConfig # 加载一个小配置进行测试 config ModelConfig(vocab_size50000, hidden_size768, num_layers6, num_heads12) model TransformerLM(config) model.eval() # 切换到评估模式 # 创建随机输入模拟一个batch batch_size, seq_len 4, 128 dummy_input torch.randint(0, config.vocab_size, (batch_size, seq_len)) # 前向传播 with torch.no_grad(): logits, loss model(dummy_input, labelsdummy_input) # 这里labels仅用于测试loss计算 print(fInput shape: {dummy_input.shape}) print(fOutput logits shape: {logits.shape}) # 应为 [batch_size, seq_len, vocab_size] print(fLoss value: {loss.item()})预期结果代码无错误执行。logits的形状为[4, 128, 50000]。loss是一个标量数值。失败排查维度不匹配错误检查ModelConfig参数与model.py中的实现是否一致特别是注意力头的维度hidden_size必须能被num_heads整除。CUDA内存不足如果模型放在GPU上尝试减小batch_size或seq_len。5.3 单步训练验证测试目的验证完整的训练循环前向、损失计算、反向传播、优化器更新能否正常执行一步。操作步骤# test_training_step.py from src.trainer import Trainer, TrainingConfig from src.model import TransformerLM from src.dataset import create_dataloaders # ... 初始化model, dataloader, optimizer, scheduler ... trainer Trainer( modelmodel, train_loadertrain_loader, val_loaderval_loader, configtraining_config ) # 执行一个训练epoch或几步 trainer.train_one_epoch()预期结果训练开始控制台打印类似Epoch 1, Step 100, Loss: 5.4321的日志。TensorBoard中能看到损失曲线开始下降。检查点目录下生成了模型保存文件如checkpoint-1000/pytorch_model.bin。失败排查Loss为NaN检查学习率是否过高数据中是否有异常值模型初始化是否有问题。显存爆炸OOM减小config.py中的batch_size或启用梯度检查点gradient checkpointing。5.4 文本生成质量验证测试目的这是最终验收看模型是否学到了语言规律。操作步骤使用第4步中的generate.py脚本。输入示例Prompt:In a surprising turn of events, Prompt:The key to understanding machine learning is 判断成功的标准语法基本正确生成的文本在单词拼写、基本语法结构上没有大量错误。语义局部连贯生成的句子在短距离内几个词到一句话是通顺、合理的。符合提示主题生成的内容与提示词在主题上相关。注意对于一个小规模教学模型不要期望它有长篇大论的逻辑性或事实准确性。只要它能生成看起来像人类语言的、与提示相关的文本构建就是成功的。困惑度Perplexity在验证集上的持续下降是更客观的指标。6. 接口API与批量任务原生的CS336项目不提供现成的REST API。但将训练好的模型封装成服务是自然且有用的下一步。这里提供一个基于Flask的简易API实现示例以及批量生成文本的思路。6.1 简易模型API服务封装创建一个新的文件app.py# app.py - 一个简单的模型推理API服务 import torch from flask import Flask, request, jsonify from src.model import TransformerLM from src.tokenizer import SimpleTokenizer from src.config import ModelConfig import argparse app Flask(__name__) model None tokenizer None device torch.device(cuda if torch.cuda.is_available() else cpu) def load_model(model_path, config_path, tokenizer_path): 加载模型和分词器 global model, tokenizer config ModelConfig.from_json_file(config_path) model TransformerLM(config) state_dict torch.load(model_path, map_locationdevice) model.load_state_dict(state_dict) model.to(device) model.eval() tokenizer SimpleTokenizer.from_file(tokenizer_path) print(fModel and tokenizer loaded on {device}.) app.route(/generate, methods[POST]) def generate_text(): 文本生成接口 data request.json prompt data.get(prompt, ) max_length data.get(max_length, 50) temperature data.get(temperature, 1.0) top_k data.get(top_k, 50) if not prompt: return jsonify({error: Prompt is required}), 400 # 编码输入 input_ids tokenizer.encode(prompt) input_tensor torch.tensor([input_ids], devicedevice) # 生成 with torch.no_grad(): generated_ids model.generate( input_tensor, max_lengthmax_length, temperaturetemperature, top_ktop_k ) # 解码输出 generated_text tokenizer.decode(generated_ids[0].tolist()) return jsonify({generated_text: generated_text}) if __name__ __main__: parser argparse.ArgumentParser() parser.add_argument(--model_path, requiredTrue) parser.add_argument(--config_path, requiredTrue) parser.add_argument(--tokenizer_path, requiredTrue) parser.add_argument(--port, typeint, default5000) args parser.parse_args() load_model(args.model_path, args.config_path, args.tokenizer_path) app.run(host0.0.0.0, portargs.port, debugFalse) # 生产环境应关闭debug启动API服务python app.py \ --model_path ./checkpoints/checkpoint-10000/pytorch_model.bin \ --config_path ./configs/base_model.json \ --tokenizer_path ./data/wikitext2 \ --port 7860调用API示例使用curlcurl -X POST http://127.0.0.1:7860/generate \ -H Content-Type: application/json \ -d { prompt: The weather today is, max_length: 30, temperature: 0.9 }6.2 批量文本生成任务对于需要处理大量提示词的场景可以编写一个批量脚本。# batch_generate.py import json import torch from tqdm import tqdm from src.model import TransformerLM from src.tokenizer import SimpleTokenizer from src.config import ModelConfig def batch_generate(prompts_list, model, tokenizer, max_length50, batch_size4): 批量生成文本 results [] model.eval() device next(model.parameters()).device for i in tqdm(range(0, len(prompts_list), batch_size)): batch_prompts prompts_list[i:ibatch_size] # 编码批次内所有提示词并处理成长度一致的张量需要padding batch_inputs [] for prompt in batch_prompts: ids tokenizer.encode(prompt) batch_inputs.append(torch.tensor(ids)) # 简单padding实际生产环境应用更健壮的collate_fn input_tensor torch.nn.utils.rnn.pad_sequence(batch_inputs, batch_firstTrue, padding_valuetokenizer.pad_token_id).to(device) with torch.no_grad(): batch_outputs model.generate(input_tensor, max_lengthmax_length) # 解码 for j, output_ids in enumerate(batch_outputs): generated_text tokenizer.decode(output_ids.tolist()) results.append({ prompt: batch_prompts[j], generated: generated_text }) return results if __name__ __main__: # 加载模型和分词器代码同上略 # ... # 从文件读取提示词列表 with open(./prompts.txt, r, encodingutf-8) as f: prompts [line.strip() for line in f if line.strip()] # 执行批量生成 outputs batch_generate(prompts, model, tokenizer, max_length100, batch_size8) # 保存结果 with open(./generation_results.jsonl, w, encodingutf-8) as f: for item in outputs: f.write(json.dumps(item, ensure_asciiFalse) \n) print(f批量生成完成共处理{len(outputs)}条提示词。)7. 资源占用与性能观察在本地构建和训练LLM监控资源占用至关重要它直接决定了你能训练多大的模型以及训练速度。1. 显存占用观察显存是训练中最紧张的资源。主要被以下部分占用模型参数与模型大小参数量成正比。一个hidden_size768, num_layers6的模型参数量大约在1亿左右。优化器状态Adam优化器会为每个参数保存动量和方差通常占用2倍于参数的显存混合精度训练可减少。激活值Activations前向传播过程中产生的中间变量在反向传播时需要用到。其占用与batch_size * sequence_length * hidden_size相关且随着模型层数加深而累积。梯度与模型参数量相当。使用nvidia-smi动态监控# 在训练过程中另开一个终端窗口定期执行 watch -n 1 nvidia-smi重点关注Volatile GPU-UtilGPU利用率和GPU Memory Usage显存使用量。如果显存接近满载训练可能会因OOM而崩溃。降低显存占用的常用技巧减小batch_size最直接有效的方法。减小max_sequence_length在数据预处理时截断过长的文本。使用梯度累积Gradient Accumulation通过--gradient_accumulation_steps N模拟更大的batch size但实际前向和反向传播时只用较小的batch显存占用按小batch来算。启用梯度检查点Gradient Checkpointing以时间换空间只保存部分层的激活需要时重新计算。在model.py的Transformer层中可以使用torch.utils.checkpoint。使用混合精度训练AMP使用torch.cuda.amp让部分计算使用float16减少显存占用并可能加速。2. 训练速度与吞吐量监控指标记录每秒处理的样本数samples/sec或令牌数tokens/sec。性能瓶颈使用nvtop或py-spy等工具分析。瓶颈可能在数据加载I/O、前向计算、还是All-Reduce通信多GPU时。优化建议使用DataLoader的num_workers参数进行多进程数据加载避免GPU等待数据。使用pin_memoryTrue加速数据从CPU到GPU的传输。确保数据预处理足够快避免在训练循环中进行复杂的实时处理。3. 模型评估与验证验证集困惑度Perplexity, PPL这是衡量语言模型好坏的核心指标。PPL越低越好。确保在训练过程中定期在验证集上计算PPL以监控模型是否过拟合。生成文本质量定期如每5000步用固定的prompt让模型生成文本人工观察其流畅度和相关性的变化趋势。8. 常见问题与排查方法在构建过程中你几乎一定会遇到各种问题。下表整理了常见问题及其排查思路。问题现象可能原因排查方式解决方案ImportError或ModuleNotFoundError依赖未安装或虚拟环境未激活。1. 检查当前Python环境 (which python)。2. 检查包是否已安装 (pip list | grep package_name)。1. 激活正确的conda/venv环境。2. 运行pip install -r requirements.txt。CUDA out of memory (OOM)显存不足。1. 使用nvidia-smi查看显存占用。2. 检查代码中的batch_size和max_length。1.立即降低batch_size。2. 减小模型尺寸或序列长度。3. 启用梯度累积和混合精度训练。4. 使用梯度检查点。Loss 值为 NaN 或无限大训练不稳定通常由过大学习率、梯度爆炸或数据问题引起。1. 检查初始的几个训练step的loss。2. 检查梯度范数 (torch.nn.utils.clip_grad_norm_)。1.大幅降低学习率。2. 添加梯度裁剪 (gradient clipping)。3. 检查数据中是否有非文本字符或空样本。4. 检查模型初始化权重。训练速度极慢1. 数据加载是瓶颈。2. 模型在CPU上运行。3. GPU利用率低。1. 观察GPU利用率 (nvidia-smi)。2. 检查数据加载代码是否有同步操作。1. 增加DataLoader的num_workers。2. 确认model.to(device)已将模型移至GPU。3. 使用更高效的数据格式如预处理的二进制文件。生成的文本全是乱码或重复词1. 模型训练不充分。2. 推理参数如temperature设置不当。3. 分词器编码/解码错误。1. 检查训练loss是否还在下降。2. 尝试不同的temperature(如0.7-1.0) 和top_k/top_p。3. 用简单prompt测试分词器往返。1. 继续训练更多步数。2. 调整推理采样策略。3. 验证分词器decode(encode(“test”)) “test”。无法加载预训练检查点模型结构定义与保存的state_dict不匹配。打印当前模型参数名和检查点中的参数名进行对比。1. 确保加载检查点时使用的ModelConfig与训练时完全一致。2. 如果只是微调可能需要忽略不匹配的键 (strictFalse)。端口被占用API服务指定端口已被其他进程使用。使用lsof -i:端口号或netstat -tulnp | grep 端口号查看。1. 终止占用端口的进程。2. 在启动命令中更换一个端口号。9. 最佳实践与使用建议为了让你的构建和学习过程更顺畅这里有一些从实践中总结的建议。1. 从小开始迭代验证微型模型第一次运行时构建一个极小的模型例如hidden_size128, num_layers2在非常小的数据子集上跑通整个流程。这能快速验证代码正确性且几乎不会遇到显存问题。逐步放大确认流程无误后再逐步增加模型大小、数据量和训练步数。2. 代码与配置管理版本控制使用Git管理你的代码、配置文件和关键脚本。每次重要的架构或参数变更都进行提交。配置化将所有超参数模型尺寸、学习率、batch size等集中放在一个配置文件如config.yaml或config.json中避免硬编码在代码里。实验记录为每次训练运行创建独立的输出目录保存其配置文件、日志和模型检查点。可以使用工具如Weights Biases或MLflow进行更系统的实验跟踪。3. 数据预处理是关键质量检查在训练前务必检查预处理后的数据。随机查看一些样本确保分词结果合理没有过多的[UNK]标记。数据集划分严格区分训练集、验证集和测试集避免数据泄露。重复数据删除如果使用网络爬取数据注意去重防止模型过度记忆。4. 训练过程监控定期保存设置合理的save_steps或save_epochs定期保存检查点。同时保存优化器状态以便从中断处恢复训练。验证集评估不要只看训练损失。必须定期在验证集上计算困惑度PPL这是判断模型是否过拟合、何时早停early stopping的核心依据。可视化坚持使用TensorBoard或类似工具将训练损失、验证PPL、学习率曲线等可视化。5. 推理与部署模型导出训练完成后考虑将模型导出为TorchScript或ONNX格式以便在不同环境中部署。服务化如第6节所示将模型封装成API服务时务必注意线程安全和性能。生产环境应使用更高效的服务器框架如FastAPI和异步处理。安全与合规如果计划开放API给他人使用必须设置速率限制、输入过滤并对生成内容进行必要的安全审查。10. 总结与下一步通过这个“从头构建大语言模型”的项目你获得的最有价值的东西不是另一个聊天机器人而是对Transformer架构和LLM训练生命周期的深刻理解。你亲手实现了数据流、模型层、损失函数和优化循环这种经验是单纯调用API无法比拟的。最值得尝试的下一步修改模型架构尝试在src/model.py中添加或修改模块例如实现不同的位置编码如RoPE、尝试不同的注意力机制如滑动窗口注意力、或增加MoEMixture of Experts层观察对性能和效果的影响。在自己的数据上训练找一个你感兴趣的垂直领域如科技新闻、古典诗词、代码注释收集一些文本数据用这个流程训练一个领域小模型体验“定制化”的过程。集成到现有生态将你训练好的模型用Hugging Facetransformers库的格式进行封装使其能够通过AutoModelForCausalLM接口加载从而无缝接入LangChain、LlamaIndex等更上层的应用框架。探索高效训练技术尝试集成DeepSpeed或FSDPFully Sharded Data Parallel来训练更大的模型或者使用LoRA等参数高效微调技术在有限资源下适配新任务。构建过程中最容易踩的坑往往不是算法本身而是环境配置、数据管道和资源管理。因此养成系统性排查问题的习惯如本文第8节所述善用日志和监控工具比盲目调整超参数更重要。这个项目代码库是你探索LLM世界的绝佳起点。建议收藏本文的实践指南和排查清单在遇到问题时回来查阅。当你成功运行起第一个自己构建的模型并看到它生成文本时那份成就感将是驱动你继续深入这个领域的最佳燃料。现在就打开终端开始你的构建之旅吧。
返回列表