来源:投稿 作者:寒武纪
编辑:学姐
今天分享一些阿里达摩院大模型算法岗一面面经。
1、对大模型有什么了解?
简单说了大致的流程,预训练、有监督微调,RLHF
在训练大语言模型时,通常会采用几个关键的步骤,包括
预训练
、
有监督微调
(Supervised Fine-Tuning)和
基于人类反馈的强化学习
(RLHF,Reinforcement Learning from Human Feedback)。以下是这些步骤的简要流程:
预训练 (Pre-training)是大语言模型的基础阶段,目的是让模型学习语言的基本结构、语法、语义、常识等。这个过程不依赖于特定任务,而是通过大量的无标注数据来训练模型。
预训练阶段后,模型虽然能够理解语言的基础规律,但它可能并未针对特定任务优化。在有监督微调阶段 (Supervised Fine-Tuning),模型会通过有标签的数据进一步调整,以提高在某些特定任务上的表现。
在有监督微调后,模型已经能在特定任务上表现得相对不错,但它可能在生成质量、有效性和对话的多样性等方面仍然存在不足。基于人类反馈的强化学习(RLHF)旨在通过人类反馈进一步提高模型的性能,尤其是在生成对话内容时。
总结流程:
-
预训练
:使用海量的无标签数据训练模型,学习语言的基本规律。
-
有监督微调
:使用标注数据针对特定任务进行微调,以提高任务表现。
-
RLHF
:基于人类反馈,通过强化学习进一步调整和优化模型的输出质量,使其更加符合人类期望。
关键点:
-
-
-
RLHF
则通过人类的反馈进一步精细化模型,使其在实际应用中更加实用和高效。
2、介绍一下RLHF的具体流程
RLHF(Reinforcement Learning from Human Feedback)
是一种利用人类反馈对模型进行强化学习优化的方法,主要用于进一步改进大语言模型的性能,尤其是在生成质量和用户体验方面。它的核心思想是通过人类评审员对模型输出的反馈来指导模型的学习,使得模型的行为更加符合人类的期望。
1、数据收集:模型生成初步输出
首先,基于一个预训练的语言模型(如 GPT 系列)进行
初步生成
,即模型根据输入的内容生成一些回答或文本。这些生成的文本并非完美的,因为模型尚未经过优化以适应具体的反馈目标。
2、收集人类反馈
收集人类评审员对模型输出的
质量评估
是 RLHF 的关键部分。通常,人类评审员会根据多个维度(如准确性、流畅度、相关性等)对模型的回答进行评分。
3、构建奖励模型
在获取足够的人类反馈后,接下来是
构建奖励模型
。奖励模型的任务是根据人类评审员的反馈,为每个生成的回答分配一个
奖励值
,这个奖励值反映了模型输出的质量。
4. 强化学习优化
一旦奖励模型建立好,就进入
强化学习阶段
。在这个阶段,模型会利用奖励模型来进行强化学习的训练,优化自己的生成策略,以产生更高质量的输出。
5、多轮反馈和迭代优化
RLHF 不是一次性的过程,而是一个
迭代优化
的过程。随着模型在现实环境中的应用,人类反馈可以不断收集,更新奖励模型,从而不断提升模型的表现。
经过一系列的强化学习和反馈调整,模型的生成能力会得到显著的提升,输出的质量更加贴合人类期望。
3、场景题
给了一个场景:如果现在给你一个预训练模型,然后场景是要帮助小学生做数学题,你会如何从头到尾来做这件事?
大概提了数据收集,清洗,然后有监督微调,思维链分解过程之类的东西,还有幻觉问题。
4、请问你知道有哪些缓解幻觉问题的思路吗?
5、你刚刚提到了思维链,大概说一下流程
思维链(Chain of Thought, CoT)
是一种在大语言模型中应用的策略,旨在帮助模型在处理复杂问题时,通过逐步推理的方式增强推理能力,最终得出正确的答案。这个方法尤其适用于需要多步骤推理或逻辑推导的任务。它的基本流程:
1、问题理解与拆解
首先,模型需要理解给定问题的类型,明确是数学问题、逻辑推理问题,还是某种需要分步解答的问题。
如果问题较复杂,模型需要将其拆解为多个较小的子问题。例如,计算数学题时,先将计算分解为各个步骤;在解答逻辑问题时,先理解每个条件的含义。
2、逐步推理与思考
模型在思维链中执行逐步的推理,每一步都基于前一步的结果。例如,解答数学题时,先计算一个简单的中间结果,再根据这个结果继续下一步的推导。
每一步的推理都必须确保前后逻辑一致,遵循规则或约束条件,不遗漏关键的细节。
3、中间结果生成
在思维链的每一步中,模型不仅仅给出最终答案,而是生成每个步骤的中间结果。这些中间步骤有助于最终得到正确答案,并且让模型能够追踪到自己的推理过程。
如果是复杂的推理问题,模型可以输出中间的结果,帮助用户理解问题的处理过程。
4、得出结论
在完成所有推理步骤后,模型会综合所有中间结果,得出最终的答案或结论。模型通过回顾推理过程,确保最终答案符合逻辑,并纠正可能的错误。
5、反馈和修正
如果得到的结果不符合预期或有错误,模型可以回溯推理过程,检查是否有漏掉的步骤或错误的推理,进行修正。通过不断优化推理步骤,改进模型的思维链能力,逐步提升问题解决的准确性和高效性。
6、写代码
以为会是LeetCode那种,没想到是让生成一个Numpy随机矩阵,然后进行诸如判断数字是否在数组内求数组均方差,还有索引之类的东西。
7、如果进来后,想做什么方向?
要求将现在做的方向和LLM进行一个结合。
8、进来后如果让你发一篇论文,你倾向于做些什么东西出来,有思考吗?
9、代码题:数组中的第K个最大元素
我们需要找出数组中第
k
大的元素。可以通过多种方法解决,包括排序、堆、快速选择算法等,这里我只叙述其中一种方法。
可以使用最小堆来找到第
k
个最大的元素。我们维护一个大小为
k
的最小堆,堆顶元素就是第
k
大的元素。
-
-
-
-
如果堆的大小已经等于
k
,比较堆顶元素与当前元素的大小,如果当前元素更大,就替换堆顶元素。
import heapq
def findKthLargest(nums, k):
# 使用 heapq 库,默认是最小堆
return heapq.nlargest(k, nums)[-1]
时间复杂度
:O(n log k),其中 n 是数组的长度,k 是堆的大小。
空间复杂度
:O(k),用于存储堆中的元素。
10、代码题:无重复字符的最长子串
这是一个典型的滑动窗口问题。我们可以利用双指针技巧,通过维护一个滑动窗口,逐步扩展窗口并确保窗口内没有重复字符。
-
使用两个指针
left
和
right
,
left
指向窗口的起始位置,
right
指向窗口的结束位置。
-
使用一个集合
char_set
来存储当前窗口内的字符,确保窗口内没有重复字符。
-
-
如果字符
s[right]
不在
char_set
中,说明当前字符没有重复,可以扩展窗口,将
s[right]
加入到
char_set
中。
-
如果字符
s[right]
在
char_set
中,说明存在重复字符,需要缩小窗口,移动
left
指针,直到窗口内没有重复字符。
在每次更新窗口时,计算当前窗口的大小,并更新结果。
def lengthOfLongestSubstring(s: str) -> int:
char_set = set() # 存储当前窗口内的字符
left = 0 # 窗口的左边界
max_len = 0 # 记录最长无重复子串的长度
for right in range(len(s)):
# 如果当前字符重复,则缩小窗口
while s[right] in char_set:
char_set.remove(s[left]) # 移除窗口左边的字符
left += 1 # 收缩窗口
# 添加当前字符到集合中
char_set.add(s[right])
# 更新最长子串的长度
max_len = max(max_len, right - left + 1)
return max_len
时间复杂度
:O(n),其中 n 是字符串的长度。每个字符最多被访问两次(一次通过
right
指针,另一次通过
left
指针),所以时间复杂度是线性的。
空间复杂度
:O(min(n, m)),其中 n 是字符串的长度,m 是字符集的大小(例如,ASCII 字符集为 128)。在最坏情况下,
char_set
会存储所有的字符,因此空间复杂度是 O(min(n, m))。
11、代码题:岛屿数量
这个问题可以通过
深度优先搜索(DFS)
或
广度优先搜索(BFS)
来解决。基本思路是遍历二维网格,当遇到一个陆地('1')时,说明找到了一块新的岛屿。然后从这个点开始,通过DFS或BFS将该岛屿周围的陆地标记为已访问(例如将
'1'
变为
'0'
)。每找到一个新的岛屿,就岛屿数量加 1。