大模型之深度学习PyTorch篇——导学、创建、运算

写在前面

大模型作为当前前沿方向,许多框架还未成熟,必定有许多坑,几乎所有大模型编写框架都是采用PyTorch,所以学习好PyTorch是迈向大模型开发的基础。之前零零散散的学习了PyTorch,这里做一些总结和复习,这篇主要区B站上找了一些up(卢菁VIP课、刘二大人、我是土堆等)学习,另外也使用了大模型进行辅助(学习大模型肯定要知道怎么巧用大模型,没毛病吧),推荐在vscode中安装一个trea插件,方便编写代码。

导学

'''这节简单介绍下什么是PyTorch,为什么需要学习PyTorch'''

PyTorch框架介绍:Facebook的⼈⼯智能研究院 (FAIR) 向世界推出了PyTorch. 这个基于Torch的框架, 以其Python语⾔作为前端, 同时为深度学习研究者和开发者提供了两⼤核⼼优势: ⼀是强⼤的GPU加速张量计算能⼒ , 其并⾏计算能⼒在当时与NumPy相媲美。 ⼆是内置的⾃动微分系统, 使得构建深度神经⽹络变得更加直观和⾼效。

大模型相关支持huggingface社区 的开源的transformers库使⽤pytorch实现了市⾯上绝⼤多数开源的预训练模型 。微软的分布式训练框架deepspeed也⽀持Pytorch, 由于Pytorch备受研究⼈员的⻘睐, 近年来绝⼤多数开源神经⽹络架构都采⽤Pytorch实现。

安装:这类网上教程巨多,不多赘述,可以采用直接官网安装 ,但安装缓慢,甚至可能断链,这里贴一个镜像下载 的安装教程https://zhuanlan.zhihu.com/p/612181449

Python List 、Numpy Array和PyTorch Tensor的区别:

为什么不直接用Python自带的List处理数组呢?看了下面这个表和例子就知道答案,大模型参数量动不动就上几十、几百、几千亿,从下面的示例可以看出,处理数据,nmpy效率时list的100倍之多,这只是考虑的数据的读取和简单的运算,如果把求导等复杂运算,GPU加速考虑进来,PyTorch Tensor效率高于Python List数千倍、数十万倍,甚至上百万倍。假设需要1B的大模型进行推理,一般情况下需要几秒时间即可得到答案,但假设用List处理可能就需要几天才能得到答案。

Python List Numpy Array PyTorch Tensor
最基础的动态数组,可存储任意类型的数据(异构) 由 Python 的NumPy库提供,支持同构数据(元素类型必须一致) 由PyTorch库提供,专为深度学习设计,与NumPy类似支持GPU加速
灵活性高 ,但计算效率较低(尤其是大规模数据) 固定维度 (如 1D 向量、2D 矩阵),内存连续计算效率高 支持自动求导(requires_grad=True时),用于构建神经网络
不支持向量化操作,需通过循环处理元素 支持向量化操作(无需显式循环),适合科学计算 NumPy 数组语法高度相似,可无缝转换
python 复制代码
def test04():
    #Numpy内存连续,计算效率高(对比python List)
    # 创建大型数组/列表
    #np_array = np.arange(1000000)
    #py_list = list(range(1000000))
    # timeit 模块来比较NumPy数组向量化操作和Python列表循环操作的性能差异。
    
    numpy_time = timeit.timeit(
    stmt='np_array + 1',                
    setup='import numpy as np; np_array = np.arange(100000)',  
    number=1000                         
    )
    '''
    stmt:要测试的代码语句,这里是 np_array + 1,表示对 NumPy 数组的每个元素加 1。
    setup:在执行测试代码前运行的初始化代码,这里导入 numpy 并创建一个包含 1000000 个整数的数组。
    number:指定测试代码的执行次数(这里是 1000 次)。
    timeit.timeit() 返回的是 number 次执行的总耗时(秒),因此需要除以 number 得到每次执行的平均耗时。
    '''
    list_time = timeit.timeit(
    stmt='[x+1 for x in py_list]',      
    setup='py_list = list(range(100000))',  
    number=1000                        
    )
    print(f"NumPy 操作耗时: {numpy_time/1000:.6f} 秒/次")  # 计算每次操作的平均耗时
    print(f"列表操作耗时: {list_time/1000:.6f} 秒/次")  # 计算每次操作的平均耗时

运行结果;

NumPy 操作耗时: 0.000047 秒/次

列表操作耗时: 0.005235 秒/次

张量的简单操作

**张量的创建、创建技巧、格式转换、**随机数生成器

python 复制代码
def test01():
    # 张量标量的创建
    data = torch.tensor(10)  
    print(data)        # 输出 tensor(10)
    # 2. numpy 数组转化为张量
    data = np.random.randn(2, 3)
    data = torch.tensor(data)
    print(data)   # 输出两行三列的随机张量,类型默认为dtype=torch.float64
    # 3. 列表转化为张量
    data = [[10., 20., 30.], [40., 50., 60.]]
    data = torch.tensor(data)
    print(data)   # 输出tensor([[10, 20, 30],[40, 50, 60]])

def test02():
    # 1. 创建2⾏3列的张量
    data = torch.Tensor(2, 3)
    # 2. 注意: 如果传递列表, 则创建包含指定元素的张量
    data = torch.Tensor([10])
    print(data)
    data = torch.Tensor([10, 20])
    print(data)
    #注意:torch.Tensor是一个类
    #torch.tensor(10)和torch.Tensor([10])的区别
    # 验证数据类型
    print(torch.tensor(10).dtype)       # torch.int64
    print(torch.Tensor([10]).dtype)     # 注意torch.Tensor会自动转化为torch.float32
    # 验证形状
    print(torch.tensor(10).shape)       # torch.Size([])

# 3. 使⽤具体类型的张量
def test03():
    # 1. 创建2⾏3列, dtype 为 int32 的张量
    data = torch.IntTensor(2, 3)
    # 2. 注意: 如果传递的元素类型不正确, 则会进⾏类型转换
    data = torch.IntTensor([2.5, 3.3])
    # 3. 其他的类型
    data = torch.ShortTensor([2.5, 3.3]) # int16
    data = torch.LongTensor([2.5, 3.3]) # int64
    data = torch.FloatTensor([2.5, 3.3]) # float32
    data = torch.DoubleTensor([2.5, 3.3]) # float64
    #注意:
    #1、对于整型,Pytorch默认的是int64,dtype字段默认不显示
    #2、对于浮点型,Pytorch默认的是float32,dtype字段默认不显示

def test04():
    # 1. 创建2行3列, dtype 为 int32 的张量
    data = torch.zeros(2, 3, dtype=torch.int32)
    print(data)

    # 2. 注意: 如果传递的元素类型不正确, 则会进行类型转换
    data = torch.tensor([2.5, 3.3], dtype=torch.int32)
    print(data)

    # 3. 其他的类型
    # 同样使用 torch.tensor() 并通过 dtype 明确指定不同的数据类型。
    data = torch.tensor([2.5, 3.3], dtype=torch.int16) # int16
    print(data)
    data = torch.tensor([2.5, 3.3], dtype=torch.int64) # int64
    print(data)
    data = torch.tensor([2.5, 3.3], dtype=torch.float32) # float32
    print(data)
    data = torch.tensor([2.5, 3.3], dtype=torch.float64) # float64
    print(data)

def test05():   # 创建的技巧
    data = torch.arange(0, 10, 2)  # 步长为2
    data = torch.linspace(0, 11, 10)   # 均匀分布
    data = torch.rand(2, 3)   # 创建2行3列的随机张量,在区间 [0, 1) 上均匀分布
    data = torch.randn(2, 3)    # 从标准正态分布(高斯分布),即均值为0,方差为1

    data = torch.zeros(2, 3)  
    data = torch.zeros_like(data)  # 复制

    data = torch.ones(2, 3)
    data = torch.ones_like(data)
    
    data = torch.full([2, 3], 10)
    data = torch.full_like(data, 20)

def test06():    # 格式转换
    data = torch.full([2, 3], 10.)
    data = data.type(torch.DoubleTensor)
    # 将 data 元素类型转换为 float64 类型
    # 2. 第⼆种⽅法
    data = data.double()
    # 转换为其他类型
    data = data.short()
    data = data.int()
    data = data.long()
    data = data.float()

对于torch.Tensor与torch.tensor的区别其实没有太多实质性的区别,只是老版本用的torch.Tensor,新版本用的torch.tensor更灵活,大多数情况下都可以相互替换,但应当首选torch.tensor。

数据精度

PyTorch 默认使用float32 以优化计算效率(尤其适合GPU加速),但可能损失部分精度。 NumPy 默认使用 float64,适合科学计算中对精度要求高的场景。

随机数生成器

为了验证可复现性,需要使用随机数种子

torch.random.manual_seed(100) # 设置随机种子

张量的基本数学运算、统计运算、维度dim选择基本理解、深浅拷贝

python 复制代码
#张量的基本数学计算
def test01():
    x = torch.tensor([1.0, 2.3, 3.6])
    # 绝对值
    abs_x = torch.abs(x)
    # 平方根
    sqrt_x = torch.sqrt(x)
    # 指数运算
    exp_x = torch.exp(x)
    # 对数运算
    log_x = torch.log(x)
    # 幂运算
    pow_x = torch.pow(x, 2)  # 或者 x ** 2
    # 四舍五入
    round_x = torch.round(x)
    # 向上取整
    ceil_x = torch.ceil(x)
    # 向下取整
    floor_x = torch.floor(x)
#张量的统计运算
def test02():
    # 维度的选择,我的理解是dim代表维度,维度越小代表选取的原始张量范围越大,
    # 比如dim=0代表选取原始张量的第0维,也就是最外层的中括号,范围为2,
    # 再比如dim=1代表选取原始张量的第1维,也就是第1层的中括号,范围为3,依次类推
    x = torch.randint(0, 10, [2, 3, 4, 5])  # 生成一个 2x3x4x5 的随机整数张量
    print(x)
    max_vals, max_indices = torch.max(x, dim=0)
    print('dim = 0:max_vals, ', max_vals)
    print('dim = 0:max_indices', max_indices)
    max_vals, max_indices = torch.max(x, dim=1)
    print('dim = 1:max_vals, ', max_vals)
    print('dim = 1:max_indices', max_indices)
    max_vals, max_indices = torch.max(x, dim=2)
    print('dim = 2:max_vals, ', max_vals)
    print('dim = 2:max_indices', max_indices)
    max_vals, max_indices = torch.max(x, dim=3)
    print('dim = 3:max_vals, ', max_vals)
    print('dim = 3:max_indices', max_indices)
 
#张量的基础运算
def test03():
    #randint生成离散均匀分布随机整数的函数
    data = torch.randint(0, 10, [2, 3])
    # 1. 不修改原数据
    new_data = data.add(10) # 等价 new_data = data + 10
    # 2. 直接修改原数据
    # 注意: 带下划线的函数为修改原数据本身
    data.add_(10) # 等价 data += 10
    # 3. 其他函数
    print(data.sub(100))
    print(data.mul(100))
    print(data.div(100))
    print(data.neg())

# 注意: tensor 必须为 Float 或者 Double 类型
def test04():
    data = torch.randint(0, 10, [2, 3], dtype=torch.float64)
    print(data.mean()) #计算均值
    print(data.sqrt()) #计算平方根
    print(data.exp()) #指数运算,e^n 次⽅
    print(data.log()) #对数运算,以 e 为底

### 深拷贝与浅拷贝  ,记住torch.tensor函数是深拷贝,data.item()取值赋值也类似于深拷贝
# 1. 将张量转换为 numpy 数组
def test05():
    data_tensor = torch.tensor([2, 3, 4])
    # 使⽤张量对象中的 numpy 函数进⾏转换
    data_numpy = data_tensor.numpy()   # 浅拷贝
# 2. 使⽤ from_numpy 函数
def test06():
    data_numpy = np.array([2, 3, 4])
    # 将 numpy 数组转换为张量类型
    data_tensor = torch.from_numpy(data_numpy)# 浅拷⻉
    print(data_numpy)
# 3. 使⽤ torch.tensor 函数
def test07():
    data_numpy = np.array([2, 3, 4])
    data_tensor = torch.tensor(data_numpy)
    # numpy 和 tensor 不共享内存,深拷贝
# 4. 标量张量和数字的转换
def test08():
    # 当张量只包含⼀个元素时, 可以通过 item 函数提取出该值
    data = torch.tensor([30,])
    print(data.item())
    data = torch.tensor(30)
    print(data.item())
    #应用场景:获取loss值

维度简单理解:dim越小,维度越低,看的越广,tensor括号越靠外面

相关推荐
ZStack开发者社区17 分钟前
首批 | 云轴科技ZStack加入施耐德电气技术本地化创新生态
人工智能·科技·云计算
X Y O1 小时前
神经网络初步学习3——数据与损失
人工智能·神经网络·学习
FL16238631291 小时前
如何使用目标检测深度学习框架yolov8训练钢管管道表面缺陷VOC+YOLO格式1159张3类别的检测数据集步骤和流程
深度学习·yolo·目标检测
唯创知音1 小时前
玩具语音方案选型决策OTP vs Flash 的成本功耗与灵活性
人工智能·语音识别
Jamence1 小时前
多模态大语言模型arxiv论文略读(151)
论文阅读·人工智能·语言模型·自然语言处理·论文笔记
tongxianchao1 小时前
LaCo: Large Language Model Pruning via Layer Collapse
人工智能·语言模型·剪枝
HyperAI超神经2 小时前
OmniGen2 多模态推理×自我纠正双引擎,引领图像生成新范式;95 万分类标签!TreeOfLife-200M 解锁物种认知新维度
人工智能·数据挖掘·数据集·图像生成·医疗健康·在线教程·数学代码
网安INF2 小时前
深度学习中批标准化与神经网络调优
人工智能·深度学习·神经网络·机器学习
开开心心_Every2 小时前
便捷的电脑自动关机辅助工具
开发语言·人工智能·pdf·c#·电脑·音视频·sublime text
EnochChen_2 小时前
多实例学习简介
人工智能