赞
踩
目录
本文免费发表于我的微信公众号:“AI与编程之窗”,请关注我的公众号后免费阅读,搜索“AI与编程之窗”或扫描以下二维码添加关注。
Llama 3.1 是 Meta 公司于 2024 年 7 月 23 日发布的最新开源大语言模型。这一版本在先前 Llama 3 的基础上进行了增强,支持多模态处理,并具有多种参数规模,包括 8B、70B 和 405B 参数。Llama 3.1 经过大规模文本数据的预训练,并结合了超过 1000 万个人工标注的示例,显著提高了模型的性能和适应性。Llama 3.1 尤其在多语言对话和编码能力方面表现出色,是目前 Meta 最先进的大语言模型之一。
Meta公司开源了Llama 3.1大模型,任何人都可以下载并用于二次开发。本教程的目的是帮助用户从头开始构建自己的Llama 3.1模型,包括在本地搭建自己的大模型和对大模型进行微调。通过详细的步骤讲解,我们将引导您完成Llama 3.1模型的安装、配置、训练以及微调,帮助您充分利用这个先进的开源大语言模型。
在开始之前,确保您的系统满足以下要求:
首先,安装所需的Python库:
pip install torch matplotlib tiktoken
从Meta的官方网站下载Llama 3.1模型权重和分词器文件。假设下载链接如下:
https://llama.meta.com/llama3.1/model.pth
https://llama.meta.com/llama3.1/tokenizer.model
下载后,将它们保存在您的工作目录中。
使用 tiktoken 库加载和使用 Llama 3.1 的分词器。以下是下载分词器模型并进行初始化的详细步骤。
首先,确保您已经安装了 tiktoken 库。如果没有安装,请使用以下命令进行安装:
pip install tiktoken
从Meta的官方网站下载Llama 3.1的分词器模型。假设下载链接为:
https://llama.meta.com/llama3.1/tokenizer.model
将下载的文件保存到您的工作目录中,例如 path/to/tokenizer.model
。
接下来,使用 tiktoken 库加载并初始化分词器模型。以下是示例代码:
- from pathlib import Path
- import tiktoken
-
- # 指定分词器模型的路径
- tokenizer_path = "path/to/tokenizer.model"
-
- # 特殊令牌,可以根据需要添加更多的特殊令牌
- special_tokens = ["<|startoftext|>", "<|endoftext|>"]
-
- # 加载分词器模型
- mergeable_ranks = tiktoken.load(tokenizer_path)
-
- # 初始化分词器
- tokenizer = tiktoken.Encoding(
- name=Path(tokenizer_path).name,
- mergeable_ranks=mergeable_ranks,
- special_tokens={token: len(mergeable_ranks) + i for i, token in enumerate(special_tokens)},
- )
-
- # 测试分词器
- encoded = tokenizer.encode("hello world!")
- decoded = tokenizer.decode(encoded)
-
- print("Encoded:", encoded)
- print("Decoded:", decoded)

tokenizer_path
。tiktoken.load
方法加载分词器模型。tiktoken.Encoding
初始化分词器,将模型名称、可合并的词汇表(mergeable_ranks)和特殊令牌传递给它。encode
方法将文本转换为 token,并使用 decode
方法将 token 转换回文本,以验证分词器的工作是否正常。从模型文件中读取参数和权重是构建 Llama 3.1 模型的关键步骤之一。这部分将详细介绍如何读取模型文件中的参数和权重,并进行初始化设置。
确保安装了 PyTorch 库,因为我们将使用 PyTorch 来加载模型文件。
pip install torch
首先,我们需要从模型文件中加载模型权重和配置参数。假设我们已经下载了模型权重文件 model.pth
和配置文件 params.json
。
- import torch
- import json
-
- # 加载模型权重
- model_path = "path/to/model.pth"
- model = torch.load(model_path)
-
- # 打印模型的部分键以验证加载
- print(json.dumps(list(model.keys())[:20], indent=4))
-
- # 加载配置参数
- config_path = "path/to/params.json"
- with open(config_path, "r") as f:
- config = json.load(f)
-
- # 提取配置参数
- dim = config["dim"]
- n_layers = config["n_layers"]
- n_heads = config["n_heads"]
- n_kv_heads = config["n_kv_heads"]
- vocab_size = config["vocab_size"]
- multiple_of = config["multiple_of"]
- ffn_dim_multiplier = config["ffn_dim_multiplier"]
- norm_eps = config["norm_eps"]
- rope_theta = torch.tensor(config["rope_theta"])
-
- # 打印配置参数以验证加载
- print(f"Model Dimension: {dim}")
- print(f"Number of Layers: {n_layers}")
- print(f"Number of Heads: {n_heads}")
- print(f"Vocabulary Size: {vocab_size}")

torch.load
方法加载模型文件 model.pth
。加载后,可以通过打印模型的键来验证权重是否正确加载。params.json
,该文件包含了模型的超参数和其他设置。在构建语言模型时,首先需要将输入的自然语言文本转换为模型所需的 tokens。Llama 3.1 使用的分词器可以将文本转换为一系列 tokens,这些 tokens 是模型可以理解和处理的基本单元。
以下是将输入文本转换为模型所需 tokens 的详细步骤:
以下是具体的代码实现:
- # 定义输入文本
- prompt = "the answer to the ultimate question of life, the universe, and everything is "
-
- # 使用分词器将文本编码为 tokens
- tokens = tokenizer.encode(prompt)
-
- # 打印编码后的 tokens
- print(f"Encoded tokens: {tokens}")
-
- # 添加特殊 tokens
- # 假设 128000 是模型要求的特殊 token
- tokens = [128000] + tokens
-
- # 将 tokens 转换为 PyTorch 张量
- tokens_tensor = torch.tensor(tokens)
-
- # 打印转换后的张量
- print(f"Tokens Tensor: {tokens_tensor}")

prompt
是我们要转换的输入文本。tokenizer.encode(prompt)
方法将输入文本转换为 tokens。tokenizer
是之前加载并初始化的分词器对象。torch.tensor(tokens)
方法将 tokens 序列转换为 PyTorch 张量。这一步是为了便于后续的模型处理,因为 PyTorch 模型通常处理张量数据。将 tokens 转换为 embeddings 是深度学习模型处理文本数据的重要步骤。Embedding 是一种将离散的 tokens 转换为连续向量表示的方法,使模型能够处理和理解文本数据。
确保您已经安装并导入了必要的库:
- import torch
- import torch.nn as nn
以下是将 tokens 转换为 embeddings 的具体代码实现:
- # 定义模型参数
- vocab_size = 50257 # 假设词汇表大小为 50257
- dim = 768 # 假设每个 token 的 embedding 维度为 768
-
- # 初始化 Embedding 层
- embedding_layer = nn.Embedding(vocab_size, dim)
-
- # 加载预训练的 Embedding 权重
- embedding_layer.weight.data.copy_(model["tok_embeddings.weight"])
-
- # 将 tokens 转换为 embeddings
- token_embeddings_unnormalized = embedding_layer(tokens_tensor).to(torch.bfloat16)
-
- # 打印 Embeddings 的形状
- print(f"Token Embeddings Shape: {token_embeddings_unnormalized.shape}")
vocab_size
) 和 embedding 向量的维度 (dim
)。nn.Embedding
初始化一个 Embedding 层。这个层将词汇表中的每个 token 映射到一个维度为 dim
的向量。model["tok_embeddings.weight"]
包含了预训练的 embedding 权重,通过 embedding_layer.weight.data.copy_
方法将这些权重复制到初始化的 Embedding 层中。embedding_layer
将 tokens 转换为 embeddings。tokens_tensor
是之前步骤中转换的 tokens 张量。.to(torch.bfloat16)
将 embeddings 转换为 bfloat16
数据类型,以适应后续的模型处理需求。print
打印 embeddings 的形状,以验证转换是否正确。输出的形状应该是 (序列长度, embedding 维度)
。对 embeddings 进行归一化处理是确保模型稳定性和性能的重要步骤。归一化有助于避免数值不稳定,确保各层之间的数值范围一致,从而提升训练效率和模型性能。
在本教程中,我们使用均方根归一化(RMS Normalization)来处理 embeddings。均方根归一化是一种对向量进行归一化的方法,它通过计算向量的均方根(RMS)并使用该值对向量进行缩放。
均方根的计算方法如下:
归一化后的向量为:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。