0%

千问c端LLM搜索 一面

  • 介绍一下BPE算法流程是什么样的?你这里预训练词表的大小选择的是多少?有什么依据?你有进行不同大小词表的尝试吗?

    BPE是先做 pre-tokenization ,得到相应的输出字符之后,进行多次合并。合并的逻辑为先依次统计相邻的token对的出现频率,遍历到最后结束之后把频率最高的token对给合并成一个新token,更新整个编码序列,词表最大容量+1,然后反复进行这个行为。

    预训练词表大小选择的是6400这个大小,主要是用来控制embedding层和后续用来训练模型的层之间的大小差异,如果使用其他开源模型的10几w的参数,在dim=512的情况下就已经超过了模型参数。调试之后采用3m左右的嵌入层即可。

  • 你有看过你这个BPE词表 special token等等的占比是什么样的吗?

  • 你这里说使用了RoPE来做位置编码,请问RoPE相较于传统的位置编码到底有什么样的好处?

    统一了绝对和相对位置;能够很好的进行外推;同时方便加速。

  • 除了能够体现相对位置之外呢?难道传统的sin cos处理就不包含相对位置信息了吗?

    传统Vanilla PE是直接做加法注入,就是词向量和位置向量相加。但在实际计算query和key点积的时候,中间项相乘会出现内容和位置的交叉项,这些是噪声向量并不需要;
    而RoPE是直接做乘法注入,只有最干净的相对位置距离,不存在任何的交叉噪声杂项。

    同时处理的时候,RoPE是每一层都能够注入位置信息,而传统正余弦编码则是在一开始embedding层进行注入。

阅读全文 »

在新服务器使用 wandb 的时候,通常需要在命令行输入 wandb login 进行登陆。这时候会跳转出来这样的页面:

wandb login

wandb登录

然后点击提供的API链接之后,会跳转到wandb的API Key页面,这个时候需要创建新的API Key,理论上来说复制到命令行登录自己的账户即可。

阅读全文 »

我个人对实验五的全部实现代码在:Stanford_CS336_Assignment5_2025Spring

Assignment5的目的是让我们对Qwen 2.5 Math 1.5B这个模型进行SFT以及RL训练。

利用vLLM进行模型推理

主要目的是熟悉vllm的部分接口,通过vllm这个原生推理加速框架来对llm进行快速的inference操作。同时为后面SFT训练的时候使用vLLM框架做推理测试提供一个可复用的接口。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
from transformers import AutoTokenizer, AutoModelForCausalLM
from vllm import LLM, SamplingParams
from typing import Callable, List
from cs336_alignment.drgrpo_grader import r1_zero_reward_fn
import json
import os

model_path = "/gz-data/models/Qwen2.5-Math-1.5B"
MATH_DATASET_PATH = "/root/yjx/assignment5-alignment/data/MATH/validation.jsonl"
PROMPT_TEMPLATE_PATH = "/root/yjx/assignment5-alignment/cs336_alignment/prompts/r1_zero.prompt"

def load_prompts(file_path: str,
template_path: str) -> List[str]:
'''
Load prompts from a JSONL file and return them as a list of strings.
'''
prompts = []
answers = []

with open(template_path, 'r') as f:
template = f.read()

with open(file_path, 'r') as f:
for line in f:
data = json.loads(line)
question = data['problem']
answer = data['answer']
prompt = template.replace("{question}", question)
prompts.append(prompt)
answers.append(answer)
return prompts, answers


def evaluate_vllm(
vllm_model: LLM,
reward_fn: Callable[[str, str], dict[str, float]],
prompts: List[str],
groundtruths: List[str],
eval_sampling_params: SamplingParams,
save_path: str = "/root/yjx/assignment5-alignment/cs336_alignment/zero_shot_results"
) -> None:
"""
Evaluate a language model on a list of prompts,
compute evaluation metrics, and serialize results to disk.
"""
count_all_correct = 0 # (1) format=1, answer=1
count_format_only = 0 # (2) format=1, answer=0
count_fail = 0 # (3) format=0, answer=0

format_fails = []
answer_fails = []

outputs = vllm_model.generate(prompts, sampling_params=eval_sampling_params)

if not os.path.exists(save_path):
os.makedirs(save_path)

with open(os.path.join(save_path, "results.jsonl"), 'w') as f:
for prompt, output, groundtruth in zip(prompts, outputs, groundtruths):
result = output.outputs[0].text
reward = reward_fn(result, groundtruth)
if reward["format_reward"] == 1 and reward["answer_reward"] == 1:
count_all_correct += 1
elif reward["format_reward"] == 1 and reward["answer_reward"] == 0:
count_format_only += 1
elif reward["format_reward"] == 0 and reward["answer_reward"] == 0:
count_fail += 1

# 方便来观察 10个 format=0 的例子和 10 个 answer=0 的例子
if reward["format_reward"] == 0 and len(format_fails) < 10:
format_fails.append({"res": result, "gt": groundtruth})
elif reward["format_reward"] == 1 and reward["answer_reward"] == 0 and len(answer_fails) < 10:
answer_fails.append({"res": result, "gt": groundtruth})

f.write(json.dumps({
"prompt": prompt,
"result": result,
"groundtruth": groundtruth,
"rewards": reward
}) + "\n")

# Compute and print evaluation metrics
total = len(prompts)
print(f"Total Prompts: {total}")
print(f"All Correct: {count_all_correct} ({count_all_correct / total:.2%})")
print(f"Format Only: {count_format_only} ({count_format_only / total:.2%})")
print(f"Fail: {count_fail} ({count_fail / total:.2%})")

# 存储bad case
with open(os.path.join(save_path, "format_fails.json"), 'w') as f:
json.dump(format_fails, f, indent=4)
with open(os.path.join(save_path, "answer_fails.json"), 'w') as f:
json.dump(answer_fails, f, indent=4)



if __name__ == "__main__":
prompts, answers = load_prompts(MATH_DATASET_PATH, PROMPT_TEMPLATE_PATH)
llm = LLM(model=model_path)
sampling_params = SamplingParams(temperature=1, top_p=1, max_tokens=1024, stop=["</answer>"], include_stop_str_in_output=True)
evaluate_vllm(llm, r1_zero_reward_fn, prompts, answers, sampling_params)
阅读全文 »

例行总结过去一年,还是和去年一样,从实习,学业以及生活三个方面来写点流水账。

实习

在西门子实习到了今年年初的四月份,由于我自己不想干了,同时毕业设计也即将ddl,顺便享受一下剩下的大学生活,就离职了。实习的主要工作就是做了一个基于 self-supervised 的方法来检测 西门子自己PCB的缺陷的工作。我大概是把所有的代码给跑通了,有了一个初步的结果。

对于输入的图片,上面会有8块相同的PCB板子。对于这些PCB板子,首先采用传统CV图像识别的方式,根据模版图片识别出具体八块PCB。由于我们使用的是4K的摄像头,因此每一块PCB的分辨率非常的高,直接输入给模型做推理或者训练的话会非常的大。

阅读全文 »

1. 两数之和

用一个dict来存过去见过的 target-nums[i] ,然后如果当前和这个一致的话就找到匹配的两个数

1
2
3
4
5
6
7
8
9
10
from collections import defaultdict

class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
mem = defaultdict()
for i in range(len(nums)):
if target - nums[i] in mem:
return [mem[target-nums[i]], i]
mem[nums[i]] = i
return []
阅读全文 »

在西门子实习的时候,当时突发奇想想设计一个pre-training加post-training的架构,当时是希望在后面接一个projection head,然后前面用预训练好的模型冻结住不改变就可以了。原本以为只需要写一串这样的代码就完全OK:

1
2
for param in model.xxxpart.parameters():
param.require_grad = False

结果训练完后面的projection head,前面的模型输出的重建图片的结果和原来差别巨大,我就感觉并没有冻结住所有的变量,肯定是对前面也进行了训练。查看训练前后模型的参数变化:

阅读全文 »

博客是2021年就搭建好的,可惜也没有写一些技术类的文章。主要是自己也没什么本事,肚子里也没啥墨水。那还不如在互联网上记录过去一年生活与学习的痕迹,以后还能留个纪念。写流水账

实习

一月份结束了在ChaoWei Xiao老师那里的远程实习,是我第一份科研向实习工作,主要做的是大模型评测代码相关benchmark的搭建。

正如同deepseek宣传的那样,AGI的实现是算力x算法x数据,数据在其中其实扮演着很重要的角色,所以这个工作大部分时间也就在洗数据,测模型,找bad case等。据说benchmark相关的工作就是这样,但是我个人实在是觉得这样的工作没有什么含金量,也没有去继续下去。

虽然这段实习经历就三个月的时间,并没有继续延续下去,但是我觉得这倒是我受益比较多的实习经历。在zqz师兄 (虽然我觉得他情商非常低下) 的指导之下,倒是形成了自己的代码规范,对于面向对象代码的规范,方法的封装,类的继承等都比之前要写的好了很多,技术力upup。同时在做实验的时候还学到了很多分析bad case的方法,以及分析问题的角度与思路,还是蛮不错的。

寒假在家倒是挺爽的,和朋友吃吃喝喝,爽摸一个月。

阅读全文 »

中国科学院计算技术研究所客座学生 一面(40min)

面试是计算所的phd电话交流的,流程如下:

  • 介绍了要做的项目

    ICT,商汤和南方电网一起合作的项目。主要做LLM+时序预测,有卡有数据集,但是数据集是南方电网的内部私有数据集,不能公开。

  • 谈谈之前做过的LLM相关的项目,有没有自己跑过,或者测试过一些LLM?

    讲了远程实习那段用LLM做漏洞检测和漏洞修复的工作。

阅读全文 »

提交

1
git commit -m "commit_info"

创建分支

是指在当前节点下,创建一个完全一样的分支,和之前的分支互不干扰。

1
git branch <branch_name>

切换到相应的分支上:

1
git checkout <branch_name>

可以用一个指令完成创建与移动:

1
git checkout -b <branch_name>
阅读全文 »