s之llamafromscratch:llamafromscratch从头开始利用pytorch来实现并解读a

LLMs之llama3-from-scratch:llama3-from-scratch(从头开始利用pytorch来实现并解读LLaMA-3模型的每层代码)的简介、核心思路梳理

导读:这篇论文实现了transformer网络的llama3模型,从头开始利用pytorch来实现该模型。

背景:目前机器学习语言模型内容的复杂性不断增强,但是大多模型都是基于高度抽象和封装的框架来实现,对模型内部工作机制的理解不是很深入。这篇论文采用从零开始逐步实现的方式,帮助读者更好地理解transformer和llama3模型是如何工作的。

具体解决方案:作者加载了llama3预训练模型的参数,并按照每个算子依次实现。

流程和关键步骤:

>> 加载tokenizer对文本进行tokenize

>> 从模型文件加载各层参数

>> 对输入文本的tokens生成嵌入向量

>> 对嵌入向量进行RMSNorm标准化

>> 实现单头注意力机制,包括Q、K、V矩阵的生成、位置编码、掩码、softmax计算注意力权重等

>> 循环实现多头注意力

>> 加载FFN层的参数实现前向传播

>> 循环上述步骤实现整个模型

>> 应用训练好的输出层参数进行预测

关键技术点

>> 利用RoPE位置编码为Q、K向量添加位置信息

>> 多头注意力分头计算并拼接

>> SwiGLU结构的FFN层

>> 应用RMSNorm进行标准化

>> 循环实现每一层的计算

>> 代码运行效果

>> 最后利用加载的llama3模型在样本问题"答案是什么"上正确预测答案为42,验证了从零开始实现的整个流程是正确的。

总之,这篇论文采用详尽清晰的流程,帮助读者通过实际实现深入理解transformer模型底层工作机制,是一篇值得推荐的论文。

GitHub地址:GitHub - naklecha/llama3-from-scratch: llama3 implementation one matrix multiplication at a time

简介

我不会实现一个BPE分词器(但是Andrej Karpathy有一个非常简洁的实现)

链接到他的实现:

该项目给出了一个针对中文分词任务的最小化、清晰而可读的Python实现Byte Pair Encoding(BPE)算法的代码库。它实现了两个Tokenizer对象用于文本到词元和词元到文本的转换:BasicTokenizer和RegexTokenizer。 BasicTokenizer直接在文本上运行BPE算法,RegexTokenizer在BPE之前通过正则表达式将文本切分为不同类型(如字母、数字、标点等)以防止词汇跨类型合并。

思路步骤

从Meta下载权重文件。

使用tiktoken库加载BPE分词器,并定义特殊token。

核心技术点

BPE分词:字节对编码(Byte Pair Encoding)是一种常见的分词方法,用于处理词汇表。

目的是设置和测试一个自定义的tokenizer,它能够处理文本数据

设置路径和特殊标记:

加载BPE(Byte Pair Encoding)模型:

创建tokenizer对象:

解码和编码测试:

简介

通常情况下,读取模型文件取决于模型类的编写方式和其中的变量名称。但由于我们要从头实现llama3,所以我们将逐个张量读取文件。

我们使用此配置来推断模型的细节,模型有32个Transformer层,每个多头注意力块有32个头,n_kv_heads,词汇表大小为128256等等。

下面是各个参数的含义:

思路步骤

加载模型文件,查看模型参数。

读取模型配置文件,获取模型的详细参数。

核心技术点

配置解析:解析配置文件以提取模型超参数。

简介

这里我们使用tiktoken(我认为是OpenAI的库)作为分词器。

思路步骤

输入一个提示文本,并使用分词器将其转换为tokens。

打印tokens及其对应的文本表示。

核心技术点

分词:使用分词器将文本转换为token ID。

文本表示:解码token ID为文本以验证分词过程。

简介

这是代码库中唯一使用内置神经网络模块的部分。

我们的[17x1] tokens现在是[17x4096],即17个长度为4096的嵌入(每个token一个嵌入)。

注意:跟踪形状,这使它更容易理解一切

思路步骤

定义一个嵌入层,并加载预训练的权重。

将tokens转换为嵌入表示。

核心技术点

简介

我们然后使用RMS归一化嵌入,请注意此步骤后形状不会改变,值只是被归一化了。需要注意的是我们需要一个norm_eps(从配置中获取),因为我们不想意外地将rms设为0并除以0。

公式如下:

归一化后我们的形状仍然是[17x4096],与嵌入相同但已归一化。

思路步骤

对嵌入进行RMS归一化。

核心技术点

RMS归一化:对嵌入向量进行均方根归一化(RMS Norm)。

简介

您会看到我从这个模型字典中访问layer.0(这是第一层) 无论如何,所以归一化后,我们的形状仍然是【17x4096】,与嵌入相同但已归一化

思路步骤

构建Transformer的第一层:

核心技术点

多头注意力机制(Multi-Head Attention)与残差连接

Transformer层:应用注意力机制和前馈神经网络进行特征提取和变换。

简介

让我们加载Transformer第一层的注意力头。

>> 加载查询Query、键Key、值Value和输出向量时,我们注意到它们的权重矩阵形状分别为[4096x4096]、[1024x4096]、[1024x4096]、[4096x4096]。

>> 乍一看这有点奇怪,因为我们理想情况下希望每个Query、Key、Value和输出分别对应每个头。而代码作者将它们捆绑在一起,因为这样做,有助于并行化注意力头的矩阵乘法。

接下来,我将展开所有内容...

下一步,我将展开多个注意力头的查询,结果形状为[32x128x4096]。

这里,32是llama3的注意力头数,128是Query向量的大小,4096是token嵌入的大小。

这里我访问第一层第一个头的Query权重矩阵,Query权重矩阵的大小为【128x4096】。

我们现在,将Query权重【128x4096】与token嵌入【17x4096】相乘,以接收token的查询,即获得每个token的query。

结果形状为[17x128],因为我们有17个token,每个token有一个128长度的query向量。

思路步骤

通过查询、键和值向量计算注意力分数,提取输入中重要的信息。

加载第一层的查询、键、值和输出向量权重。

展开注意力头的查询权重矩阵。

计算token的查询向量。

核心技术点

自注意力(Self-Attention)的计算。

痛点:现在,已经为prompt中的每个token生成了query向量,但每个单独的query向量并不知道它在prompt中的具体位置。我们现在处于每个token在我们的提示中有一个查询向量的阶段,但如果你想一想——单个查询向量对提示中的位置没有任何了解。例如:

期望:在我们的提示中我们使用了三次“the”,我们需要所有3个“the”token的查询向量(每个大小为[1x128])根据它们在查询中的位置具有不同的query向量。

解决方案:采用RoPE(旋转位置嵌入)执行这些旋转操作。

简介

在上述步骤中,我们将查询向量分成了若干对,并对每对应用一个旋转角度偏移!

现在我们有一个大小为[17x64x2]的向量,这是将128长度的query向量,对每个prompt中的每个token分成的64对,这64对中的每一对都会按照m*(theta) 进行旋转,其中m是要为其旋转query的token的位置!

使用复数的点积来旋转向量

现在我们为每个token的query元素得到了一个复数(角度变化向量),我们可以将我们的query(即我们之前分成的对)转换为复数,然后使用点积根据位置旋转query向量。

老实说,想到这一点真是太美妙了 :)

在获得旋转后的向量后,我们可以通过将复数,重新视为实数,来得到(或来还原)成对的query向量。

旋转后的对现在被合并,我们现在有了一个新的query向量(旋转后的query向量),其形状为 [17x128],其中17是token的数量,128是query向量的维度。

准备基向量:

基向量定义为一个由二维位置(p)索引的表情形(对于大小为128的嵌入,生成的形状为[64])。此基向量本质上是一个在0到θ之间等距离的线性间隔。

为提示生成旋转向量

为了生成旋转向量,我们将基向量乘以0到16之间的整数,这些整数是我们提示中token的位置。此乘法后的结果形状为[17x64],其中每行表示token的旋转向量。

应用RoPE到查询向量

最后,我们可以将我们的查询向量与旋转向量结合,生成位置编码的查询向量。每个查询向量现在被旋转以反映它们在提示中的位置。

最终位置编码的查询向量

我们现在有一个大小为[17x128]的查询向量,每个token都有它在提示中位置的旋转编码。

思路步骤

生成RoPE(旋转位置嵌入)以编码token的位置信息。

将查询向量与位置编码向量结合,生成位置编码的查询向量。

核心技术点

旋转位置编码(RoPE):使用旋转位置嵌入(RoPE)将位置信息编码到查询向量中。

向量旋转:使用cos和sin函数对查询向量进行旋转,结合位置编码信息。

简介

查询Query、键Key、值Value和输出向量

思路步骤

Key键向量生成

>> key向量维度为128。

>> key的权重共享机制,key的权重只有query的四分之一,,这是因为每4个头共享一次,以减少计算量。

>> key向量也进行旋转以加入位置信息,原因与query相同。

Query向量生成及旋转,增加位置信息。

查询向量与键向量的维度匹配。

旋转操作用于引入位置编码。

在这个阶段,我们现在有了每个token旋转后的query和key,其中每一个query和key现在的形状是[17x128]。

核心技术点

矩阵乘法与旋转位置编码

简介

查询Query、键Key、值Value和输出向量

1、计算注意力分数矩阵:在下一步中,我们将Query和Key矩阵相乘,这样做会给我们一个分数矩阵,将每个token与另一个token映射或关联起来。这个分数矩阵描述了每个token的query与每个token的key之间的关系有多好(相关性),这就是自注意力机制(Self Attention)。其中,分数矩阵(qk_per_token)的形状是[17x17],其中17是prompt中的token数量。

2、对注意力分数矩阵中的未来token进行掩码处理:然后,我们现在必须对Query-Key分数进行掩码处理,在llama3的训练过程中,未来token的qk分数会被屏蔽。 为什么?因为在训练过程中,我们只学习使用过去的token来预测未来token。 因此,在推理时,我们将未来token的评分设置为0。

思路步骤

计算Query向量与Key向量之间的匹配得分,即自注意力得分。

使用矩阵乘法和归一化。

自注意力的核心机制:查询-键匹配得分。

训练过程中掩盖未来的token,确保只使用过去的token进行预测。

上三角掩码矩阵,屏蔽未来token。

核心技术点

分数计算与未来词元掩码

简介

查询Query、键Key、值Value和输出向量

接下来是value,接近注意力机制的最后一步。

思路步骤

这些分数(0-1)用于确定每个token使用多少value矩阵。就和key一样,value权重也在每4个注意力头之间共享(以节省计算)。因此,下面的Value权重矩阵的形状是[8x128x4096] 。

第一层,第一个注意力头的Value权重矩阵如下所示

Softmax 归一化得到注意力权重:对掩码后的得分进行Softmax归一化,得到注意力权重。

使用Softmax函数将得分转换为概率分布。

Values(值向量)计算:使用Value向量和注意力权重计算最终的注意力输出。Value向量与Query和Key向量的共享机制。

注意力计算:现在使用Value权重来获取每个token的注意力值,矩阵的大小是[17x128],其中17是prompt中的token数量,128是每个token的value向量的维度。

注意力:与每个token的value相乘后得到的注意力向量的形状为[17x128]。

核心技术点

分数与值的权重合并

值向量的矩阵乘法

简介

我们现在有了第一层中第一个头的注意力值,然后,将运行一个循环,并对第一层中的每一个头执行与上述单元格完全相同的数学运算。

然后,得到了第一层所有32个头的qkv_attention矩阵,接下来我将把所有的注意力分数合并成一个大的矩阵,其大小为[17x4096]

我们快要结束了!

思路步骤

多头注意力机制:对每个注意力头分别计算注意力输出,并将其拼接。

多头注意力的并行计算和拼接。

线性层变换:通过线性变换将拼接后的多头注意力输出进行进一步处理。

线性层的矩阵乘法。

核心技术点

向量的拼接

简介

查询Query、键Key、值Value和输出向量

思路步骤

对于第0层注意力机制的最后步骤,其一是将注意力得分矩阵与权重矩阵相乘。

这是一个简单的线性层,所以我们只需进行矩阵乘法

核心技术点

线性层(全连接层)的应用。

简介

查询Query、键Key、值Value和输出向量

现在,我们有了注意力后嵌入Value的变化,应该加到原始的token嵌入中;

然后,对嵌入增量进行归一化,然后通过嵌入增量运行一个前馈神经网络;

思路步骤

核心技术点

残差连接

简介

在Llama3中,加载前馈权重并实现前馈网络。使用了一种名为SwiGLU的前馈网络,这种网络结构在模型需要的时候,能够有效地增加非线性。 在当今的LLMs中,使用这种前馈网络架构已经相当标准。

思路步骤

归一化与前馈网络:对注意力输出进行归一化,并通过前馈神经网络进行非线性变换。

RMSNorm归一化。

SwiGLU前馈网络,用于增强非线性表达能力。

核心技术点

SwiGLU激活函数与线性层

简介

查询Query、键Key、值Value和输出向量

我们终于在第1层之后为每个词元获得了新的编辑后的嵌入。我们还有31层才能完成(还需要一个循环)。

你可以将这个编辑后的嵌入,想象成包含了第一层中所有Query信息的嵌入。随着层数的增加,每一层都会对输入的信息进行越来越复杂的处理,直到最终得到一个,能够全面了解下一个需要预测的token的嵌入。

天哪,一切都集中在一起了

是的,就是这样。我们之前所做的所有事情,现在一次性为每个层都做了

思路步骤

重复以上步骤,处理所有Transformer子层

核心技术点

循环与层堆叠

循环迭代处理每一层。

简介

思路步骤

核心技术点

矩阵乘法,线性变换。

最终归一化处理

简介

生成最终的嵌入向量,用于预测下一个token的最优预测。这个嵌入的形状与常规的token嵌入相同,为[17x4096],其中17是token的数量,4096是嵌入的维度。

思路步骤

确认logits张量的形状:确保计算得到的logits具有正确的维度,以便后续处理。

核心技术点

线性层与softmax激活函数

简介

我们将使用输出解码器,将最终嵌入转换为token值,使用输出解码器将最终的嵌入转换成一个token。确认输出解码器的尺寸是否正确,确保矩阵乘法可以顺利进行。

使用最后一个词元的嵌入通过矩阵乘法预测下一个令牌的概率分布。

通过最后一个令牌的嵌入和输出解码器权重矩阵的乘法,计算出每个可能令牌的logits。

思路步骤

获取预测的下一个令牌的索引,通过argmax函数从logits中选择概率最高的令牌,来确定下一个令牌,得到最终的预测结果。

核心技术点

分词器的逆过程

argmax函数,分类问题中的预测。

期望:使用最后一个token的嵌入来预测下一个value,希望预测的结果是42。加载的llama3模型在样本问题"答案是什么"上正确预测答案为42,验证了从零开始实现的整个流程是正确的。

希望在我们这个例子中,是42 :)

方法:查看预测的下一个令牌是否为“42”

注意:因为根据《银河系漫游指南》一书中的说法,42是“生命、宇宙及一切的终极问题的答案”。大多数现代LLM在这里都会回答42,这将验证整个代码的正确性。

简介

模型预测下一个词元是token编号2983,这是42的token ID吗?

THE END
0.ScratchDesktop下载ScratchDesktop官方版下载下载前请确认本软件为电脑版《Scratch Desktop》是一款很实用的编辑器,编辑器使用者能够创造出属于自己的互动媒体,把自己编写的故事、动画和游戏分享给世界各地的伙伴们,还提升对用户编程的兴趣和学习能力,对于学习编程的用户来说是一个很方便的软件。 最新功能 1、内核更新 Scratch Desktop官方版使用H5和JS语言编jvzquC41o09eopfog0ipo8xqhv52;?6620nuou
1.ScratchDesktop3.6.0下载ScratchDesktop3.6.0官方下载《Scratch Desktop(积木编程软件) 3.6.0》是一款游戏设计的软件,用户可以在该软件上制作简单的二维游戏,还支持故事设计功能,功能非常强大丰富,操作也很简单,是一款很不错的软件,有需要的快来下载吧! 软件截图 软件功能 1、Scratch Desktop提供动画设计功能,通过这款软件学习如何通过编程设计动画 jvzquC41uqlu0
2.上安装scratch3.0编程软件scratch平板版下载3·0文章浏览阅读6.4k次,点赞5次,收藏10次。在ipad上无法安装exe和dmg文件,所以不能在它上面安装scratch3.0。为了解决这个问题,可以让学生在ipad上下载scratch studio,跟scrtch3.0是一样的,下载方法如下。_scratch平板版下载3·0jvzquC41dnuh0lxfp0tfv8fdknoya}tp{1gsvrhng1jfvjnnu1756:;98:9
3.Scratch3.0手机版下载Scratch3.0appv3.0.66最新版腾牛·下载 首页| 软件| 游戏| 排行| 专题 Scratch3.0 app大小:75.2M语言:中文 类别:学习教育系统:Android 点击下载简介|教程|评论(0) 版本:v3.0.66 最新版时间:2024-07-24 应用介绍 Scratch3.0 app是一款编程设计学习软件,软件可以帮助用户创作故事,游戏和动画,可以帮助学习到创造性的思考力,觉得不错的朋友jvzquC41o0wrvw3eqo5r1@>78;?
4.scratch平板版下载3.0扫描访问手机版 应用介绍 应用截图 下载地址 网友评论 应用标签: scratch编程app学习app scratch少儿编程平板电脑版有好多好多有趣的课程呢,大家可以根据自己学习的进度,挑自己喜欢的课题来学。在这里呀,不仅能看课程,还能自己动手练习,把学到的知识用到实际当中去。 scratch平板版介绍 Scratch是一个程序设计语言,jvzq<84yyy4kzmtyp0ipo8xqhv522>8;20nuou
5.Scratch3With Scratch, you can program your own interactive stories, games, and animations.jvzquC41yy}/orhtquugv7hqo1ko/rj1r1ydtjyej/90;ykil4;kn?}5
6.猿编程HD平板端下载猿编程HD官方下载v5.9.0最新版本3、完成后点击立即登录 4、最后就能够进入到页面进行体验了 软件介绍 猿编程平板端是一款专为 7-12 岁青少年设计的编程教育产品,由猿辅导在线教育荣誉出品,旨在培养人工智能时代下掌握编程语言、计算思维、创造能力和未来视野的科技少年,软件将计算思维全面应用到编程知识学习的各个环节,关注编程知识在游戏、数据分析、jvzq<84yyy47nu3eqo5tqoy158:277mvon
7.→台风模拟器typhoonscratch下载1.0最新版v1.0.0安卓版应用版本:v1.0.0安卓版 应用语言:中文 应用等级: 应用授权:免费软件 官方网址:暂无 厂商: 台风模拟器typhoon scratch下载1.0最新版,是一款非常有趣的模拟游戏,它提供了丰富的挑战和新的形状解锁,让玩家可以享受攻击城市的破坏乐趣。同时,游戏也向玩家传达了尊重自然的重要信息。如果您对这款游戏感兴趣,不妨来289下载jvzquC41o089;7hqo1ohcvj175=19=3jvor
8.scratch2.0下载scratch2.0软件下载v3.5.0scratch2.0版本: v3.5.0 学习 下载163.2 MB暂无 ⼿机⼆维码扫描下载 纠错举报我要认领 图片 介绍 相关标签: #学习 #教育 #编程 scratch2.0是专门为儿童设计的编程软件,家长每天可以为孩子挑选合适的内容,都可以随时学习编程,还有各种有趣的小游戏,也能为孩子提供非常好的教学内容。程序指令不多,职业是移动,旋jvzquC41yy}/i~lw|j{/exr1crvmg89677<20qyon
9.scratch3.0中文官方下载介绍相关推荐 评论(3)儿童编程软件 scratch3.0中文官方版是款超级好用的儿童编程软件!强大的功能,化繁为简,上手容易,可以让孩子们从基础编程学起,通过它能够创作许多的东西,比如动画、游戏、故事等等,自由发挥,提升自我创作能力! 软件介绍 Scratch是由MIT(麻省理工学院)米切尔·瑞斯尼克(Mitch Resnick)教授带领的“jvzquC41o0ouoxu0eqs0fx|pkplp1<:995>/j}rn
10.mDesigner3图形编程软件v2.1.0官方版下载mDesigner 3图形编程软件 v2.1.0官方版 <> 好玩 0 坑爹 0 应用语言:中文 应用大小:273M 更新时间:2021-12-02 11:40 发行时间: 应用类型:普通 应用标签:编程 mDesigner是一款基于Scratch3.0开发的编程软件,在原来基础上增加Arduino、Python代码编程、AI(人工智能)和IoT(物联网)等功能,使用简单方便,可以轻松控制jvzquC41yy}/h}|0eun1|thv1<56B540jznn
11.画质box准星免费版下载无广告画质box准星免费版是一款游戏辅助软件!画质box准星免费版app所有这些功能都可以免费使用,使玩家能够轻松地调整游戏画面的亮度、对比度和饱和度等参数,通过一键优化功能,你可以快速调整游戏画面,使其更加逼真、细腻,让你仿佛身临其境般沉浸在游戏世界中,还可以使用准星定位功能,从而提高射击的精准度,感兴趣的用户还等什么!jvzquC41crv/5mricok/exr1cpjsqri158;69<3jvor
12.scratch30编程5愤怒的小鸟课件.pptscratch3-0编程5- 愤怒的小鸟 课件.ppt,课堂总结 (3) 将某角色移到舞台区的最前面,防止被其他角色挡住。 拓展巩固 5 尝试添加多个小猪,让游戏角色更加丰富一些。 拓展巩固 知识从点滴累积 2023年新版 * # (等同学们全部到齐之后,统一播放此页面) * * 上节课我们实现了jvzquC41o0hpqt63:0ipo8mvon532;8126651A6362:33;72276657xjvo
13.Scratch3forMac(超火的儿童编程学习软件)v3.25.0中文版一款超火的儿童编程学习软件推荐给大家,scratch中文版是一款由麻省理工学院(MIT) 设计开发的一款面向少年的简易编程工具。scratch软件针对8岁以上孩子们的认知水平,以及对于界面的喜好,MIT做了相当深入研究和颇具针对性的设计开发,不仅易于孩子们使用,又能寓教于乐,让孩子们获得创作中的乐趣。 Scratch 3 for Mac下载 jvzquC41yy}/fxzdcp4dqv4itq{q1}trke53:A55;67:1
14.scratch3.5中文版下载ScratchV3.5.0官方最新版下载网友评论下载地址收藏该页 scratch3.5中文版是一款针对少儿打造的编程软件。该软件在这个版本中有着全新的界面,你可以编写属于你的互动媒体,像是故事、游戏、动画,然后你可以将你的创意分享给全世界,现在已经有来自世界各地的青少年们编程并共享了超过1500万个Scratch项目了。 jvzquC41yy}/fx|pzkg/exr1fq}okwkq14>:4?<0jvsm
15.ucode4官方下载ucode4编程软件下载v1.15.08安卓版1.新增 适配多款平板 2.开放 硬件插件中心、新增多款硬件插件 3.优化 AI视觉识别效率 4.优化 ucdx作品加载逻辑 5.优化 硬件设备代码烧录的交互与逻辑 6.修复 多个bug 7.其他 性能优化与提升 应用截图 <> 多平台下载 Android版 ucode4编程软件 v1.15.0-8 安卓版 jvzq<84yyy484@80eqs0fx|p15=38A3jvor
16.scratch下载scratch手机版下载v3.5.0编程手机版 游戏简介 scratch是一款功能强大的手机趣味编程app,这款软件为用户提供众多故事、动画、游戏、音乐和艺术等方面的学习,使用积木组合式的程式语言,让小朋友在游戏中学习,快来下载吧! scratch特色 1.scratch是中文语言,方便所有国内用户使用; 2.构成程序的命令和参数通过积木形状的模块来实现; 3.用鼠标拖动jvzquC41crv/cun4354og}4cpfxpkm44;4;6;7mvon
17.快科技资讯2023年02月19日Blog版资讯中心根据安谋科技2022年未经审计的收益报表显示,安谋科技在2022年的营收达到了近8.9亿美元,相比2021年的6.65亿美元同比增长了33.8%;净利润则由2021年的7920万美元暴跌了95.96%至320万美元。 需要指出的是,根据文件注释,安谋科技2022年外汇损失为3700万美元,而前一年则为900万美元正收益。 jvzquC41pg}t0v~ftk|ft|3eqo5cnxl142842;6;0jzn
18.猿编程app下载安卓版猿编程官方版下载v5.10.0安卓版Ios下载需跳转至App Store下载!应用截图Screenshot应用简介Introduction 猿编程app是为少儿提供的编程学习平台,它通过真人直播互动与AI动画引导相结合的方式,让孩子在趣味场景中掌握Python等编程语言,课程覆盖从Scratch图形化编程到人工智能应用的进阶路径,结合跨学科知识融入计算思维训练,并配套权威考级测评体系,帮助孩子系统jvzq<84o08rm0lto1uugv88863:/j}rn
19.MIT少儿编程软件Scratch33.6.0安装版deb论坛废话不多说,scratch-desktop_3.6.0_amd64.deb 的网址:链接: https://pan.baidu.com/s/1OfmK0jvzquC41ddy/fnjrkp4ptp4|j1vpu}43:86:3