从零学习大模型(一)-----GPT3(上)

GPT-3(Generative Pre-trained Transformer 3)是一种大型自回归语言模型,由OpenAI团队训练和发布。GPT-3 拥有1750亿个参数,是当时发布的最大的非稀疏(non-sparse)语言模型之一。其参数规模是前一代模型(如GPT-2)的10倍以上。GPT-3的目标是通过大规模的参数量和广泛的预训练来实现对多种语言任务的few-shot学习,即通过少量示例而无需额外的任务特定训练或微调来完成下游任务。

架构细节

GPT-3 的架构基于 Transformer 架构,特别是自回归 Transformer,这与其前代模型 GPT-2 基本相同,但在参数数量、深度和模型容量上进行了显著的扩展。具体架构细节如下:

  • Transformer 架构:GPT-3 使用经典的 Transformer 设计,包括注意力机制、多层网络等。Transformer 是一种基于注意力机制的神经网络,尤其适用于自然语言处理任务。
  • 模型规模
    • GPT-3 实际上由 8 个不同规模的模型组成,参数规模从 1.25 亿到 1750 亿不等,分别被称为 GPT-3 Small, GPT-3 Medium, GPT-3 Large 等等。模型规模从小到大的变化使得研究人员可以研究模型性能与规模的关系。
    • 最大的版本(GPT-3 175B)拥有96层(layers)每层包含12288个隐藏单元(hidden units),注意力头的数量为96。GPT-3 使用了一种称为**本地带状稀疏注意力模式(locally banded sparse attention patterns)**的方法,以增强在上下文窗口内进行信息处理的效率。
  • 自回归生成:GPT-3 是一种自回归语言模型,即它通过预测前一部分文本后面的下一个词来生成文本。其训练过程的目标是最小化语言模型在给定上下文下生成下一个词的交叉熵损失。
  • 上下文窗口大小:GPT-3 使用的上下文窗口大小为2048个标记(tokens)。这意味着在生成文本时,模型能够处理长达2048个标记的文本输入,用于捕捉较长的依赖关系和上下文信息。

什么是自回归Transformer

自回归 Transformer 是一种基于 Transformer 架构的语言模型,用于生成序列数据。它通过逐步预测下一个单词来生成整个句子或序列。这种生成方式称为自回归(autoregressive),即模型基于之前生成的内容来预测下一个内容。自回归 Transformer 模型特别适合自然语言生成任务,比如机器翻译、对话系统、文本补全等。

**自回归(autoregressive)**是一种生成策略,其中模型使用当前时间步的输出作为输入来预测下一个时间步的输出。例如,假设有一个目标序列 y 1 , y 2 , … , y T y_1, y_2, \ldots, y_T y1,y2,,yT,自回归模型会通过如下的方式进行生成: P ( y 1 , y 2 , … , y T ) = P ( y 1 ) ⋅ P ( y 2 ∣ y 1 ) ⋅ P ( y 3 ∣ y 1 , y 2 ) ⋯ P ( y T ∣ y 1 , y 2 , … , y T − 1 ) P(y_1, y_2, \ldots, y_T) = P(y_1) \cdot P(y_2 \mid y_1) \cdot P(y_3 \mid y_1, y_2) \cdots P(y_T \mid y_1, y_2, \ldots, y_{T-1}) P(y1,y2,,yT)=P(y1)P(y2y1)P(y3y1,y2)P(yTy1,y2,,yT1)即每一步的输出是基于之前生成的所有内容。这种方式可以确保模型的生成过程是顺序的,且每一步都根据之前生成的部分进行预测。

自回归 Transformer 的特点
  1. 基于 Transformer 架构: 自回归 Transformer 使用了经典的Transformer 架构,该架构由 Vaswani 等人在 2017 年提出,以其**注意力机制(Attention Mechanism)**和高效的并行化能力而受到广泛关注。Transformer 架构通过多头注意力机制(Multi-Head Attention)捕捉输入序列中不同位置之间的依赖关系,能够更好地理解上下文和全局信息。
  2. 自回归生成方式: 自回归 Transformer 模型的生成方式是逐词预测,即根据前面已生成的词,逐步预测序列中的下一个词,直到生成完整的句子或文本。GPT 系列模型(如 GPT-2 和 GPT-3)便是自回归 Transformer 的典型代表。
    • 在训练阶段,模型会学习从给定的前面部分序列预测下一个词的概率。它通过最大化每一步生成的正确性的对数似然函数来进行训练。
    • 在推理或生成阶段,模型会基于输入的初始文本,通过不断地预测下一个词的概率来生成文本。例如,对于输入序列“我喜欢”,模型会根据上下文生成“吃苹果”或其他合理的词语。
  3. 无并行生成: 由于自回归模型需要根据前面的内容逐步生成序列,因此生成的过程是顺序的,这意味着不能像 Transformer 的编码器部分那样完全并行化。尽管 Transformer 本身在训练时能够对整个输入并行计算,但在生成阶段,自回归特性使得它必须逐词进行计算,从而限制了生成的效率。
自回归 Transformer 与其他生成方式的对比
  • 自回归 vs. 非自回归: 自回归 Transformer 与非自回归 Transformer不同,后者尝试在一次性生成整个序列,主要用于加速生成过程。然而,非自回归生成在质量上通常较自回归生成有所折扣,因为它难以捕捉到序列中的复杂依赖关系。
  • GPT vs. BERT: 自回归 Transformer 的一个典型代表是 GPT 系列(如 GPT-2、GPT-3)。相比之下,BERT 使用的是双向编码(bidirectional encoding),即它在预测某个词时,能够利用该词前后所有的上下文信息。这使得 BERT 更适合理解类任务(如分类、问答),而自回归的 GPT 更适合生成类任务。
自回归 Transformer 的应用
  1. 文本生成: 自回归 Transformer 非常适合各种文本生成任务,例如文本补全、机器翻译、对话系统等。GPT-3 正是通过自回归的方式,从输入的提示中逐词生成高质量的自然语言文本。
  2. 机器翻译: 在机器翻译中,自回归 Transformer 会逐词生成目标语言的译文,确保每个词语都是基于前面的译文内容,从而保持语法和语义的一致性。
  3. 代码生成与补全: 自回归 Transformer 也被用于代码生成与补全,例如 GitHub 的 Copilot 工具,它基于 Transformer 模型,能够根据上下文逐步生成代码片段。
用pytorch写的自回归Transformer训练与预测的代码
PositionalEncoding
import torch
import torch.nn as nn
import torch.optim as optim
import torch.nn.functional as F
import numpy as npclass PositionalEncoding(nn.Module):def __init__(self, d_model, max_len=5000):super(PositionalEncoding, self).__init__()# 创建位置编码矩阵,形状为 (max_len, d_model)pe = torch.zeros(max_len, d_model)# 创建位置的张量 (0, 1, 2, ..., max_len-1) 并扩展其维度position = torch.arange(0, max_len, dtype=torch.float).unsqueeze(1)# 计算正弦和余弦函数的除数项div_term = torch.exp(torch.arange(0, d_model, 2).float() * -(np.log(10000.0) / d_model))# 对位置编码的偶数索引应用正弦函数,奇数索引应用余弦函数pe[:, 0::2] = torch.sin(position * div_term)pe[:, 1::2] = torch.cos(position * div_term)# 添加一个额外的维度以便与批次兼容pe = pe.unsqueeze(0).transpose(0, 1)# 注册位置编码为缓冲区,在训练期间不更新self.register_buffer('pe', pe)def forward(self, x):# 将位置编码加到输入的嵌入上return x + self.pe[:x.size(0), :]
TransformerEncoderLayerCustom
class TransformerEncoderLayerCustom(nn.Module):def __init__(self, d_model, nhead, dim_feedforward, dropout=0.1):super(TransformerEncoderLayerCustom, self).__init__()# 自定义多头自注意力机制self.d_model = d_modelself.nhead = nheadself.dropout = nn.Dropout(dropout)# 前馈网络,包含两个线性层和一个激活函数(ReLU)self.linear1 = nn.Linear(d_model, dim_feedforward)self.linear2 = nn.Linear(dim_feedforward, d_model)# 层归一化self.norm1 = nn.LayerNorm(d_model)self.norm2 = nn.LayerNorm(d_model)# 激活函数self.activation = F.reludef scaled_dot_product_attention(self, query, key, value, mask=None):# 计算注意力分数scores = torch.matmul(query, key.transpose(-2, -1)) / np.sqrt(self.d_model // self.nhead)# 应用掩码(如果有)if mask is not None:scores = scores.masked_fill(mask == 0, float('-inf'))# 计算注意力权重attn_weights = F.softmax(scores, dim=-1)# 应用注意力权重到值上return torch.matmul(attn_weights, value)def forward(self, src, src_mask=None):batch_size, seq_len, _ = src.size()head_dim = self.d_model // self.nhead# 将输入分割成多个头query = key = value = src.view(batch_size, seq_len, self.nhead, head_dim).transpose(1, 2)# 计算多头注意力attn_output = self.scaled_dot_product_attention(query, key, value, mask=src_mask)attn_output = attn_output.transpose(1, 2).contiguous().view(batch_size, seq_len, self.d_model)attn_output = self.dropout(attn_output)# 残差连接和层归一化src = self.norm1(src + attn_output)# 前馈网络src2 = self.linear2(self.dropout(self.activation(self.linear1(src))))# 残差连接和层归一化src = self.norm2(src + src2)return src

上述代码中一些解释

torch.matmul(query, key.transpose(-2, -1)) 的作用是计算**查询(query)键(key)**之间的点积相似度,这一步是实现自注意力机制的核心。

具体解释如下:

  1. querykey
    • querykey 是嵌入向量,它们的维度通常为 (batch_size, nhead, seq_len, head_dim)
    • query 是用于寻找相关性的信息,而 key 是与 query 进行匹配的对象。通过计算 querykey 的点积相似度,模型可以判断输入序列中不同位置之间的关系。
  2. key.transpose(-2, -1)
    • key 的维度为 (batch_size, nhead, seq_len, head_dim)
    • key.transpose(-2, -1)key 的最后两个维度进行转置,结果的维度为 (batch_size, nhead, head_dim, seq_len)。这样可以确保矩阵乘法的维度匹配。
  3. torch.matmul(query, key.transpose(-2, -1))
    • 计算 querykey 的矩阵乘法,其结果为注意力得分矩阵。
    • 计算出的矩阵的维度为 (batch_size, nhead, seq_len, seq_len),表示序列中每个位置与其他位置的相关性。
    • 每个注意力头会得到一个 seq_len x seq_len 的得分矩阵,其中每个元素代表输入序列中某个位置与另一个位置的相似度。

总结来说,这段代码的作用是计算 querykey 的点积来衡量相似度,从而帮助模型确定在自注意力机制中每个位置应该关注序列中的哪些部分。

torch.matmul(attn_weights, value) 这段代码的作用是应用注意力权重到值(value)上,从而生成最终的注意力输出。

具体解释如下:

  1. attn_weights
    • attn_weights 是通过 querykey 之间的点积计算得出的注意力权重。
    • 它的维度通常为 (batch_size, nhead, seq_len, seq_len),表示每个序列中每个位置对其他位置的注意力强度。
    • 这个权重矩阵表明在生成每个序列位置时,应该关注序列中其他位置的程度。
  2. value
    • value 是输入嵌入的一部分,维度通常为 (batch_size, nhead, seq_len, head_dim)
    • 它提供了被注意的内容,attn_weights 通过选择性加权的方式来对这些内容进行组合。
  3. 矩阵乘法 torch.matmul(attn_weights, value)
    • 操作torch.matmul(attn_weights, value) 进行矩阵乘法,使用注意力权重加权 value 向量。
    • 结果:输出的维度为 (batch_size, nhead, seq_len, head_dim),即为每个序列位置在应用注意力后的表示。
    • 意义:这一步通过注意力权重对 value 进行加权求和,使模型能够聚焦于最相关的部分,从而生成更加丰富且具有上下文相关性的输出表示。
AutoregressiveTransformer
class AutoregressiveTransformer(nn.Module):def __init__(self, vocab_size, d_model, nhead, num_encoder_layers, dim_feedforward, max_len):super(AutoregressiveTransformer, self).__init__()# 嵌入层,将标记索引转换为稠密向量self.embedding = nn.Embedding(vocab_size, d_model)# 位置编码,用于将序列信息添加到嵌入中self.pos_encoder = PositionalEncoding(d_model, max_len)# 自定义的 Transformer 编码器层,使用指定的参数encoder_layers = TransformerEncoderLayerCustom(d_model, nhead, dim_feedforward)# 堆叠多个 Transformer 编码器层self.transformer_encoder = nn.ModuleList([encoder_layers for _ in range(num_encoder_layers)])self.d_model = d_model# 线性层,将编码器的输出投影到词汇表大小self.decoder = nn.Linear(d_model, vocab_size)def forward(self, src, src_mask):# 对源标记应用嵌入层,并按 sqrt(d_model) 进行缩放src = self.embedding(src) * np.sqrt(self.d_model)# 将位置编码加到嵌入后的标记上src = self.pos_encoder(src)# 通过所有的 Transformer 编码器层for layer in self.transformer_encoder:src = layer(src, src_mask)# 将输出投影到词汇表大小output = self.decoder(src)return outputdef generate_square_subsequent_mask(self, sz):# 生成一个掩码,以防模型关注未来的位置mask = (torch.triu(torch.ones(sz, sz)) == 1).transpose(0, 1)mask = mask.float().masked_fill(mask == 0, float('-inf')).masked_fill(mask == 1, float(0.0))return mask
训练和预测的过程
def train(model, data, vocab_size, num_epochs=10, learning_rate=0.0005):# 定义损失函数为交叉熵损失criterion = nn.CrossEntropyLoss()# 使用 Adam 优化器进行训练optimizer = optim.Adam(model.parameters(), lr=learning_rate)for epoch in range(num_epochs):model.train()  # 将模型设置为训练模式total_loss = 0for batch in data:# 输入序列为除最后一个标记外的所有标记src = batch[:-1]# 目标序列为除第一个标记外的所有标记(向右移动一个位置)tgt = batch[1:]# 为输入序列生成后续掩码src_mask = model.generate_square_subsequent_mask(len(src)).to(src.device)optimizer.zero_grad()  # 在反向传播前将梯度归零# 通过模型进行前向传播output = model(src, src_mask)# 计算模型输出与目标序列之间的损失loss = criterion(output.view(-1, vocab_size), tgt.view(-1))# 反向传播损失loss.backward()# 更新模型参数optimizer.step()total_loss += loss.item()# 打印每个 epoch 的平均损失print(f"Epoch {epoch+1}, Loss: {total_loss / len(data)}")def predict(model, start_token, max_len, vocab_size):model.eval()  # 将模型设置为评估模式generated_sequence = [start_token]  # 使用起始标记初始化生成的序列# 使用起始标记创建初始输入张量src = torch.tensor([start_token]).unsqueeze(1)  # 形状为 (seq_len, batch_size)for _ in range(max_len - 1):# 为当前输入序列生成掩码src_mask = model.generate_square_subsequent_mask(len(src)).to(src.device)# 通过模型进行前向传播output = model(src, src_mask)# 获取具有最高概率的标记作为下一个标记next_token = torch.argmax(output[-1, 0, :], dim=-1).item()# 将预测的标记添加到生成的序列中generated_sequence.append(next_token)# 通过添加新标记更新输入序列src = torch.cat([src, torch.tensor([[next_token]])], dim=0)return generated_sequence# 超参数
vocab_size = 100  # 示例词汇表大小
d_model = 32  # 嵌入向量的维度
nhead = 2  # 注意力头的数量
num_encoder_layers = 2  # Transformer 编码器层的数量
dim_feedforward = 64  # Transformer 中前馈网络的维度
max_len = 20  # 输入序列的最大长度# 实例化模型
model = AutoregressiveTransformer(vocab_size, d_model, nhead, num_encoder_layers, dim_feedforward, max_len)# 示例数据(随机生成,仅用于演示)
data = [torch.randint(0, vocab_size, (10,)) for _ in range(100)]# 训练模型
train(model, data, vocab_size, num_epochs=10)# 预测序列
start_token = 1  # 序列生成的起始标记
generated_sequence = predict(model, start_token, max_len, vocab_size)
print("Generated Sequence:", generated_sequence)

上述代码中一些难点的解释:

torch.tensor([start_token]).unsqueeze(1) 的作用是将 start_token 转换为一个形状适合于模型输入的张量。具体步骤如下:

  1. torch.tensor([start_token])

    • 创建一个包含 start_token 的 1D 张量。假设 start_token1,那么这一步生成的张量为 [1],其形状为 (1,)
  2. .unsqueeze(1)

    • .unsqueeze(1) 用于在张量的第一个维度之后插入一个新的维度,使得张量的形状从 (1,) 变为 (1, 1)
    • 在这个上下文中,新的维度用于模拟批次维度(batch size)。因此,结果是一个形状为 (seq_len, batch_size) 的张量,其中 seq_len=1batch_size=1

生成的张量形状为 (1, 1),表示一个序列长度为 1、批大小为 1 的张量,这样它可以作为模型的输入。在序列生成任务中,通常需要明确批次维度,即使批大小只有 1,这也是保持代码通用性和与模型输入接口兼容的常见做法。

next_token = torch.argmax(output[-1, 0, :], dim=-1).item() 的作用是从模型的输出中获取下一个最可能的标记。具体解释如下:

  1. output[-1, 0, :]
    • output 的形状通常是 (seq_len, batch_size, vocab_size)
    • output[-1, 0, :] 表示取最后一个时间步(即当前预测的词),对于第一个样本(批大小为 1 的情况下就是唯一的样本),从词汇表中获取所有词的概率分布。
    • output[-1, 0, :] 的结果是一个长度为 vocab_size 的张量,表示最后一个时间步生成的每个词的概率。
  2. torch.argmax(output[-1, 0, :], dim=-1)
    • torch.argmax(..., dim=-1) 会返回概率最大的元素的索引,这意味着它会找到最可能的下一个词的索引(即具有最高概率的词汇表中的词)。
    • 这一步的结果是一个整数值,表示词汇表中最有可能的词的索引。
  3. .item()
    • .item() 将单元素张量转换为 Python 标量。最终的 next_token 是一个整数,表示模型预测的下一个标记的索引。

总结来说,这段代码的作用是从模型的输出中找到下一个最可能的词的索引,然后将其用于序列的下一步生成。在预测阶段,模型根据这个最可能的词来不断扩展生成的序列。

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

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

相关文章

S2 引擎-大数据分析表格

一、特性 1)开箱即用:提供不同场景下开箱即用的 React, Vue3 表组件及配套分析组件,只需要简单的配置即可轻松实现复杂场景。 2)多维交叉分析: 告别单一分析维度,全面拥抱任意维度的自由组合分析。 3&#…

数据脱敏方案总结

什么是数据脱敏 数据脱敏的定义 数据脱敏百度百科中是这样定义的: 数据脱敏,指对某些敏感信息通过脱敏规则进行数据的变形,实现敏感隐私数据的可靠保护。这样就可以在开发、测试和其它非生产环境以及外包环境中安全地使用脱敏后的真实数据集…

YOLOv11模型改进-注意力-引入简单无参数注意力模块SimAM 提升小目标和遮挡检测

本篇文章将介绍一个新的改进机制——卷积和注意力融合模块SimAM ,并阐述如何将其应用于YOLOv11中,显著提升模型性能。首先,SimAM 是一种用于卷积神经网络的简单且无参数的注意力模块,它基于神经科学理论定义能量函数来计算 3-D 注…

若依框架的下载与配置

1. 若依版本 RuoYi-Vue前后端分离版。 2. 框架下载 2.1 后端框架下载 https://gitee.com/y_project/RuoYi-Vue 2.2 前端框架下载 https://github.com/yangzongzhuan/RuoYi-Vue3 3. 数据库配置 3.1 创建数据库 基于MySQL数据库,创建数据库:ry-vu…

Top Down 2D Dojo Chip Set

以下是对这款 2D 微型像素关卡芯片集的简洁介绍: 这是一款基于 8x8 像素网格的 2D 微型像素关卡芯片集,采用经典的像素风格。它包含 66 个.png 格式的芯片,涵盖多种墙壁和门的变体,非常适合用于快速搭建游戏原型的道场关卡。利用…

gazebo显示urdf

最近想要将urdf显示在gazebo中。也就是实现下面这样的效果。 因为我看到网上&#xff0c;很多都是在rviz中显示urdf文件。 <launch><!-- 将 Urdf 文件的内容加载到参数服务器 --><param name"robot_description" textfile"$(find urdf_gazebo)/…

【GAMES101笔记速查——Lecture 17 Materials and Appearances】

目录 1 材质和外观 1.1 自然界中&#xff0c;外观是光线和材质共同作用的结果 1.2 图形学中&#xff0c;什么是材质&#xff1f; 1.2.1 渲染方程严格正确&#xff0c;其中BRDF项决定了物体的材质 1.2.2 漫反射材质 &#xff08;1&#xff09;如何定义漫反射系数&#xff1…

mysql8以上版本第一次下载后的登录问题

mysql8以上版本第一次下载后的登录问题 在官网下载mysql后&#xff0c;按照MySQL下载和安装教程操作就可以 如果出现问题&#xff0c;参考https://blog.csdn.net/weixin_63107823/article/details/136588474 注意ini配置文件&#xff0c;如果你是复制的别人的代码&#xff0…

ESD防静电闸机如何保护汽车电子产品

随着汽车电子技术的快速发展&#xff0c;汽车中集成了越来越多的电子设备&#xff0c;如车载信息娱乐系统、自动驾驶传感器、驾驶辅助系统等。静电放电可能导致电子组件的损坏、性能下降&#xff0c;甚至使整个系统失效。因此&#xff0c;如何有效保护汽车电子产品免受静电损害…

2024 四川省大学生信息安全技术大赛 安恒杯 部分 WP

文章目录 一、前言二、MISCunzip-png拓展 第47张图片重要的文件 三、WEB四、CRYPTO五、REVERSE 一、前言 WP不完整&#xff0c;仅供参考&#xff01; 除WEB外&#xff0c;其余附件均已打包完毕&#xff0c;在这里也是非常感谢师傅的附件支持&#xff01; 123网盘下载&#x…

Web应用框架-Django应用基础(2)

1.请求响应对象 1.1 请求对象HttpRequest测试 #hello\views def http_request(request):#1.获得请求方式print(request.method)#2.获得请求头信息#2.1 获取META中的请求头信息headers request.METAprint(headers)#2.2 获取请求头信息的内容ua request.META.get(HTTP_USER_AG…

[已解决] pycharm添加本地conda虚拟环境 + 配置解释器 - pycharm找不到conda可执行文件

目录 问题&#xff1a; 方法&#xff1a; 补充&#xff1a;创建conda虚拟环境 参考文档&#xff1a;pycharm找不到conda可执行文件怎么办&#xff1f;-CSDN 问题&#xff1a; 1.显示&#xff1a;未为项目配置 Python 解释器 2.想在pycharm中使用本地创建的虚拟环境 方法&a…

通过前端UI界面创建VUE项目

通过前端UI界面创建VUE项目&#xff0c;是比较方面的一种方式&#xff0c;下面我们详细分析一下流程&#xff1a; 1、找到合适目录 右键鼠标&#xff0c;点击在终端打开 2、开始创建 输入 vue ui 浏览器弹出页面 3、点击Create项目 显示已有文件列表&#xff0c;另外可以点击…

ChatGLM4重磅开源! 连忙实操测试一波,效果惊艳,真的好用!附带最新相关资料和喂饭级实操推理教程!!

本文目录 GLM4重磅开源啦 GLM4系列版本介绍 GLM4大模型能力测评结果 经典测评任务结果 长文本能力 工具调用能力 多模态能力 手把手实操GLM-4-9B-Chat推理预测&&效果展示 GLM4运行硬件和环境要求 配置对应的库环境 使用peftbitsandbytes 进行4位量化推理 进…

【大模型报告】2024年中国AI大模型场景探索及产业应用调研报告【免费下载】

1.行业概况 市场规模&#xff1a; 2023年中国AI大模型行业规模达到147亿元&#xff0c;预计到2028年将突破1000亿元&#xff0c;复合增速超过50%。 应用价值&#xff1a; AI大模型技术能够提升生产要素的产出效率&#xff0c;并提高数据要素在生产要素组合中的地位。 应用路…

本地生活便民信息服务小程序源码系统 PHP+MySQL组合开发 带完整的安装代码包以及搭建部署教程

系统概述 地方门户分类信息网站源码系统是一个基于PHP和MySQL开发的强大平台&#xff0c;旨在帮助用户轻松搭建地方性的分类信息网站。该系统集成了众多实用功能&#xff0c;支持用户自由发帖、浏览和搜索各类信息&#xff0c;如二手交易、求职招聘、房屋租售、生活服务、商家…

Git核心概念图例与最常用内容操作(reset、diff、restore、stash、reflog、cherry-pick)

文章目录 简介前置概念.git目录objects目录refs目录HEAD文件 resetreflog 与 reset --hardrevert(撤销指定提交)stashdiff工作区与暂存区差异暂存区与HEAD差异工作区与HEAD差异其他比较 restore、checkout(代码撤回)merge、rebase、cherry-pick 简介 本文将介绍Git几个核心概念…

ubuntu22.04下GStreamer源码编译单步调试

前言 本文会通过介绍在linux平台下的GStreamer的源码编译和单步调试example实例。官网介绍直接通过命令行来安装gstreamer可以参考链接&#xff1a;Installing on Linux。 这种方法安装后&#xff0c;基于gstreamer的程序&#xff0c;单步调试的时候并不会进入到gstreamer源码…

李飞飞:不要数字孪生,要数字表兄弟,一张照片生成机器人训练场景

我们很多人都听说过数字孪生&#xff08;digital twin&#xff09;&#xff0c;在英伟达等公司的大力推动下&#xff0c;这种高效运营工作流程的方法已经在很多工业场景中得到应用。 但你听说过数字表亲&#xff08;digital cousin&#xff09;吗&#xff1f; 近日&#xff0…

2024年【浙江省安全员-C证】复审考试及浙江省安全员-C证证考试

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 浙江省安全员-C证复审考试是安全生产模拟考试一点通总题库中生成的一套浙江省安全员-C证证考试&#xff0c;安全生产模拟考试一点通上浙江省安全员-C证作业手机同步练习。2024年【浙江省安全员-C证】复审考试及浙江省…