手搓一个Agent#Datawhale 组队学习Task3
书接上回,首先回顾一下Task2的一些补充:
Task2主要任务是从零预训练一个tiny-llama模型,熟悉一下Llama的模型架构和流程。然后测试一下模型的效果。总的来说,因为某些未知的原因,loss一直没有降下去,导致最终效果一般般。
Task2知识点补充和解读
contextlib库
from contextlib import nullcontext
contextlib
是 Python 标准库中的一个模块,它提供了一系列工具来帮助开发者更方便地使用上下文管理协议(context management protocol)。
nullcontext
是 Python 中 contextlib
模块提供的一个上下文管理器,它主要用于不需要执行任何特定的进入或退出操作的情况。
datetime库
from datetime import datetime
datetime
是 Python 的标准库之一,提供了处理日期和时间的强大工具。
datetime
类是 datetime
模块中最常用的类之一,它代表了一个具体的日期和时间。你可以用它来进行日期和时间的运算,获取当前时间,格式化日期等。
datetime
库和 time
库的比较
datetime
库和 time
库都是 Python 中用于处理日期和时间的标准库,但它们各有侧重,适用于不同的应用场景。
datetime
库更适合于需要高级日期时间处理的应用场景,而 time
库则更适合于简单的计时和时间戳操作。
functools库
from functools import partial
functools
是 Python 标准库中的一个模块,它提供了多种工具来帮助开发者更高效地编写函数。partial
函数可以固定一个函数的一部分参数,从而创建一个新的函数。
AdamW优化器
AdamW
是一种广受欢迎的优化算法,它是在经典的 Adam 优化器基础上发展而来,引入了权重衰减(Weight Decay)机制。
Adam(Adaptive Moment Estimation)是一种自适应学习率优化算法,它结合了 AdaGrad 和 RMSProp 的优点。Adam 使用了动量(momentum)和自适应学习率来更新参数,其中动量用于加速收敛速度,自适应学习率用于调整不同参数的学习速率。
AdaGrad 没有使用动量的概念,而是直接根据历史梯度的平方来调整学习率。学习率单调递减:随着训练的进行,学习率会逐渐减小,最终可能变得太小。
动量机制:RMSProp 使用了指数移动平均来估算梯度的平方,从而避免了 AdaGrad 中学习率单调递减的问题。
- AdaGrad:适合处理稀疏梯度的问题,但由于学习率单调递减,不适合长期训练。
- RMSProp:通过指数移动平均解决了 AdaGrad 中学习率单调递减的问题,适合处理动态变化的梯度。
- Adam:结合了 AdaGrad 和 RMSProp 的优点,并通过偏置校正机制提高了初始阶段的收敛速度,是目前最常用的优化算法之一。
在使用 AdamW 优化器的情况下,是否需要使用 Dropout 主要取决于您的具体应用场景和模型设计的需求。
Dropout 和 Weight Decay 的区别:
-
Dropout
- 定义:Dropout 是一种正则化技术,通过随机“丢弃”一部分神经元(即设置为 0),从而降低模型的复杂度,防止过拟合。
- 作用:Dropout 可以使模型的各个部分相互独立地学习特征,从而提高模型的鲁棒性。
- 适用场景:通常用于深层网络中,特别是在训练非常大的模型时,Dropout 可以帮助模型更好地泛化到未见过的数据。
-
Weight Decay
- 定义:Weight Decay 是一种正则化技术,通过对模型的权重施加惩罚(通常为 L2 正则化),减少模型的复杂度。
- 作用:Weight Decay 通过使权重趋向于较小的值,从而降低模型的整体复杂度。
- 适用场景:几乎所有的模型都可以从中受益,特别是在数据集较小或者模型容量很大的情况下。
学习率调度器scheduler:
学习率调度器(Learning Rate Scheduler)是深度学习训练中用来动态调整学习率的技术。通过调整学习率,可以提高模型的训练效率和性能。在训练初期使用较高的学习率可以加快收敛速度,在后期精细调整参数,提高训练效率。
余弦退火(Cosine Annealing)学习率调度是一种动态调整学习率的技术,它根据余弦函数的周期性变化来调整学习率。尤其适合需要平滑地调整学习率的场景。
一般建议预热迭代次数为总迭代次数的 5% 到 10% 左右。
退火开始的迭代次数通常在训练的中期到后期,一般建议设置为总迭代次数的 80% 左右。
初始学习率取决于模型的复杂度和数据集的大小。一个常见的初始学习率设置为 0.001。
根据模型规模和数据集大小Llama技术报告里面
,初始学习率可能在 1e-4
到 5e-5
之间。
最小学习率应该设置得足够小,以防止在训练后期学习率仍然过高而导致的振荡。通常为初始学习率的十分之一。
我又重新跑了一次,根据学习率调度修改了一些参数,等结果更新,希望这次可以取得一个比上次更有的结果。
Task3.Tiny-Agent
论文:《REACT: SYNERGIZING REASONING AND ACTING IN LANGUAGE MODELS》
我们先来看一下这篇论文主要讲了什么。
摘要:该论文介绍了一种名为ReAct(Reason+Act)的新方法,它探索了如何使大型语言模型(LLMs)以交错方式生成推理轨迹和特定任务动作,以此增强推理与行动间的协同效果。ReAct通过推理来指导和更新行动计划,并通过实际行动与外部资源(如知识库)互动获取信息。这种方法在多种语言理解和决策制定任务中进行了测试,显示出了比现有技术更好的性能,并提高了模型的可解释性和可信度。特别是在HotpotQA和Fever任务中,ReAct减少了推理错误,并产生了更容易理解的结果;而在ALFWorld和WebShop这两个互动决策制定基准测试中,ReAct仅需少量示例就能显著提高成功率,超越了传统的模仿和强化学习方法。
接下来我们开始手搓Agent的代码实现:
Step 1: 构造大模型
这里我们选择了书生谱语的开源InternLM2作为我们的Agent模型。InternLM2是一个基于Decoder-Only
的通用对话大模型,可以使用transformers
库来加载InternLM2模型。
Step 2: 构造工具
我们在tools.py
文件中,构造一些工具,比如Google搜索
。在这个文件中,构造一个Tools
类。在这个类中,我们需要添加一些工具的描述信息和具体实现方式。
Step 3: 构造Agent
我们在Agent.py
文件中,构造一个Agent
类,这个Agent
是一个React
范式的Agent
,我们在这个Agent
类中,实现了text_completion
方法,这个方法是一个对话方法,我们在这个方法中,调用InternLM2
模型,然后根据React
的Agent
的逻辑,来调用Tools
中的工具。
Step 4: 运行Agent
在这个案例中,使用了InternLM2-chat-7B
模型, 如果你想要Agent
运行的更加稳定,可以使用它的big cup
版本InternLM2-20b-chat
,这样可以提高Agent
的稳定性。