punchy
Stay foolish Stay hungry

模拟面试

2025-04-20 面试

利用AI进行模拟面试

将简历发给AI,让AI针对简历和要面试的岗位,提出一些问题,并给出AI的回答,参考AI的回答进行梳理,最终给出自己的回答。

个人科研助手项目

RAG的工作流程

  • 文档预处理
    • 文档导入,使用langchain的document_loader方法,导入md文件,PPT文件,PDF文件,word等非结构化文本
    • 文档切块,多少个字符算一个块,块与块之间重合的字符数是多少
  • 使用Embedding模型将chunk向量化,存储入库
  • 检索召回:用户的query作为查询向量,计算查询向量与库中向量的相似度。这里就有一个问题,查询的时候是直接遍历所有文本向量与查询向量的相似度吗?不是的,这样复杂度是O(N),非常慢。实际Chroma底层是基于FAISS在存储的时候构建近似最近邻索引,将向量聚成多个簇或者构建图结构,查询的时候在相邻的几个簇内搜索,牺牲一点点精度换取极大的速度提升。本质上是使用特别的数据结构来换取查询效率的提升。 找到TopK个结果后,将结果和query拼接,调用LLM回答。

为什么选用Chroma,它相比于FAISS有什么优势?

  • chroma的优势是轻量化,易于本地部署,适用于个人科研场景。相比FAISS没有那么强的分布式存储和大规模检索能力。

使用的什么Embedding模型?

  • 使用的是阿里巴巴发布的GTE-large-zh,因为它相比于openai的一些embedding模型,更适合中文场景。

使用的哪个大模型作为LLM?

  • 使用阿里巴巴开源的qwen2.5:7b,使用Ollama部署在本地,程序中使用langchain的方法来调用。

AIMO数学竞赛

CoT数据,TIR数据分别指什么?为什么要用这些数据?

  • CoT即指chain of thought,即思维链数据,是将问题的解答过程一步步拆解开来而不是直接给一个答案。拿着这样的数据去训练模型,可以让模型在解答过程中一步步的去分析问题,从而让模型学会思考,学会推理。从数学上来说,解码器模型的每一次输出都是一个条件概率分布,这里的条件就是之前产生的token。那么在得到答案之前产生的token越多,给模型的上文就越多,这个条件概率分布的条件就越多,那么得到正确答案的概率就越高。
  • TIR是tool-integrated reasoning。针对数学问题,会涉及到许多运算,那么我们希望大模型能在涉及运算的问题上调用工具比如使用python来计算,而不是自己用“脑子”算。所以在这一类数据集中,我们除了将问题拆解为一步步的方式来执行,同时在涉及计算问题时,会在solution中以markdown的方式添加python代码。这样训练出来的模型,输出中会带有代码。这样再写一个解析函数,将代码提取出来并执行,得到输出结果

self-consistency decoding怎么做的?

  • 它是来自于一篇论文,其本质是多次采样生成,取出现概率最高的结果,能降低单词生成的误差,提高解题稳定性。

为什么使用vLLM,性能怎么样?

  • vLLM是高效推理引擎,支持高并发,GPU高利用率,它可以最大限度的使用GPU来加速推理,比Transformers快2-3倍。

WSDM Cup

为什么使用4bit量化,4bit量化具体是怎么实现的?

  • 使用4bit量化可以将模型的大小大大压缩,同时对模型的性能也影响较小,从而让我们可以在消费级的显卡上部署和微调。
  • 最简单的均匀量化的原理就是将模型的参数范围空间,从原来的非常大,映射到16个固定的值,这样模型的参数值只有16中可能,使用4个比特位就可以表示,这样就能大大的压缩模型参数对显卡显存的占用。实际上是将原来比如10000个参数按照数值大小,分别划分了16个桶,这样用这16个编号就能对每一个参数进行表示了。
  • 上一点说的是一种十分简单的量化方式,即均匀量化,所有的权重参数按照数值的大小进行量化。但现在主流的量化方式是GPTQ,一种后训练量化方法。

GPTQ

步骤如下:

  • 前向跑一批代表性的样本,前向推理记录每层输出的激活值
  • 计算梯度敏感度,对权重W计算输出误差对权重的敏感度。即判断如果$W$被量化为$W_1$,对输出的影响有多大。
  • 对一个权重矩阵分块,分别量化,在量化每一个矩阵块的时候,其他矩阵块都不懂,避免误差扩散。利用第二步算出来的权重敏感度来决定量化顺序,即第三步优先量化对整体影响最小的块
  • 第四步选择重建误差最小的量化方式,比如非均匀量化,NF4编码

总之,先前向推理记录激活值,计算每个权重对输出的的敏感度,即每个权重对输出的影响程度。第三步将权重分块,优先量化输出敏感度高的权重块,第四步量化时选择重建误差最小的量化方式。GPTQ是一种更精细的量化方式,宗旨即为在量化的同时,最小化量化对输出的影响。

GPTQ 是一种后训练量化方法,通过计算权重对模型输出的敏感性,优先保留对输出影响大的权重的量化精度,分组逐块量化权重,最小化量化误差带来的输出偏差。它能在无需微调的情况下,将 FP16 大模型压缩成 4-bit 精度,在显著降低显存和加速推理的同时,保持原模型90%以上的推理精度,广泛应用于 LLaMA、Qwen、DeepSeek 等主流大语言模型的本地部署。

Bert模型

bert是谷歌提出的一种基于transformer的双向预训练语言模型,广泛应用于文本分类,问答,命名体识别,句子匹配等下游任务。

核心结构是transformer的encoder layer的堆叠。input text 输入进来后,会得到三个部分,input embedding,position embeding, segment embedding。其中segment embedding 是表示句子属于句子A还是句子B。因为bert还有一个句对任务。

Encoder layer 中包含attention layer 和 MLP layer。

经过多层encoder layer之后, 得到输出向量,特别的,输出向量的第一个token是CLS,bert规定他是整个句子的聚合表示,常用来做分类。

bert预训练中有两个任务,一个是 masked language model (MLM), 随机mask 15%的词,让模型根据上下文预测被mask掉的词。第二个任务是 next sentence prediction (NSP)即下一个句子预测。判断句子B是否是句子A的下一句。

自注意力机制代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
def self_attention(x, d_k):
W_Q = torch.randn(X.size(-1), d_k)
W_K = torch.randn(X.size(-1), d_k)
W_V = torch.randn(X.size(-1), d_k)

q = x @ W_Q
k = x @ W_K
v = x @ W_V

scores = (q @ k.transpose(-2, -1)) / torch.sqrt(torch.tensor(d_k))
weight = F.softmax(scores, dim=-1)

o = weight @ v

return o

掩码注意力机制代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def masked_attention(x, d_k):

W_Q = torch.randn(X.size(-1), d_k)
W_K = torch.randn(X.size(-1), d_k)
W_V = torch.randn(X.size(-1), d_k)

q = x @ W_Q
k = x @ W_K
v = x @ W_V

scores = (q @ k.transpose(-2, -1)) / torch.sqrt(torch.tensor(d_k))
mask = torch.triu(torch.ones(seq_len, seq_len) * float('-inf'), diagonal=1)

weight = F.softmax(scores + mask, dim=-1)
o = weights @ v

return o

交叉注意力机制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
def cross_attention(q_input, kv_input, d_k):
## q来自decoder,kv来自encoder
## tgt_len表示要解码的文本,src_len表示编码好的文本
# Q_input: (batch_size, tgt_len, d_model)
# KV_input: (batch_size, src_len, d_model)

wq = torch.randn(q_input.size(-1), d_k)
wk = torch.randn(kv_input.size(-1), d_k)
wv = torch.randn(kv_input.size(-1), d_k)

Q = q_input @ wq # (batch, tgt_len, d_k)
K = kv_input @ wk # (batch, src_len, d_k)
V = kv_input @ wv # (batch, src_len, d_k)

scores = (Q @ K.transpose(-2, -1)) / torch.sqrt(torch.tensor(d_k)) # (batch, tgt_len, src_len)
weights = F.softmax(scores, dim=-1)
output = weights @ V

return output

在 Encoder-Decoder 架构中,交叉注意力的 Q 来自 Decoder 当前输入或上一层隐藏状态,K 和 V 来自 Encoder 编码后的输出。这样 Decoder 就可以在解码每个位置时,基于自己当前状态,有选择性地关注源句子的不同部分。

MHA

Author: 武丢丢

Link: http://example.com/2025/04/20/%E6%A8%A1%E6%8B%9F%E9%9D%A2%E8%AF%95/

Copyright: All articles in this blog are licensed under CC BY-NC-SA 3.0 unless stating additionally.

< PreviousPost
面试复盘
NextPost >
周总结4.13
CATALOG
  1. 1. 利用AI进行模拟面试
    1. 1.1. 个人科研助手项目
      1. 1.1.1. RAG的工作流程
      2. 1.1.2. 为什么选用Chroma,它相比于FAISS有什么优势?
      3. 1.1.3. 使用的什么Embedding模型?
      4. 1.1.4. 使用的哪个大模型作为LLM?
    2. 1.2. AIMO数学竞赛
      1. 1.2.1. CoT数据,TIR数据分别指什么?为什么要用这些数据?
      2. 1.2.2. self-consistency decoding怎么做的?
      3. 1.2.3. 为什么使用vLLM,性能怎么样?
    3. 1.3. WSDM Cup
      1. 1.3.1. 为什么使用4bit量化,4bit量化具体是怎么实现的?
      2. 1.3.2. GPTQ
      3. 1.3.3. Bert模型
      4. 1.3.4. 自注意力机制代码
      5. 1.3.5. 掩码注意力机制代码
      6. 1.3.6. 交叉注意力机制
      7. 1.3.7. MHA