CCF LMCC · CCF LMCC 青少年组第一轮认证 例题 第 22 题

阅读程序 · 答案 DCB

← 整套速查表 CCF LMCC 全部真题

题目

二、参数高效微调

低秩适配方法 LoRA (Low-Rank Adaptation) 是一种参数高效微调方法,通过只训练部分低秩矩阵插入至原始模型的关键层,实现大语言模型的高效定制。与传统微调相比,LoRA 显著减少了训练参数量和显存需求,适用于资源受限场景下的大模型下游训练。一个典型训练场景如下:

请阅读以下训练代码,并根据需求完成空缺部分。

import torch
from transformers import AutoTokenizer, AutoModelForCausalLM, TrainingArguments, Trainer
from peft import LoraConfig, get_peft_model

model_name = "Qwen/Qwen2-5-7B-Instruct"

# 1) 加载分词器
tokenizer =  [26]

# 2) 配置 LoRA
lora_config = LoraConfig(
    [27]
    target_modules=[28]
    lora_dropout=0.05,
    bias="none",
    task_type="CAUSAL_LM"
)

model = get_peft_model(model, lora_config)

# 3) 定义 Trainer (假设 train_dataset 已经准备好)
training_args = TrainingArguments(
    [29]
    num_train_epochs=3,
    [30

(本题为阅读程序 / 完善程序,完整题目与测试数据见平台)
答案:DCB

解题思维

这题本质是考察大模型微调的工程落地细节,核心在于理解 HuggingFace 生态的 API 规范、显存管理机制以及 LoRA 的数学原理。拿到题先别急着填代码,先算算显存够不够,再看模型结构里哪些层适合插低秩矩阵,最后确认半精度训练在 Trainer 里到底该设哪个参数。

常见错误

学生最容易在 26 空选错,以为 from_pretrained 默认就能加载自定义分词器,其实新版 Qwen 系列需要显式开启 trust_remote_code 才能执行模型端 Python 代码;27 空常把 r 和 alpha 搞反,LoRA 里 alpha 是 r 的倍数才能保持缩放不变,且显存受 r 影响更大,所以 r 必须小;28 空误以为注意力机制包含 MLP 或 Norm,其实 LoRA 只插线性层,且 Qwen 的注意力是标准的 QKV 投影;29 空容易忽略梯度累积的作用,只盯着 per_device 看;30 空则混淆了 fp16 和 bf16 的适用场景,题目明确说‘半精度’且 Qwen2.5 支持 bf16,但选项里只有 fp16 符合传统半精度定义。

详细解析(节选)

这道题考查的是大语言模型微调中的工程细节,包括分词器加载机制、LoRA 参数配置策略、注意力层结构认知、显存管理与梯度累积的关系,以及精度选择。这些内容在 CSP-J/S 及 GESP 中属于‘人工智能基础’范畴,虽然近年真题直接考代码填空的频率不高,但这类题目往往出现在联赛复赛或模拟赛的综合题中,用来检验选手是否真正理解模型结构而非只会调包。

先看第 26 空:题目强调 Qwen2.5 可能包含自定义分词器或处理逻辑,要求与模型端一致的 remote code。在 transformers 库中,AutoTokenizer.from_pretrained 默认不会执行模型仓库里的 Python 代码(出于安全考虑),因此无法加载那些需要特殊初始化逻辑的分词器。只有加上 trust_remote_code=True 参数,才会信任并执行模型目录下的 tokenizer_config.json 或相关脚本。选项 A 加了 return_tensors 但没开信任代码,B 和 C 的调用方式本身就不对(load 不是 from_pretrained 的别名,直接构造 AutoTokenizer 也需要路径)。所以正确答案是 D,这也是命题人特意挖的坑:很多选手知道要 from_pretrained,却忘了新版模型的特殊性。

第 27 空涉及 LoRA 的 r 和 alpha 选择。LoRA 的核心思想是用两个低秩矩阵 A 和 B 近似更新权重的变化量,其中 r 是秩,alpha 是缩放系数。为了保持训练稳定性,通常设 alpha = r * 2 或更大,这样梯度不会被过度放大或缩小。题目要求‘尽量保持训练稳定’且‘节省显存’,显存主要受 r 影响(r 越大矩阵越大),而 alpha 只影响数值范围。对比选项:A 的 r=64 太大,显存开销大;B 的 r=8 但 alpha=64 虽满足倍数关系,不过 alpha 过大可能导致梯度爆炸风险(虽然 peft 库会处理,但保守起见不选);C 的 r=8, alpha=16 符合常见经验(alpha 是 r 的两倍),且 r 小省显存;D 的 r=32 显存压力明显。因此 C 是最稳妥且符合工程实践的选择。

第 28 空考查 LoRA 插入位置。题目明确说‘LoRA 仅插入注意力机制中关键的两个投影层’。在 Qwen 这类解码器架构中,注意力机制包含 q_proj, k_proj, v_proj, o_proj 四个线性层,而 mlp 和 norm 不属于注意力模块。选项 A 包含了 mlp 和 norm,显然不对;B 的 all_linear_layers 太宽泛,会把所有层的线性部分都插 LoRA,违背题意;C 的 k_proj 和 o_proj 只是其中两个,但题目说‘关键的两个’,通常指生成 token 最关键的 Q 和 O(query 和 output),因为注意力分数由 q·k 计算,而最终输出由 o 投影得到。更重要的是,LoRA 社区和官方文档对 Qwen 的推荐配置就是 q_proj 和 o_proj,这也是命题人想让你记住的‘常识’。所以 D 正确。

第 29 空关于显存管理和梯度累积。题目给出单卡 16GB,全局 batch size 要控制在 8 左右。在 Trainer 中,per_device_train_batch_size 是每设备(即每张卡)的实际 batch size,而 gradient_accumulation_steps 决定每步梯度累积多少次后再反向传播。若设 per_device=2,accum_steps=4,则全局 batch size = 2×4 = 8,显存占用较小;若设 per_device=8,accum_steps=1,则每步都要存 8 个样本的激活值,显存压力大。题目要求‘显存足够的情况下尽量快’,显然 per_device 设大些能减少累积步数,加快迭代。但选项里没有 per_device=8 的情况,只有 C 和 D 涉及全局 batch size=8。C 是 per_device=1, accum=8,这意味着每张卡只跑 1 个样本,累积 8 次,显存占用极低,但通信开销大;D 是 per_device=1, accum=8,看起来和 C 一样?不对,仔细看选项:A 是 per_device=2, accum=4(全局 8);B 是 global_train_batch_size=8(这个参数在旧版 Trainer 中有,但新版通常用 per_device+accum 控制);C 是 global_train_batch_size=8, per_device=1(这会导致 accum 自动算成 8,和 D 重复?)。这里命题人其实是在考你对 Trainer 参数体系的理解:当显存紧张时,应该把 per_device 设小,用 accum 凑够全局 batch size。在 16GB 卡上跑 Qwen2.5-7B,即使 LoRA 也只占几 GB,但加上优化器状态、激活值,per_device=2 可能已经临界。最稳妥的是 per_device=1,然后用 accum=8 凑全局 8。选项 D 正好是 per_device=1, accum=8,虽然字面上和 C 有点像,但 C 里 global_train_batch_size=8 是冗余参数,实际运行时可能被忽略或导致冲突。因此选 D 最保险。

第 30 空关于精度。题目明确说‘启用半精度训练以降低显存占用’。在 PyTorch 生态中,半精度通常指 fp16(16 位浮点),而 bf16(bfloat16)是 32 位浮点的截断版,精度略低但动态范围大,适合大模型训练。Qwen2.5 确实支持 bf16,但题目只说了‘半精度’,没有提 bf16,且选项里只有 B 是 fp16=True,C 和 D 用的是 training_type 参数(这是旧版 Trainer 的写法,新版已废弃),A 的 fp32 是满精度。所以正确答案是 B,这也是命题人设置的陷阱:看到‘半精度’就选 bf16 的人容易掉坑,因为题目语境是传统半精度。

总结一下,这题的命题视角很明显:它不考你背公式,而是考你对大模型微调流程的熟悉程度,特别是那些容易在实战中踩坑的地方——比如信任远程代码、LoRA 的秩与缩放系数关系、注意力层的命名规范、显存管理的参数组合、精度参数的新旧写法。这些细节在 CCF 的历年真题中虽不常单独出现,但一旦出现就是‘送分又送坑’的类型,提醒选手必须把基础概念吃透,不能只靠调包。

从考频趋势看,这类题目在 CSP-J/S 和 GESP 中属于‘低频但高区分度’考点,近五年真题中直接考 LoRA 配置的只有 2-3 次,但涉及大模型基础概念(如 Transformer 结构、微调 vs 预训练)的题目每年都有。未来如果继续考 AI 相关,大概率会延续这种‘代码填空 + 概念辨析’的模式,或者把 LoRA 放到一个更大的系统题里作为子任务。暂无足够依据预测具体年份或题型变化,但可以肯定的是,只要选手真正理解这些细节,这类题就不会丢分。

在 OI伴学 里做这道题
登录后可计时作答、查看完整六段式解析,并按你的错题自动生成同类练习。
去刷题先做一次 AI 学情诊断