1.pytorch中model、码改conv、码改linear、码改nn.Module和nn.optim模块参数方法一站式理解+finetune应用(上)
2.Hugging Face模型高效微调工具peft详解
3.我的码改世界安全插件初始化,老是码改进不去,而且初始化也一直不成功,码改喜鹊喜报源码怎么办?
4.NLP修炼系列之Bert(二)Bert多分类&多标签文本分类实战(附源码)
5.P-tuning V2论文和代码实现解析
6.Bert4keras开源框架源码解析(一)概述
pytorch中model、码改conv、码改linear、码改nn.Module和nn.optim模块参数方法一站式理解+finetune应用(上)
在深度学习编程初学者面对的码改挑战中,理解模型参数和方法是码改关键一步。本文将对PyTorch中的码改`model`, `conv`, `linear`, `nn.Module`和`nn.optim`模块的常见属性和方法进行深入解析,旨在消除疑惑,码改并提供清晰的码改理解路径。
首先,码改`model(net)`代表模型类的一个实例对象,例如 `model(net) = LeNet(3)`,这里 `LeNet` 是网络类,而数字 `3` 代表类别数量。`LeNet` 类型可能由不同开发者实现,具体细节在后续章节中会详细讨论。`Module`, `Optimizer`, `Conv2d`, `Linear` 等类则继承自 `Module`,是构成模型的基本单元。
模型类的初始化包含了8个有序字典,这些字典用于存储模型参数和结构。有序字典确保了数据的顺序性,而模型自身只直接使用 `self._parameters` 和 `self._modules` 这两个字典。
关注的主要方法包括但不限于 `add_module()`, `get_parameter()`, `modules()`, `named_modules()` 和 `parameters()` 等。这些方法提供了获取模型结构、参数信息以及执行模型更新的能力。
举例来说,构建一个简单的 `LeNet` 模型时,除了定义模型类自身和使用 `nn.Conv2d`, `nn.Linear` 等类外,这些对象都继承自 `Module` 类,因此它们都具备 `self._parameters` 和 `self._modules` 属性,以及一系列相关方法。
在 `LeNet` 的上下文中,`model.conv1`, `model.fc1` 等层同样继承自 `Module`,它们各自拥有属性和方法,全屏吸怪源码允许操作参数,如初始化 `model.conv1.weight` 使用凯明正态分布。
模型的层可被替换或调整,例如将 `model.fc3` 替换为 `nn.Linear(model.fc2.out_features, class_num)`,用于调整分类器输出数量。这些操作是模型微调过程中的常见实践。
解释清楚了模型参数的来源后,文章深入探讨了 `Conv2d` 和 `Linear` 类的参数和方法,这一部分的清晰理解有助于深入理解模型构建和参数操作。
解决参数如何进入 `self._parameters` 和 `self._modules` 属性的疑问,涉及对魔术方法如 `__setattr__`、`__getattr__`、`__delattr__`、`__getattribute__` 和 `__dict__` 的理解,以及 `getattr()` 和 `dir()` 函数的作用。
构建模型时,属性和参数会依次进入这些有序字典。以 `model.conv1 = nn.Conv2d(3, 6, 5)` 的过程为例,参数首先在 `Module` 类中存储,接着被注册到 `model` 实例的 `self._parameters` 中。若参数为 `Parameter` 类型,会进一步注册到该字典,以确保模型结构和参数的正确性。
通过理解模型属性和方法的运作机制,开发者能够更高效地构建和调整深度学习模型,提升模型性能和适应性。
以上内容为本文的主要部分,更多深入细节和源码剖析将在后续篇章中呈现。期待读者们继续探索,深化对深度学习模型构建的理解。
Hugging Face模型高效微调工具peft详解
PEFT,即Parameter Efficient Fine-Tuning,是一种模型参数高效微调技术,旨在通过减少微调参数数量和计算复杂度,提高预训练模型在新任务上的性能,从而降低大型预训练模型的训练成本。PEFT方法包括Prefix Tuning、Prompt Tuning、快排核心源码PTuning、Adapter、LoRA等技术,分别在不同阶段对模型参数进行微调,以适应特定任务需求。
在微调过程中,PEFT方法通过增加额外参数、选取部分参数更新、引入重参数化、混合高效微调等方式,来优化模型性能。例如,Prefix Tuning和PTuning在模型的每一层添加任务相关的token,训练时仅更新这些参数;Prompt Tuning简化了Prefix Tuning,仅在输入层加入提示token;Adapter Tuning在Transformer Block中加入两层MLP,只对新增Adapter结构进行微调;LoRA通过重参数化思想,仅更新部分参数,以模拟全量微调过程。
具体实现上,PEFT技术在训练阶段会通过配置文件确定使用哪种方法,如Prefix Tuning、Prompt Tuning等,而在推理阶段则无需额外参数,仅需对原有模型进行微调。这使得PEFT方法在保留模型性能的同时,显著降低了训练成本和计算资源需求。
PEFT技术在自然语言处理和图像处理任务中展现出显著效果,不仅提高了模型在新任务上的性能,而且减少了训练时间和资源消耗。随着PEFT的快速迭代开发,代码可能有所变动,因此在使用时应参考PEFT的最新版本。
要深入了解PEFT技术的实现细节,可以查看PEFT的源码,重点关注src/peft目录下的tuners文件夹,这些文件提供了各种PEFT方法的具体实现。例如,PeftModelForSequenceClassification类的四价溯源码forward函数展示了如何在推理阶段对不同PEFT方法进行操作,如根据配置文件的父类类型判断是否执行PrefixTuning或PromptTuning,并进行相应处理。此外,还有专门的文件解析和类继承关系,以实现PEFT方法的灵活应用。
通过深入研究PEFT技术及其源码,开发人员可以更好地理解如何在实际项目中利用PEFT方法提高模型性能、降低训练成本,从而在自然语言处理、计算机视觉等领域的应用中取得更优成果。
我的世界安全插件初始化,老是进不去,而且初始化也一直不成功,怎么办?
我自己不写Java,也没看过Minecraft的源码,但看过许多mod作者的吐槽,列举如下:
完全没有API的概念。所有mod都是解包后强行hack进源码,甚至要用到一堆private方法。forge/bukkit是把这个hack工作进行封装抽象,模拟了一组API。
几乎没有事件概念,连它自己用的Java网络框架(netty)的事件架构都没用上,mod要自己做个游戏内的交互界面,得自己从头到尾造轮子,包括处理鼠标事件。
完全没有多线程。有人作了全文搜索,代码里仅有的几个thread和synchronized只出现在I/O相关的地方。直到最新的几个版本更新后,才开始为区块生成做了多线程,区块/单位更新这种最急需的不知道最新版本是不是多线程了。
因为没有多线程,Minecraft的服务器是市面上极其稀有的,用酷睿比用至强性能好的,因为酷睿单核主频比志强高……然而哪怕是顶配服务器,让人同时在线就能给你卡飞……心疼所有腐竹的钱包,有这钱租服务器,资金出逃指标源码搭个魔兽私服都舒服得多。
对 OpenGL 的应用,连入门级别都算不上,OpenGL 中 glVertexBuffer 根本没使用上,导致图形性能奇差无比,于是出现了装上 OptiFine这个光影 mod 后反而帧数更高的诡异结果……因为这个游戏太流行了,几乎所有安卓系统的厂商,都不得不在 GPU 驱动里,专门为手机 Minecraft 开了个绿色通道,在 Minecraft 调用 OpenGL 接口时,系统帮忙擦屁股,把 glVertexBuffer 补上……(详见/answer/)
同上,方块渲染绘制时,根本没管方块是否可见,只要是所有暴露出来的面都会被绘制……比如区块加载未完成时能看到的地底方块……比如某些明明一马平川却能把人卡飞的地方,地底肯定有一个大型矿洞。
再同上,单线程+无优化,导致了Minecraft里万恶的区块更新策略的诞生(只有玩家角色附近的区块会更新,其他区块都是时间静止的),严重影响了机械化/工业化/红石化玩家的经营规模。
方块列表是一个数组,静态长度数组。没有方块注册接口,程序初始化时直接array[0] = new xxx(1, 3, "Dirt", ...); array[1] = new xxx(xx, xx, ...)这样把所有属性硬编码进去,如此写了几百行初始化上所有方块类型。方块的唯一标识就是数组下标,导致不同mod添加的自定义方块极容易因为下标重复而撞车。(比如某两个大型工业mod(看其他回答,这个feature终于被当作bug修复掉了?
因为根本没有API设计,所以方块的实现非常困难。实现一个新方块,需要继承自方块的基类并填充接口方法,那个基类貌似有+的接口方法……
因为上面的各个问题,导致Minecraft貌似至今都无法让一个格子里放下任意两种不同半砖的组合,因为每种组合都必须硬编码一个新方块来实现,而无法通过一个“半砖组合机制”来自动完成——建筑玩家体验极差。
药水同样是一个静态数组,同样的硬编码初始化,更惨的是,药水数组长度只有,一开始就写死了。听说有的主打药水的mod,是自己从零开始硬造了另一套药水系统,来绕过这个限制的。(这个操作似曾相识……前面说的写GUI/HUD的mod也是这么搞的)
因为没有API,不同版本之间的代码变化非常大。并且作者还头铁(或者技术不够),不肯(或者不会)二进制发布,发布的是Java包,极容易解包源码。所以作者还做了代码混淆,然而不同版本之间的代码混淆方式也不同,导致代码变动更大了——因此,Minecraft的mod更新极难无比,大多数大中型mod都是直接绑定在少数几个常用版本里的,而没法全版本适配或者迅速跟进新版本——因为每次更新后,forge/bukkit作者都得重新解包原码,重新反混淆,然后重新适配API,更新mod框架。
上一条的直接后果是,Minecraft的所有mod作者(包括不写mod的高清贴图作者,因为高清贴图依赖于mod),都是hack了游戏本身,违反了游戏软件的用户许可协议EULA。然而Mojang默许了这些行为的存在,并不去管——因为自己没本事做出稳定的API和mod框架,管了的话mod社区就不存在了,游戏就火不起来了。
某个评论都不敢开的答主居然说我们看到的代码烂因为它是反编译的,不是开发者写的源码,而且说有遮挡判断所以 drawCall 很低,性能很好?笑掉大牙了,编译优化会把一堆设计良好的类结构组成的方块系统合并成有几千行代码两百多个 API 的基类?编译优化会把方块/药水 ID 注册机制改造成静态数组?编译优化会把半砖拼接系统运行时代码干掉直接变成硬编码?编译优化会把 glVertrxBuffer 删除然后等驱动给你打补丁?编译优化会把多线程砍没?编译优化会把 netty 的事件层调用完全砍掉,让反编译呈现出没有事件系统的表现?任何一个合格的遮挡判断会在地表完全看不见时依然绘制矿洞?Minecraft 的编码水平之烂已经不是反编译能洗的了。
微软收购Mojang后,用C++基于移动版将其重写了,放到了win应用商城里。有Java正版key的用户可以到Minecraft官网上激活win应用商店版。有兴趣的可以对比一下,在win版和Java版上都开一个默认存档,进入世界,简单移动鼠标转换下视角,你就会感受到天壤之别。(话说网易和微软做了PY交易,把MC盒子包装了下美其名曰国服版,然后win应用商店版在中文区下架了……之前购买/激活了的老用户还可以用,没购买/激活的新用户,只能改系统语言跨区购买了)
再来个很残忍的对比——Minecraft之后,市面上兴起的类似设计的沙盘类游戏,除了泰拉瑞亚还是像素风,其他全特么是真·3D,而不是马赛克世界。
听说巨硬接手后1.8开始,许多问题大有改观,微软爸爸赛高!
综上所述,每一个mod作者上辈子都是折翼的天使,这辈子都是走向烈士之路的壮士
NLP修炼系列之Bert(二)Bert多分类&多标签文本分类实战(附源码)
在NLP修炼系列之Bert(二)的上一篇文章中,我们对Bert的背景和预训练模型进行了深入讲解。现在,我们将步入实战环节,通过Bert解决文本的多分类和多标签分类任务。本文将介绍两个实际项目,一个是基于THUCNews数据集的类新闻标题分类,另一个是我们公司业务中的意图识别任务,采用多标签分类方式。 1.1 数据集详解多分类项目使用THUCNews数据集,包含万个新闻标题,长度控制在-个字符,共分为财经、房产等个类别,每个类别有2万个样本。训练集包含万个样本,验证集和测试集各1万个,每个类别条。
多标签任务数据集来自公司业务,以对话形式的json格式存在,用于意图识别。由于隐私原因,我们无法提供,但网上有很多公开的多标签数据集,稍加调整即可适用。
1.2 项目结构概览项目包含Bert预训练模型文件、配置文件和词典等,可以从Huggingface官网下载。
datas 目录下存放数据集、日志和模型。
models 包含模型定义和超参数配置,还包括混合模型如Bert+CNN等。
run.py 是项目入口,负责运行训练。
train_eval.py 负责模型训练、验证和测试。
utils 提供数据预处理和加载工具。
2. 项目流程和环境要求 通过run.py调用argparse工具配置参数。安装环境要求Python 3.8,项目中已准备好requirements.txt文件。 3. 项目实战步骤 从构建数据集到模型定义,包括数据预处理、数据迭代器的创建、配置定义以及训练、验证和测试模块的实现。 4. 实验与总结 我们尝试了以下实验参数:num_epochs、batch_size、pad_size和learning_rate。在fine-tune模式下,Bert表现最佳,否则效果不佳。项目代码和数据集可通过关注布尔NLPer公众号获取,回复相应关键词获取多分类和多标签分类项目源码。P-tuning V2论文和代码实现解析
经过对清华开源的ChatGLM-6B微调,我进一步探索了P-tuning v2,并对其源码进行了深入研究,以解决其实现方式的疑问。P-tuning v2,作为Deep Prompt Tuning的优化与适应版本,旨在为生成和知识探索提供解决方案。其关键改进在于,通过在预训练模型的每一层引入连续提示,而不仅仅是局限于输入层,从而显著提升了性能,尤其针对小型模型与复杂任务。
基于作者的优化与实现细节,P-tuning v2能够实现与Fine-tuning相媲美的性能,显著扩大了其适用范围。值得注意的是,相较于Prefix tuning,P-tuning v2更侧重于提升对NLU任务的适应性。
在代码层面,P-tuning v2的核心在于巧妙地利用`past_key_value`参数,实现连续prompt的融入。通过在`RobertaPrefixForTokenClassification`类的`forward`函数中进行初始化,以及`RobertaModel`到`RobertaEncoder`,再到`self.layer`(`nn.ModuleList([RobertaLayer(config) for _ in range(config.num_hidden_layers)])`)的路径追踪,实现连续提示的高效传递。
为了简化理解,我编写了仿真代码,直接展示了P-tuning v2连续prompt实现的核心过程。通过这一代码示例,读者可以直观地了解P-tuning v2如何通过`past_key_value`参数实现连续prompt的融入,从而达到提升模型性能的目的。
总结而言,P-tuning v2通过引入连续prompt并优化其实现细节,显著提升了预训练模型在生成和知识探索任务中的性能,特别适用于小型模型与复杂任务场景。其关键在于巧妙利用`past_key_value`参数实现连续prompt的高效融入,并通过仿真代码直观展示了这一实现过程,为读者提供了深入理解P-tuning v2实现方式的途径。
Bert4keras开源框架源码解析(一)概述
Bert4keras是苏剑林大佬开源的一个文本预训练框架,相较于谷歌开源的bert源码,它更为简洁,对理解BERT以及相关预训练技术提供了很大的帮助。
源码地址如下:
代码主要分为三个部分,分别在三个文件夹中。
在bert4keras文件夹中,实现了BERT以及相关预训练技术的算法模型架构。examples文件夹则是基于预训练好的语言模型进行的一系列fine-tune实验任务。pretraining文件夹则负责从头预训练语言模型的实现。
整体代码结构清晰,主要分为以下几部分:
backend.py文件主要实现了一些自定义组件,例如各种激活函数。这个部分之所以命名为backend(后端),是因为keras框架基于模块化的高级深度学习开发框架,它并不仅仅依赖于一种底层张量库,而是对各种底层张量库进行高层模块封装,让底层库负责诸如张量积、卷积等操作。例如,底层库可能选择TensorFlow或Theano。
在layers.py文件中,实现了自定义层,如embedding层、多头自注意力层等。
optimizers.py文件则实现了优化器的定义。
snippets.py文件包含了与算法模型无关的辅助函数,例如字符串格式转换、文件读取等。
tokenizers.py文件负责分词器的实现。
而model.py文件则是框架的核心,实现了BERT及相关预训练模型的算法架构。
后续文章将详细解析这些代码文件,期待与大家共同进步。