573. Kaggle - LLM Science Exam | kaggle-llm-science-exam
首先,感谢比赛主办方举办本次竞赛。同时,我也想感谢 @radek1、@leonidkulyk、@mozattt、@nlztrk、@mgoksu 分享的有用数据集,感谢 @jjinho 分享的检索方法,感谢 @cdeotte 在 此讨论帖 中汇总这些数据集和方法。没有你们的工作,我们无法取得这些成果。从你们身上我学到了很多!
我的方案基于 @cdeotte 的 此 notebook。我对该 notebook 做了四个方面的改进:数据集、检索、模型和集成。
由于部分数据(主要是数字)存在缺失问题(如 此处讨论),我将维基百科数据集从 https://www.kaggle.com/datasets/jjinho/wikipedia-20230701 更换为 cirrussearch 维基百科数据集。
我尝试提升搜索精度。
我使用 ChatGPT 创建了 250 个问题用于评估检索效果。为进行大量实验,仅使用了以 "a" 开头的维基百科数据进行评估(而非完整数据集)。最终在该数据集上达到 0.94@recall1 和 1.0@recall30 的召回率(使用完整维基百科数据集的问题时约为 0.85@recall1)。
为提升检索精度,我对维基百科文本进行了分段处理。具体方法是从文本开头读取,当字数达到 90 词或以上时保存分段,并保留最后三个句子用于继续读取后续内容。
伪代码如下:
def count_words(text_processed):
return len(text_processed.split(" "))
def leave_last_sentence(text, n=3):
ret = text.split(".")[-n:]
return ".".join(ret)
texts = load_wiki()
texts_processed = []
text_processed = ""
length = 90
window = 3
for text in texts:
text_split_period = text.split(".")
for sentence in text_split_period:
text_processed += sentence
if count_words(text_processed) > length:
texts_processed.append(text_processed)
text_processed = leave_last_sentence(text_processed, window)
我尝试了以下参数组合 (length, window) = (60, 2), (75, 2), (90, 2), (90, 3), (90, 4), (120, 4), (150, 6),最终选择 LB 分数最高的配置。
使用参数:{"nlists": 1, "M": 64, "nbits": 8}
使用 gte-base 和 e5-base 模型。我尝试了 {gte, bge, e5}_{small, base, large} 多种组合并选择最优结果。(最初我仅通过 "a" 开头数据的检索精度选择模型,但发现检索精度与 LB 分数无相关性,最终改为依据 LB 分数选择😭)
基本与基线 notebook 相同。训练时设置 max_length 为 256,推理时为 768。虽然希望使用 768 长度训练,但内存资源不足。在 256、384 和 512 长度训练后使用 768 长度推理的对比中,256 长度训练效果最佳。
训练参数如下:
training_args = TrainingArguments(
warmup_ratio=0.01,
learning_rate=1e-6,
per_device_train_batch_size=2,
per_device_eval_batch_size=2,
num_train_epochs=config.epochs,
report_to='wandb',
optim="adamw_hf",
overwrite_output_dir=True,
fp16=True,
gradient_accumulation_steps=8,
load_best_model_at_end=True,
metric_for_best_model="eval_map@3",
lr_scheduler_type="cosine",
weight_decay=0.01,
save_total_limit=1,
)
我集成了 4 个模型,组合了以下元素:
OpenAssistant/reward-model-deberta-v3-large-v2deepset/deberta-v3-large-squad2microsoft/deberta-v3-largegte-basee5-base编号参考 此数据集 的来源标识。
我在推理时使用了低排名检索结果。设置 4 种 TTA 策略:
[ 0, 1, 2, 3, 4, 5][ 0, 6, 7, 8, 9, 10][ 0, 11, 12, 13, 14, 15][ 0, 16, 17, 18, 19, 20]数组中的数字代表问题的检索排名。
TTA 后未使用简单平均分数,而是采用最大值与平均值相加的方式:
df = pd.read_csv("test.csv") # len(df) == 测试数据量
df["id"] = np.arange(len(df))
df = ensemble(df) # len(df) = 测试数据量 × TTA数量 × 模型数量
df = df.groupby("id").mean() + df.groupby("id").max()