【腾讯云 HAI域探秘】HAI推动Pytorch2.0 AI框架新时代

2023-11-09 17:01:12 浏览数 (2)

1、背景

对于机器学习和深度学习的码农们,几大框架大家都不陌生,但是不管是从科研还是论文上面,能看到的PyTorch的项目比TensorFlow要多,虽然在在Stack Overflow上3种主流框架Keras、TensorFlow和PyTorch统计中能看到TensorFlow依然跃居榜首:

但是,TensorFlow关注度更高,Keras陷入停滞甚至下降,而PyTorch虽然起步较晚,但这两年一直呈现关注度稳定上升的趋势。究其原因,可以归拢为以下几点:

其一,PyTorch用起来“更Python”。

使用Python编写TensorFlow框架的工作量,可能是PyTorch的两倍,此外后者编写代码的感受比TensorFlow更自然。

其二,PyTorch可用模型更多,且更适合学生和研究者使用。

据统计,在HuggingFace中,85%的大模型框架是用PyTorch实现的。

剩余的框架中,除了多个框架实现以外,只有8%的大模型框架是通过TensorFlow实现的。

这意味着PyTorch在AI大模型研究者中受欢迎程度更高。

不止大模型,使用PyTorch实现论文研究框架的人,变得越来越多。

这一观点也在Papers with Code网站统计上得到了印证。

在代码开源的那些论文研究中,单从框架使用率来看,这4年来PyTorch占比正急剧上升。

PyTorch从最初和TensorFlow持平,到如今远超TensorFlow、稳定成为使用率第一(占比62%)的框架,相比之下TensorFlow占比只有4%:

其三,PyTorch的生态发展更快。

虽然目前TensorFlow在生态体系上发展比PyTorch更好,但从PyTorch使用增长情况来看,这一趋势将在不久的将来得到逆转。

当然,TensorFlow自身也有一些不可取代的优势,例如部署更方便(类似TensorFlow Serving和TensorFlow Lite的工具很多)、以及对其他语言的支持更好等。

毕竟目前对于JavaScript、Java、C 、Julia和Rust等语言来说,TensorFlow还是更好的选择。

PyTorch则基本以Python为中心,即使有个C API,但其他语言的整体支持仍然比不上TensorFlow。

同时,Q11中国开发者主流人工智能框架使用率中,PyTorch也是排第一。

2、腾讯云HAI背景介绍

高性能应用服务 HAI:澎湃算力,即开即用。以应用为中心,匹配GPU云算力资源,助力中小企业及开发者快速部署LLM、AI作画、数据科学等高性能应用。是为开发者量身打造的澎湃算力平台。无需复杂配置,便可享受即开即用的GPU云服务体验。在 HAI 中,根据应用智能匹配并推选出最适合的GPU算力资源,以确保您在数据科学、LLM、AI作画等高性能应用中获得最佳性价比。

HAI 服务优势

智能选型 :根据应用匹配推选GPU算力资源,实现最高性价比。同时,打通必备云服务组件,大幅简化云服务配置流程。undefined 一键部署 :分钟级自动构建LLM、AI作画等应用环境。提供多种预装模型环境,包含如StableDiffusion、ChatGLM等热门模型。undefined 可视化界面 :友好的图形界面,AI调试更为简单

即插即用 · 轻松上手

基于腾讯云GPU云服务器底层算力,提供即插即用的高性能云服务。

智能选型

根据应用匹配推选GPU算力资源,实现最高性价比。同时,打通必备云服务组件,大幅简化云服务配置流程。

一键部署

分钟级自动构建LLM、AI作画等应用环境。提供多种预装模型环境,包含如StableDiffusion、ChatGLM等热门模型。

可视化界面

提供开发者友好的图形界面,支持jupyterlab、webui等多种算力连接方式,AI研究调试超低门槛。

横向对比 · 青出于蓝

大幅降低GPU云服务器使用门槛,多角度优化产品使用体验,开箱即用

应用场景

AI作画(视觉设计、游戏)

基于StableDiffusion开源模型进行AI绘画

场景介绍

AI绘画是一种利用深度学习算法进行创作的绘图方式。广泛应用于数字媒体、游戏、动画、电影、广告等领域。

业务痛点

  • GPU卡型多样,算力、显存差异大,选型困难
  • 环境配置复杂、模型安装和调试门槛高
  • 各类插件迭代频繁,难以在进行环境管理

产品优势

  • 智能匹配算力,多种算力套餐满足不同需求的绘图性能。
  • 预置主流AI作画模型及常用插件,无需手动部署,支持即开即用。
  • 动态更新模型版本,确保模型版本与时俱进,无需频繁操作。

AI对话/写作(Agent、企业知识库)大语言模型

基于开源大语言模型,创作属于自己的Agent、企业知识库

场景介绍

大语言模型在广泛的文本数据上进行训练,可以执行广泛的任务,包括文本总结、翻译、情感分析等等。

业务痛点

  • 环境配置复杂,部署难度大。
  • 模型效果调试难,无可视化界面。
  • 模型、数据集储存流程繁琐,难以快捷保存

业务痛点

  • 预置国内外主流LLM大语言模型。
  • 支持可视化界面一键登录,方便调优
  • 打通云上存储组件,支持模型、数据集快捷存储

AI开发/测试(学术研究、论文)算法研发

学术研究、论文

场景介绍

面向高校、研究所等大量科研场景,需针对深度学习、机器学习等前沿算法进行开发探索。

业务痛点

  • 需要大量的计算资源进行验证和优化。
  • 涉及多种框架、模型及开发库,环境配置复杂。

业务痛点

  • 提供多种高性能GPU云服务器,满足算法验证和测试的需求。
  • 提供公共模型、数据集文件存储桶,优化资源拉取效率。

3、实验介绍

本次我们使用 腾讯云高性能应用服务 HAI 体验快速搭建并使用AI框架 Pytorch2.0 ,实现思路如下:

1、开发者体验 高性能应用服务HAI 一键部署 PyTorch 2.0

2、开发者体验 高性能应用服务HAI 学习 PyTorch 基础知识,通过 JupyterLab 实现的完整的机器学习工作流程。

3、开发者体验 高性能应用服务HAI PyTorch 2.0 使用字符级循环神经网络(RNN) 生成姓名

4、开发者体验 高性能应用服务HAI PyTorch 2.0 强大的视频抠图 (RVM)

3.1 效果展示

使用 JupyterLab 体验完整的机器学习工作流程

使用 JupyterLab 体验字符级循环神经网络(RNN) 生成姓名

使用 JupyterLab 体验视频抠像神器RobustVideoMatting

4、动手实验

4.1 申请高性能应用服务 HAI

4.1.1 点击链接进入 高性能应用服务 HAI 申请体验资格
4.1.2 等待审核通过后,进入 高性能应用服务 HAI
4.1.3 点击前往体验HAI,登录 高性能应用服务 HAI 控制台
4.1.4 点击 新建 选择 AI框架,选择算力方案、输入实例名称、选择数量 后立即购买
4.1.5 查看实例创建状态
4.1.6 完成创建,查看运行状态

4.2 使用 JupyterLab 体验完整的机器学习工作流程

4.2.1 创建工作空间

算力管理页面 点击 算力连接 ,选择 jupyter_lab

认识 JupyterLab 操作界面,这里 选择 Notebook

4.2.2 数据处理

PyTorch 中有两个处理数据的基元:Torch.utils.data.DataLoader 和 Torch.utils.data.Dataset。

Dataset 存储样本及其相应的标签,而 DataLoader 则围绕 Dataset 包装了一个可迭代的数据。

PyTorch 提供了特定领域的库,如 TorchText、TorchVision 和 TorchAudio,它们都包括数据集。在本教程中,我们将使用一个 TorchVision 数据集。

torchvision.datasets 模块包含了许多真实世界的视觉数据的 Dataset 对象,如 CIFAR、COCO。每个 TorchVision 中的 Dataset 对象都包括两个参数:transform 和 target_transform,分别用来修改样本和标签。在本教程中,我们使用 FashionMNIST 数据集。

由于外网环境下载数据集缓慢,这里我们使用清华大学的镜像加载本地数据集

代码语言:javascript复制
mkdir dataset-fashion-mnist #创建文件夹 dataset-fashion-mnist
cd dataset-fashion-mnist
wget https://mirror.tuna.tsinghua.edu.cn/raspberry-pi-os/raspbian/pool/main/d/dataset-fashion-mnist/dataset-fashion-mnist_0.0~git20200523.55506a9.orig.tar.xz #下载数据集
tar -xf dataset-fashion-mnist_0.0~git20200523.55506a9.orig.tar.xz --strip-components=1
cd data && mkdir FashionMNIST && mkdir FashionMNIST/raw 

执行创建命令后:

点击目录 依次进入 root/dataset-fashion-mnist/data/fashion

按住 ctrl 键 选中四个数据集文件并拷贝至 /FashionMNIST/raw/ 文件夹

依次进入 /FashionMNIST/raw/ 文件夹并粘贴文件

创建一个 Notebook 文件

粘贴代码并点击菜单栏 RunRun Selected Cell 执行选中代码

代码语言:javascript复制
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="/root/dataset-fashion-mnist/data",
    train=True,
    download=True,
    transform=ToTensor(),
)
# 加载本地测试数据
test_data = datasets.FashionMNIST(
    root="/root/dataset-fashion-mnist/data",
    train=False,
    download=True,
    transform=ToTensor(),
)

代码截图:

新建一个控制台页面来配置使用 腾讯云 提供的镜像服务并安装依赖

选择默认使用 腾讯云 提供的镜像服务

代码语言:javascript复制
pip config set global.index-url http://mirrors.cloud.tencent.com/pypi/simple
pip config set global.trusted-host mirrors.cloud.tencent.com
代码语言:javascript复制
pip install matplotlib

返回之前的 Notebook 页面

我们可以像列表一样手动索引 Dataset:training_data[index]。我们可以使用 matplotlib 来可视化数据中的一些样本。

代码语言:javascript复制
import matplotlib.pyplot as plt

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()

可视化样本:

我们将 Dataset 作为参数传递给 DataLoader。这会在我们的数据集上包裹一个可迭代的对象,并支持自动批处理、采样、顺序打乱和多进程数据加载。在这里,我们定义了一个64的批处理大小,即 dataloader 可迭代的每个元素将返回64个特征和标签的批次。

粘贴代码并点击菜单栏 RunRun Selected Cell 执行选中代码

代码语言:javascript复制
batch_size = 64

# 创建 dataloader
train_dataloader = DataLoader(training_data, batch_size=batch_size)
test_dataloader = DataLoader(test_data, batch_size=batch_size)

for X, y in test_dataloader:
    print(f"Shape of X [N, C, H, W]: {X.shape}")
    print(f"Shape of y: {y.shape} {y.dtype}")
    break

执行结果截图:

4.2.3 创建模型

为了在 PyTorch 中定义一个神经网络,我们创建一个继承自 nn.Module 的类。我们在__init__函数中定义网络的层,并在 forward 函数中指定数据将如何通过网络。为了加速神经网络的操作,我们将其移到GPU上。

粘贴代码并点击菜单栏 RunRun Selected Cell 执行选中代码

代码语言:javascript复制
# 获取用于训练的 cpu 或 gpu 设备
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)

执行结果截图:

4.2.4 优化模型参数

为了训练模型,我们需要一个损失函数和一个优化器。

代码语言:javascript复制
loss_fn = nn.CrossEntropyLoss() 
optimizer = torch.optim.SGD(model.parameters(), lr=1e-3)

在一个训练循环中,模型将对训练数据集(分批送入)进行预测,并反向传播预测误差以调整模型的参数。

代码语言:javascript复制
def train(dataloader, model, loss_fn, optimizer):
    size = len(dataloader.dataset)
    model.train()
    for batch, (X, y) in enumerate(dataloader):
        X, y = X.to(device), y.to(device)

        # 计算预测误差
        pred = model(X)
        loss = loss_fn(pred, y)

        # 反向传播
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()

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

我们还要根据测试数据集检查模型的性能。

代码语言:javascript复制
def test(dataloader, model, loss_fn):
    size = len(dataloader.dataset)
    num_batches = len(dataloader)
    model.eval()
    test_loss, correct = 0, 0
    with torch.no_grad():
        for X, y in dataloader:
            X, y = X.to(device), y.to(device)
            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")

训练过程是通过几个迭代(epochs)进行的。在每个迭代中,模型学习参数以做出更好的预测。我们在每个迭代中打印模型的准确度和损失;我们希望看到准确度在每个迭代中逐渐增加,损失在每个迭代中逐渐减少。

代码语言:javascript复制
epochs = 5
for t in range(epochs):
    print(f"Epoch {t 1}n-------------------------------")
    train(train_dataloader, model, loss_fn, optimizer)
    test(test_dataloader, model, loss_fn)
print("Done!")

执行截图:

4.2.5 保存模型

保存模型的一个常见方法是序列化内部状态字典(包含模型参数)。

代码语言:javascript复制
torch.save(model.state_dict(), "/root/model.pth")
print("Saved PyTorch Model State to model.pth")

执行截图:

4.2.6 加载模型并预测

加载模型的过程包括重新创建模型结构和加载内部状态字典。

代码语言:javascript复制
model = NeuralNetwork()
model.load_state_dict(torch.load("/root/model.pth"))

保存并加载本地模型截图:

现在使用这个模型可以用来进行预测:

代码语言:javascript复制
classes = [
    "包",
    "上衣",
    "套头衫",
    "连衣裙",
    "外套",
    "凉鞋",
    "衬衫",
    "运动鞋",
    "包",
    "短靴",
] #定义了一个包含类别标签的 classes 列表

model.eval() #将 PyTorch 模型设置为评估模式
x, y = test_data[1][0], test_data[1][1]#测试数据 test_data 中获取样本 分别为图像数据和其真实标签
with torch.no_grad():
    pred = model(x)
    predicted, actual = classes[pred[0].argmax(0)], classes[y]#选择具有最高概率的类别索引
    print(f'Predicted: "{predicted}", Actual: "{actual}"') #模型的预测结果 predicted 与真实标签 actual 进行比较,并使用 print 函数输出这两个值。
#输出图片信息
# 将 x 转换回图像格式
image = x.numpy().transpose(1, 2, 0)
# 显示图像
plt.figure(figsize=(4, 4))
plt.imshow(image)
# 设置中文标题
print('预测结果: "{predicted}", 实际结果: "{actual}"'.format(predicted=predicted, actual=actual))
plt.axis('off')
plt.show()

模型预测截图:

4.3 使用 JupyterLab 体验使用字符级循环神经网络(RNN) 生成姓名

4.3.1 数据准备

新建一个命令窗口,输入以下命令,下载资源包并解压

代码语言:javascript复制
cd /root
wget https://gitee.com/mmliujc/tencent_gpu/raw/master/data.zip
unzip data

解压文件:

新建一个 Notebook 页面,选择 Python 3

有一堆每行一个名字的纯文本文件 data/names/[Language].txt 。我们将行拆分为一个数组,将 Unicode 转换为 ASCII,最后得到一个字典 {language: [names ...]}

代码语言:javascript复制
from __future__ import unicode_literals, print_function, division
from io import open
import glob
import os
import unicodedata
import string

all_letters = string.ascii_letters   " .,;'-"
n_letters = len(all_letters)   1 # Plus EOS marker

def findFiles(path): return glob.glob(path)

# Turn a Unicode string to plain ASCII, thanks to https://stackoverflow.com/a/518232/2809427
def unicodeToAscii(s):
    return ''.join(
        c for c in unicodedata.normalize('NFD', s)
        if unicodedata.category(c) != 'Mn'
        and c in all_letters
    )

# Read a file and split into lines
def readLines(filename):
    with open(filename, encoding='utf-8') as some_file:
        return [unicodeToAscii(line.strip()) for line in some_file]

# Build the category_lines dictionary, a list of lines per category
category_lines = {}
all_categories = []
for filename in findFiles('/root/data/names/*.txt'):
    category = os.path.splitext(os.path.basename(filename))[0]
    all_categories.append(category)
    lines = readLines(filename)
    category_lines[category] = lines

n_categories = len(all_categories)

if n_categories == 0:
    raise RuntimeError('Data not found. Make sure that you downloaded data '
        'from https://download.pytorch.org/tutorial/data.zip and extract it to '
        'the current directory.')

print('# categories:', n_categories, all_categories)
print(unicodeToAscii("O'Néàl"))

4.3.2 创建网络

该网络为类别张量,增加了一个额外的参数,该参数与其他参数连接在一起。类别张量和字母输入一样,是一个 one-hot 向量。

我们将输出解释为下一个字母出现的概率。采样时,最有可能的输出字母被用作下一个输入字母。

添加了第二个线性层 o2o(在隐藏层和输出层合并后),以增强其处理能力。还有一个 dropout 层,它以给定的概率(这里是 0.1)随机将部分输入归零,通常用于模糊输入以防止过拟合。在这里,我们将其用于网络的末端来故意加入一些混乱,增加采样的多样性。

代码语言:javascript复制
import torch
import torch.nn as nn

class RNN(nn.Module):
    def __init__(self, input_size, hidden_size, output_size):
        super(RNN, self).__init__()
        self.hidden_size = hidden_size

        self.i2h = nn.Linear(n_categories   input_size   hidden_size, hidden_size)
        self.i2o = nn.Linear(n_categories   input_size   hidden_size, output_size)
        self.o2o = nn.Linear(hidden_size   output_size, output_size)
        self.dropout = nn.Dropout(0.1)
        self.softmax = nn.LogSoftmax(dim=1)

    def forward(self, category, input, hidden):
        input_combined = torch.cat((category, input, hidden), 1)
        hidden = self.i2h(input_combined)
        output = self.i2o(input_combined)
        output_combined = torch.cat((hidden, output), 1)
        output = self.o2o(output_combined)
        output = self.dropout(output)
        output = self.softmax(output)
        return output, hidden

    def initHidden(self):
        return torch.zeros(1, self.hidden_size)

4.3.3 训练网络

(1) 训练准备

首先,创建辅助函数用于获取 (category, line) 的随机对:

代码语言:javascript复制
import random

# Random item from a list
def randomChoice(l):
    return l[random.randint(0, len(l) - 1)]

# Get a random category and random line from that category
def randomTrainingPair():
    category = randomChoice(all_categories)
    line = randomChoice(category_lines[category])
    return category, line

对于每个时间步(即每个训练单词中的每个字母),网络的输入将是 (category, current letter, hidden state),输出将是 (next letter, next hidden state)。因此,对于每个训练集,我们需要类别、一组输入字母,和一组输出/目标字母。

由于我们在每个时间步预测当前字母的下一个字母,所以字母对是来自该行的连续字母组。例如,对于 ABCD,我们将创建 ("A"、"B")、("B"、"C")、("C"、"D")、("D"、"EOS")。

类别张量是一个大小为 <1 x n_categories> 的 one-hot 张量。在训练时,我们在每个时间步将其输送到网络中——这是一种设计选择,也可以将其包含在初始隐藏状态中,或使用其他策略。

代码语言:javascript复制
# One-hot vector for category
def categoryTensor(category):
    li = all_categories.index(category)
    tensor = torch.zeros(1, n_categories)
    tensor[0][li] = 1
    return tensor

# One-hot matrix of first to last letters (not including EOS) for input
def inputTensor(line):
    tensor = torch.zeros(len(line), 1, n_letters)
    for li in range(len(line)):
        letter = line[li]
        tensor[li][0][all_letters.find(letter)] = 1
    return tensor

# ``LongTensor`` of second letter to end (EOS) for target
def targetTensor(line):
    letter_indexes = [all_letters.find(line[li]) for li in range(1, len(line))]
    letter_indexes.append(n_letters - 1) # EOS
    return torch.LongTensor(letter_indexes)

为了方便训练,我们将创建一个 randomTrainingExample 函数,该函数获取一个随机的 (category, line) 对,并将它们转换为所需的 (category, input, target) 张量。

代码语言:javascript复制
# Make category, input, and target tensors from a random category, line pair
def randomTrainingExample():
    category, line = randomTrainingPair()
    category_tensor = categoryTensor(category)
    input_line_tensor = inputTensor(line)
    target_line_tensor = targetTensor(line)
    return category_tensor, input_line_tensor, target_line_tensor

(2)训练网络

与只使用最后一步的输出的分类不同,在每一步中我们都进行了一次预测,因此我们需要在每一步都计算损失。

自动求导的神奇之处在于,您可以简单地将每一步的损失相加,并在最后进行反向传播。

代码语言:javascript复制
criterion = nn.NLLLoss()

learning_rate = 0.0005

def train(category_tensor, input_line_tensor, target_line_tensor):
    target_line_tensor.unsqueeze_(-1)
    hidden = rnn.initHidden()

    rnn.zero_grad()

    loss = 0

    for i in range(input_line_tensor.size(0)):
        output, hidden = rnn(category_tensor, input_line_tensor[i], hidden)
        l = criterion(output, target_line_tensor[i])
        loss  = l

    loss.backward()

    for p in rnn.parameters():
        p.data.add_(p.grad.data, alpha=-learning_rate)

    return output, loss.item() / input_line_tensor.size(0)

为了记录训练所需的时间,我添加了一个 timeSince(timestamp) 函数,它返回一个可读的字符串:

代码语言:javascript复制
import time
import math

def timeSince(since):
    now = time.time()
    s = now - since
    m = math.floor(s / 60)
    s -= m * 60
    return '%dm %ds' % (m, s)

训练照常进行——多次调用 train 并等待几分钟,在每 print_every 个样本处打印当前时间和损失,同时在 all_losses 中存储每 plot_every 个样本的平均损失,以供稍后绘图使用。

请耐心等待训练完成,预计耗时约21分钟

代码语言:javascript复制
rnn = RNN(n_letters, 128, n_letters)

n_iters = 100000
print_every = 5000
plot_every = 500
all_losses = []
total_loss = 0 # Reset every ``plot_every`` ``iters``

start = time.time()

for iter in range(1, n_iters   1):
    output, loss = train(*randomTrainingExample())
    total_loss  = loss

    if iter % print_every == 0:
        print('%s (%d %d%%) %.4f' % (timeSince(start), iter, iter / n_iters * 100, loss))

    if iter % plot_every == 0:
        all_losses.append(total_loss / plot_every)
        total_loss = 0

执行完毕,耗时约21分钟

4.3.4 绘制损失

all_losses 中的历史损失绘制成图可以展示网络的学习过程:

在训练完成后的 Notebook 中粘贴代码并点击菜单栏 RunRun Selected Cell 执行选中代码

代码语言:javascript复制
import matplotlib.pyplot as plt

plt.figure()
plt.plot(all_losses)

查看损失绘制图:

4.3.5 网络采样

进行采样时,向网络中输入一个字母,预测下一个字母是什么,并将其作为下一个输入的字母,重复此过程直到遇到 EOS。

创建输入类别、起始字母和空隐藏状态的张量

使用起始字母创建一个字符串 output_name

在最大输出长度范围内,

  • 将当前字母输入网络
  • 从最近输出中获取下一个字母和下一个隐藏状态
  • 如果字母是 EOS,则停止
  • 如果是普通字母,则将其添加到 output_name 中并继续
  • 返回最终的姓名

注意: 比起要求输入一个起始字母,另一种策略是在训练中加入一个“字符串起始”的标记,并让网络自己选择起始字母。

代码语言:javascript复制
max_length = 20

# Sample from a category and starting letter
def sample(category, start_letter='A'):
    with torch.no_grad():  # no need to track history in sampling
        category_tensor = categoryTensor(category)
        input = inputTensor(start_letter)
        hidden = rnn.initHidden()

        output_name = start_letter

        for i in range(max_length):
            output, hidden = rnn(category_tensor, input[0], hidden)
            topv, topi = output.topk(1)
            topi = topi[0][0]
            if topi == n_letters - 1:
                break
            else:
                letter = all_letters[topi]
                output_name  = letter
            input = inputTensor(letter)

        return output_name

# Get multiple samples from one category and multiple starting letters
def samples(category, start_letters='ABC'):
    for start_letter in start_letters:
        print(sample(category, start_letter))

samples('Russian', 'RUS')

samples('German', 'GER')

samples('Spanish', 'SPA')

samples('Chinese', 'CHI')

返回结果:

4.4 使用 JupyterLab 体验视频抠像神器RobustVideoMatting

4.4.1 安装依赖

打开 File 依次选择 New 选择 Terminal

输入命令下载 RobustVideoMatting 相关源码:

下载源码

下载方式一:https下载方式

代码语言:javascript复制
git clone https://gitee.com/ai-toys/RobustVideoMatting
# 输入你的gitee账号密码
cd RobustVideoMatting

下载方式二:ssh下载方式

在服务器上生成ssh密钥,在Jupyter终端中依次执行以下命令

代码语言:javascript复制
ssh-keygen -t ed25519 -C ""  #双引号里面填ssh key,一般填自己邮箱
# 回车一直默认即可,会在家目录生成 ~/.ssh 文件夹,存放密钥信息
cat ~/.ssh/id_ed25519.pub  # 查看生成的公钥

  1. 复制红色区域内容
  2. 打开gitee登录,并添加密钥

在Jupyter终端中依次执行以下命令

代码语言:javascript复制
git clone git@gitee.com:ai-toys/RobustVideoMatting 
# 输入yes 回车确认

代码下载完成后 安装 Python 库:

代码语言:javascript复制
pip install -r requirements_inference.txt

截图如下:

4.4.2 读取模型

下载模型以及素材文件并完成解压

代码语言:javascript复制
wget https://gitee.com/mmliujc/tencent_gpu/raw/master/rvm_res.zip
unzip rvm_res.zip

完成后 选择文件 File -> New ->Python File

编写视频抠像处理代码:

代码语言:javascript复制
import torch
import base64


from model import MattingNetwork
from inference import convert_video

model = MattingNetwork('mobilenetv3').eval().cuda()  # 或 "resnet50"
model.load_state_dict(torch.load('rvm_mobilenetv3.pth'))


convert_video(
    model,                           # 模型,可以加载到任何设备(cpu 或 cuda)
    input_source='1917.mp4',        # 视频文件,或图片序列文件夹
    output_type='video',             # 可选 "video"(视频)或 "png_sequence"(PNG 序列)
    output_composition='output/com.mp4',    # 若导出视频,提供文件路径。若导出 PNG 序列,提供文件夹路径
    output_alpha="output/pha.mp4",          # [可选项] 输出透明度预测
    output_foreground="output/fgr.mp4",     # [可选项] 输出前景预测
    output_video_mbps=4,             # 若导出视频,提供视频码率
    downsample_ratio=None,           # 下采样比,可根据具体视频调节,或 None 选择自动
    seq_chunk=12,                    # 设置多帧并行计算
)

编写完成后 Ctrl S 保存代码,重命名为 test.py

输入命令 创建我们要输出视频的文件夹并执行Python脚本:

代码语言:javascript复制
mkdir output
python test.py

4.4.3 展示结果

完成后即可在output文件夹下查看相应文件

这里我们使用notebook查看结果:

输入代码并执行:

代码语言:javascript复制
import torch
import base64
from IPython.display import HTML

outpath = "com.mp4"
mp4 = open(outpath,'rb').read()
data_url = "data:video/mp4;base64,"   base64.b64encode(mp4).decode()
HTML("""
<video width=400 controls>
      <source src="%s" type="video/mp4">
</video>
""" % data_url)

执行完成后:

加载不同的视频文件 查看不同的实验效果:

5、实验小结

本次实验主要是引导大家如何使用 高性能应用服务 HAI 部署 AI框架 Pytorch2.0 运行环境进行机器学习的工作流程,并实际体验在 高性能应用服务 HAI 上实践生成姓名、视频抠像,开箱即用,可以快速上手。最后也欢迎大家一起探索 高性能应用服务 HAI 更多的功能,为工作中赋能增效降本!

0 人点赞