02极简LLM逻辑与PyTorch快速入门

news2024/11/20 7:05:13

文章目录

  • 02极简LLM逻辑与PyTorch快速入门
    • 极简LLM逻辑
    • PyTorch环境安装(重要,不难)
    • PyTorch 主要概念
      • Tensors张量
        • 张量常见的形式:scalar、vector、matrix、n-dimensinal
        • 张量初始化
        • 张量参数:shape、datatype、device
        • 张量运算
      • Datasets and DataLoaders 数据集与数据加载
      • Transforms 转换
      • Build Model 创建模型
      • Automatic Differentiation 自动微分
      • Optimization Loop 优化循环
      • 保存、加载、使用模型

02极简LLM逻辑与PyTorch快速入门

极简LLM逻辑

提供一段伪代码,说明“对话”的基本逻辑:输入、输出。
不考虑机器学习、深度学习之类的技术,也不考虑结果是否合理、准确,仅仅为了说明LLM基本逻辑。

if __name__ == "__main__":
    aq = InputAndAnalysisQuestion()
    ga = Get_answer()
    while True:
        question = input('请输入:') 
        index, params = aq.query_question(question)
        answers = ga.get_data(index, params)
        print('答案:')
        for ans in answers:
            print(ans[0])

按照俗话解释以上伪代码流程:

  • 1、获得对话输入。根据输入内容,进行查询检索;
  • 2、上一步查询检索返回索引号、参数列表数据;
  • 3、根据索引号、参数列表计算回答内容;
  • 4、输出打印。

PyTorch环境安装(重要,不难)

在安装PyTorch前,请先确保python、cuda的版本。具体的版本对应关系参考pytorch官网给出的说明。

官网版本对应:https://pytorch.org/get-started/locally/

  • 例如:
软件版本
python>=3.8
cuda11.8
pytorch2.2.1

在这里插入图片描述

  • 注意,上面描述的是pytorch的GPU环境的安装。pytorch也支持无GPU的CPU环境安装,具体步骤请自行查阅。但是还是建议上GPU吧,GPU是绕不过去的。

  • PyTorch历史版本,用于查阅与python、cuda的版本对照
    地址:https://pytorch.org/get-started/previous-versions/
    例如:

# CUDA 11.8
conda install pytorch==2.2.0 torchvision==0.17.0 torchaudio==2.2.0 pytorch-cuda=11.8 -c pytorch -c nvidia
# CUDA 12.1
conda install pytorch==2.2.0 torchvision==0.17.0 torchaudio==2.2.0 pytorch-cuda=12.1 -c pytorch -c nvidia
# CPU Only
conda install pytorch==2.2.0 torchvision==0.17.0 torchaudio==2.2.0 cpuonly -c pytorch
  • torch版本查询
import torch
torch.__version__
  • GPU/cuda环境判断与启用
# We move our tensor to the GPU if available
if torch.cuda.is_available():
  tensor = tensor.to('cuda')
  print(f"Device tensor is stored on: {tensor.device}")

PyTorch 主要概念

Tensors张量

张量是一种特殊的数据结构,与数组和矩阵非常相似。

在PyTorch中,使用张量来编码模型的输入、输出以及模型参数。张量类似于NumPy中的ndarrays(n维数组),但不同之处在于张量可以在GPU或其他硬件加速器上运行。

张量和NumPy数组经常可以共享相同的底层内存,从而消除了数据复制的需求。张量还针对自动微分进行了优化(在Autograd部分)

import torch
import numpy as np
张量常见的形式:scalar、vector、matrix、n-dimensinal
  • 0:scalar
  • 1:vector
  • 2:matrix
  • 3:n-dimensional
import torch
from torch import tensor

#scalar通常是一个数值
x = tensor(42.)

tensor(42.)

x.dim()

tensor(84.)

x.item()

#vector, 例如: [-5., 2., 0.],在深度学习中通常指特征,例如词向量特征
v = tensor( [1.5, -0.5, 3.0])

v.dim()

v.size()
torch.Size( [3] )

#Matrix, 一般计算的都是矩阵,通常都是多维的
M = tensor( [[1., 2.], [3., 4.]] )

M.matmul(M)

tensor([1., 0.]).matmul(M)


张量初始化
  • 数据直接读取
data = [[1, 2],[3, 4]]
x_data = torch.tensor(data)
  • 读取NumPy array
np_array = np.array(data)
x_np = torch.from_numpy(np_array)
  • 从另一个张量
x_ones = torch.ones_like(x_data) # retains the properties of x_data
print(f"Ones Tensor: \n {x_ones} \n")

x_rand = torch.rand_like(x_data, dtype=torch.float) # overrides the datatype of x_data
print(f"Random Tensor: \n {x_rand} \n")
  • 随机变量
shape = (2,3,)
rand_tensor = torch.rand(shape)
ones_tensor = torch.ones(shape)
zeros_tensor = torch.zeros(shape)

print(f"Random Tensor: \n {rand_tensor} \n")
print(f"Ones Tensor: \n {ones_tensor} \n")
print(f"Zeros Tensor: \n {zeros_tensor}")
张量参数:shape、datatype、device
tensor = torch.rand(3,4)

print(f"Shape of tensor: {tensor.shape}")
print(f"Datatype of tensor: {tensor.dtype}")
print(f"Device tensor is stored on: {tensor.device}")
张量运算

超过100种张量操作,包括算术运算、线性代数、矩阵操作(转置、索引、切片)、采样以及其他更多操作。

每一种操作都可以在GPU上运行(通常速度会比在CPU上更快)。

默认情况下,张量是在CPU上创建的。需要通过.to()方法显式地将张量移动到GPU(在确认GPU可用之后)。请注意,跨设备复制大型张量在时间和内存方面可能会产生较高的开销!

  • 索引与切片(类似于numpy)
tensor = torch.ones(4, 4)
print(f"First row: {tensor[0]}")
print(f"First column: {tensor[:, 0]}")
print(f"Last column: {tensor[..., -1]}")
tensor[:,1] = 0
print(tensor)
  • 连接张量 torch.cat
t1 = torch.cat([tensor, tensor, tensor], dim=1)
print(t1)
  • 算术运算
# This computes the matrix multiplication between two tensors. y1, y2, y3 will have the same value
# ``tensor.T`` returns the transpose of a tensor
y1 = tensor @ tensor.T
y2 = tensor.matmul(tensor.T)

y3 = torch.rand_like(y1)
torch.matmul(tensor, tensor.T, out=y3)


# This computes the element-wise product. z1, z2, z3 will have the same value
z1 = tensor * tensor
z2 = tensor.mul(tensor)

z3 = torch.rand_like(tensor)
torch.mul(tensor, tensor, out=z3)
  • 单元素张量
    如果有一个单元素张量,例如通过聚合一个张量的所有值为一个值,可以使用item()方法将其转换为Python数值类型
agg = tensor.sum()
agg_item = agg.item()
print(agg_item, type(agg_item))
  • 原地操作(In-place operations)
    把结果直接存入操作数本身的运算称为原地操作。这类操作的名称后面通常会带有 _ 后缀。例如:x.copy_(y)、x.t_() 等操作会直接修改变量x自身的内容。
print(f"{tensor} \n")
tensor.add_(5)
print(tensor)

Datasets and DataLoaders 数据集与数据加载

处理数据样本的代码可能会变得混乱且难以维护;为了提高可读性和模块化程度,理想情况下希望数据集代码与模型训练代码解耦。

PyTorch提供了两个数据处理基本组件:

torch.utils.data.DataLoader 和 torch.utils.data.Dataset,既可使用预加载的数据集,也能使用自定义数据。

Dataset 类用于存储样本及其对应的标签,而 DataLoader 则将一个可迭代对象包装在 Dataset 外部,以便于轻松访问样本。

PyTorch领域库提供了一系列预加载的数据集(如FashionMNIST等),这些数据集都是torch.utils.data.Dataset的子类,并实现了针对特定数据的特定函数。可以利用它们快速原型化和基准测试您的模型。

  • 数据加载
    Fashion-MNIST是一个由Zalando提供的商品图片数据集,包含60,000个训练样本和10,000个测试样本。每个样本由一个28×28像素的灰度图像以及来自10种类别的关联标签组成。
import torch
from torch.utils.data import Dataset
from torchvision import datasets
from torchvision.transforms import ToTensor
import matplotlib.pyplot as plt


training_data = datasets.FashionMNIST(
    root="data",
    train=True,
    download=True,
    transform=ToTensor()
)

test_data = datasets.FashionMNIST(
    root="data",
    train=False,
    download=True,
    transform=ToTensor()
)
  • 迭代与可视化数据集
labels_map = {
    0: "T-Shirt",
    1: "Trouser",
    2: "Pullover",
    3: "Dress",
    4: "Coat",
    5: "Sandal",
    6: "Shirt",
    7: "Sneaker",
    8: "Bag",
    9: "Ankle Boot",
}
figure = plt.figure(figsize=(8, 8))
cols, rows = 3, 3
for i in range(1, cols * rows + 1):
    sample_idx = torch.randint(len(training_data), size=(1,)).item()
    img, label = training_data[sample_idx]
    figure.add_subplot(rows, cols, i)
    plt.title(labels_map[label])
    plt.axis("off")
    plt.imshow(img.squeeze(), cmap="gray")
plt.show()
  • 从文件创建自定义数据集
import os
import pandas as pd
from torchvision.io import read_image

class CustomImageDataset(Dataset):
    def __init__(self, annotations_file, img_dir, transform=None, target_transform=None):
        self.img_labels = pd.read_csv(annotations_file)
        self.img_dir = img_dir
        self.transform = transform
        self.target_transform = target_transform

    def __len__(self):
        return len(self.img_labels)

    def __getitem__(self, idx):
        img_path = os.path.join(self.img_dir, self.img_labels.iloc[idx, 0])
        image = read_image(img_path)
        label = self.img_labels.iloc[idx, 1]
        if self.transform:
            image = self.transform(image)
        if self.target_transform:
            label = self.target_transform(label)
        return image, label
  • 使用DataLoader加载数据准备训练

数据集一次检索一个样本的特征和标签。
在训练模型时,我们通常希望以“小批量”的方式传递样本,每轮迭代时重新打乱数据以减少模型过拟合现象,并利用Python的多进程功能来加速数据获取。

from torch.utils.data import DataLoader

train_dataloader = DataLoader(training_data, batch_size=64, shuffle=True)
test_dataloader = DataLoader(test_data, batch_size=64, shuffle=True)

# Display image and label.
train_features, train_labels = next(iter(train_dataloader))
print(f"Feature batch shape: {train_features.size()}")
print(f"Labels batch shape: {train_labels.size()}")
img = train_features[0].squeeze()
label = train_labels[0]
plt.imshow(img, cmap="gray")
plt.show()
print(f"Label: {label}")

Transforms 转换

原始数据并不总是以机器学习算法所需的理想形式出现。因此,会采用转换技术对数据进行一些操作,使其适合训练过程。

所有TorchVision数据集都具有两个参数
——transform用于修改特征,target_transform用于修改标签
——这两个参数接受包含转换逻辑的可调用对象。

torchvision.transforms模块直接提供了几种常用的转换方法。

FashionMNIST数据集的特征是以PIL Image格式表示的,标签则是整数形式。为了训练,需要将特征转化为归一化的张量,并将标签转化为独热编码的张量。为此,将使用ToTensor和Lambda来进行这些转换操作。

import torch
from torchvision import datasets
from torchvision.transforms import ToTensor, Lambda

ds = datasets.FashionMNIST(
    root="data",
    train=True,
    download=True,
    transform=ToTensor(),
    target_transform=Lambda(lambda y: torch.zeros(10, dtype=torch.float).scatter_(0, torch.tensor(y), value=1))
)

Build Model 创建模型

神经网络由执行数据操作的层/模块组成。

PyTorch中的torch.nn命名空间提供了构建自定义神经网络所需的所有基本组件。

PyTorch中的每一个模块都是nn.Module的子类。一个神经网络本身就是一个模块,它包含了其他模块(即层)。这种嵌套结构使得构建和管理复杂的架构变得容易。

我们将构建一个神经网络来对FashionMNIST数据集中的图像进行分类。

import os
import torch
from torch import nn
from torch.utils.data import DataLoader
from torchvision import datasets, transforms

device = (
    "cuda"
    if torch.cuda.is_available()
    else "mps"
    if torch.backends.mps.is_available()
    else "cpu"
)
print(f"Using {device} device")

class NeuralNetwork(nn.Module):
    def __init__(self):
        super().__init__()
        self.flatten = nn.Flatten()
        self.linear_relu_stack = nn.Sequential(
            nn.Linear(28*28, 512),
            nn.ReLU(),
            nn.Linear(512, 512),
            nn.ReLU(),
            nn.Linear(512, 10),
        )

    def forward(self, x):
        x = self.flatten(x)
        logits = self.linear_relu_stack(x)
        return logits
        
model = NeuralNetwork().to(device)
print(model)

Automatic Differentiation 自动微分

在训练神经网络时,最常使用的算法是反向传播。该算法中,会根据损失函数相对于给定参数的梯度来调整参数(即模型权重)。

为了计算这些梯度,PyTorch 内置了一个名为 torch.autograd 的自动微分引擎。它可以支持任何计算图的梯度自动计算。

考虑一个最简单的单层神经网络,其包含输入x、参数w和b以及某个损失函数。在PyTorch中,可以如下方式定义这个网络:

import torch

x = torch.ones(5)  # input tensor
y = torch.zeros(3)  # expected output
w = torch.randn(5, 3, requires_grad=True)
b = torch.randn(3, requires_grad=True)
z = torch.matmul(x, w)+b
loss = torch.nn.functional.binary_cross_entropy_with_logits(z, y)

loss.backward()
print(w.grad)
print(b.grad)

Optimization Loop 优化循环

有了模型和数据,接下来需要通过在数据上优化模型参数来训练、验证和测试我们的模型。

训练模型是一个迭代过程,在每次迭代中,模型都会对输出做出猜测,计算猜测的误差(损失),收集关于模型参数的误差梯度(正如我们在上一节中看到的那样),然后使用梯度下降法优化这些参数。

import torch
from torch import nn
from torch.utils.data import DataLoader
from torchvision import datasets
from torchvision.transforms import ToTensor

training_data = datasets.FashionMNIST(
    root="data",
    train=True,
    download=True,
    transform=ToTensor()
)

test_data = datasets.FashionMNIST(
    root="data",
    train=False,
    download=True,
    transform=ToTensor()
)

train_dataloader = DataLoader(training_data, batch_size=64)
test_dataloader = DataLoader(test_data, batch_size=64)

class NeuralNetwork(nn.Module):
    def __init__(self):
        super().__init__()
        self.flatten = nn.Flatten()
        self.linear_relu_stack = nn.Sequential(
            nn.Linear(28*28, 512),
            nn.ReLU(),
            nn.Linear(512, 512),
            nn.ReLU(),
            nn.Linear(512, 10),
        )

    def forward(self, x):
        x = self.flatten(x)
        logits = self.linear_relu_stack(x)
        return logits

model = NeuralNetwork()

def train_loop(dataloader, model, loss_fn, optimizer):
    size = len(dataloader.dataset)
    # Set the model to training mode - important for batch normalization and dropout layers
    # Unnecessary in this situation but added for best practices
    model.train()
    for batch, (X, y) in enumerate(dataloader):
        # Compute prediction and loss
        pred = model(X)
        loss = loss_fn(pred, y)

        # Backpropagation
        loss.backward()
        optimizer.step()
        optimizer.zero_grad()

        if batch % 100 == 0:
            loss, current = loss.item(), batch * batch_size + len(X)
            print(f"loss: {loss:>7f}  [{current:>5d}/{size:>5d}]")


def test_loop(dataloader, model, loss_fn):
    # Set the model to evaluation mode - important for batch normalization and dropout layers
    # Unnecessary in this situation but added for best practices
    model.eval()
    size = len(dataloader.dataset)
    num_batches = len(dataloader)
    test_loss, correct = 0, 0

    # Evaluating the model with torch.no_grad() ensures that no gradients are computed during test mode
    # also serves to reduce unnecessary gradient computations and memory usage for tensors with requires_grad=True
    with torch.no_grad():
        for X, y in dataloader:
            pred = model(X)
            test_loss += loss_fn(pred, y).item()
            correct += (pred.argmax(1) == y).type(torch.float).sum().item()

    test_loss /= num_batches
    correct /= size
    print(f"Test Error: \n Accuracy: {(100*correct):>0.1f}%, Avg loss: {test_loss:>8f} \n")
    
loss_fn = nn.CrossEntropyLoss()
optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate)

epochs = 10
for t in range(epochs):
    print(f"Epoch {t+1}\n-------------------------------")
    train_loop(train_dataloader, model, loss_fn, optimizer)
    test_loop(test_dataloader, model, loss_fn)
print("Done!")

保存、加载、使用模型

import torch
import torchvision.models as models

model = models.vgg16(weights='IMAGENET1K_V1')
torch.save(model.state_dict(), 'model_weights.pth')

model.load_state_dict(torch.load('model_weights.pth'))
model.eval()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1500522.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

从huggingface下载模型像本地加载但是UnicodeDecodeError

我自己是在Linux下出现了这个问题 原文:https://github.com/huggingface/transformers/issues/13674 The path for the AutoModel should be to a directory pointing to a pytorch_model.bin and to a config.json. Since you’re pointing to the .bin file dire…

论文笔记:Efficient Bootstrapping for Confidential Transactions

EcoBoost: Efficient Bootstrapping for Confidential Transactions 设计了一种被称为EcoBoost的新方法,以提高支持机密交易的区块链的引导效率。具体来说,利用随机抽样来验证高概率保密交易的正确性。因此,与事务数量相比**,验证…

Promise async await

简介:回调 JS会提供很多函数,允许异步行为。换句话说,现在开始执行的行为。但它们会在稍后完成。异步执行某项功能的函数应该提供一个 callback 参数用于在相应事件完成时调用。处理Error: 加载成功时,它会调用 callb…

Z Potentials | 星爵,他的征途不止向量数据库

纵观过去几十年的科技发展史,每一代新的技术架构的出现往往都伴随着新的数据范式的出现,也催生了多家百亿到千亿美金数据平台的诞生。如果说 2023 年科技领域的关键词是 LLM,那么数据库领域的关键词一定非向量数据库莫属。向量数据库是一种专…

我们是如何测试人工智能产品的

在当今数字化时代,人工智能(AI)技术已经成为我们生活中不可或缺的一部分。然而,要构建出可信赖的AI系统并非易事。这需要我们不仅深入理解人工智能的核心原理,还需要将这些理论知识应用到实际场景中。 为了帮助大家系…

一个不错的空间视频收集论坛

该网站收录了来自世界各地的空间视频、空间照片和全景照片,以突出令人惊叹的 Apple Vision Pro 的功能。 网站地址:

Java 客户端向服务端上传文件(TCP通信)

一、实验内容 编写一个客户端向服务端上传文件的程序,要求使用TCP通信的的知识,完成将本地机器输入的路径下的文件上传到D盘中名称为upload的文件夹中。并把客户端的IP地址加上count标识作为上传后文件的文件名,即IP(count&#…

mysql中insert … select锁范围

1、执行 insert … select 的时候,对目标表也不是锁全表,而是只锁住需要访问的资源。 例如, CREATE TABLE t (id int(11) NOT NULL AUTO_INCREMENT,c int(11) DEFAULT NULL,d int(11) DEFAULT NULL,PRIMARY KEY (id),UNIQUE KEY c (c) ) EN…

IP定位技术在金融风控中的应用研究

随着金融科技的快速发展,金融行业的风险也呈现出多样化、复杂化的特点。金融风控作为保障金融安全的重要手段,其面临的挑战也日益加剧。在这样的背景下,IP定位技术作为一种先进的信息技术手段,正逐渐成为金融风控领域的重要工具。…

精酿啤酒:原料来源的追溯与认证体系

为了确保啤酒品质的可靠性和安全性,Fendi Club啤酒建立了一套完善的原料来源追溯与认证体系。这套体系旨在确保从原料采购到生产过程的每一个环节都能得到进一步监控和管理,从而提高产品质量,降低风险。 Fendi Club啤酒对原料供应商进行严格的…

【kerberos】hadoop集群使用keytab认证的逻辑

一、背景: haoop的kerberos认证核心是org.apache.hadoop.security.UserGroupInformation类。 UserGroupInformation一般有两种:(1)apache原生的(2)cdh hdp改良过的,即cloudera改良过的。 由此衍…

Kube-Prometheus 监控Istio

推荐 Istio 多集群监控使用 Prometheus,其主要原因是基于 Prometheus 的分层联邦(Hierarchical Federation)。 通过 Istio 部署到每个集群中的 Prometheus 实例作为初始收集器,然后将数据聚合到网格层次的 Prometheus 实例上。 网…

【Web】浅聊Java反序列化之C3P0——不出网Hex字节码加载利用

目录 简介 原理分析 EXP 前文:【Web】浅聊Java反序列化之C3P0——URLClassLoader利用 简介 不出网的情况下,这个C3P0的Gadget可以和fastjson,Snake YAML , JYAML,Yamlbeans , Jackson,Blazeds,Red5, Castor等配合使用(调用setter和初始化…

【php】【mysql】 原生初级简易新闻发布系统成品代码动态网站开发网页WEB浏览器端B/S结构

【php】【mysql】 原生初级简易新闻发布系统成品代码动态网站开发网页WEB浏览器端B/S结构 一级目录二级目录三级目录 获取源码方式项目说明:项目运行环境文件包含运行截图程序代码结构图新闻首页图新闻详情图新闻列表管理图个人信息管理图登录界面新闻详情新闻发布 …

基于JavaWeb的NBA赛事信息管理系统

目 录 摘 要 I Abstract II 引 言 1 1 系统概述 3 1.1 系统开发背景及意义 3 1.2 开发环境、工具 3 1.3 相关技术 4 1.3.1 前端技术 4 1.3.2 数据库技术 4 1.4 本章小结 4 2 系统分析 5 2.1 功能需求分析 5 2.2 性能需求分析 5 2.3 本章小结 6 3 系统设计 7 3.1 功能设计 7 3.…

拼多多1000元虚拟店铺免4万保证金

众所周知拼多多现在流量非常大,虚拟也算是蓝海,想做的人大部分都被保证金拦在门外,高达4W的保证金不是每个人都能承受的,正好在当下有一个方法可以解决这个苦恼。 拼多多虚拟店铺免保证金玩法现在处于前期阶段,很多人…

如何搭建 Jenkins 自动化测试平台?

前言 在进行平台搭建前,我们首先要问自己:我需要搭建的平台的功能是什么,要实现什么目标? 在我的理解中,自动化构建平台的执行流程(目标)是: 我们将代码提交到代码托管工具上&…

Linux 关于NTP同步硬件时钟的可靠性验证

Linux关于NTP同步硬件时钟的可靠性验证 1. 常见的时钟类型1.1 系统时钟1.2 硬件时钟 2. 常见时钟同步方式2.1 ntpd服务2.1.1 推荐配置/etc/ntp.conf2.1.2 推荐配置/etc/sysconfig/ntpd 2.2 定时任务ntpdate2.3 ntp命令同步状态相关命令解读2.3.1 ntpq -pn解读2.3.2 ntpdate -u解…

【牛客】VL74 异步复位同步释放

描述 题目描述: 请使用异步复位同步释放来将输入数据a存储到寄存器中,并画图说明异步复位同步释放的机制原理 信号示意图: clk为时钟 rst_n为低电平复位 d信号输入 dout信号输出 波形示意图: 输入描述: clk为时…

STM32 SDRAM知识点

1.SDRAM和SRAM的区别 SRAM不需要刷新电路即能保存它内部存储的数据。而SDRAM(Dynamic Random Access Memory)每隔一段时间,要刷新充电一次,否则内部的数据即会消失,因此SRAM具有较高的性能,但是SRAM也有它…