开源方案学习

202568

9:42

Retrieval:

 

2名用llm2vec这个库,用SentenceTransformerTrainer训练,但是llm2vec这个包太老,自己想办法换成其他的方案。

Flagembedding微调。

 

5名:

  • library: SentenceTransfomer
  • model: dunzhang/stella_en_1.5B_v5
  • negative mining params
    • range_min: 512
    • num_negatives: 2
  • lora config
    • r: 32
    • lora_alpha: 64
  • loss: CachedMultipleNegativesRankingLoss
  • epoch: 1

 

 

8名和第11名,都用transformer库的Automodel 和自定义Biencoder

4名用model = Qwen2ModelLabel.from_pretrained(model_path, quantization_config=bnb_config)

 

 

11名:(重点学习):

自定义Trainer中实现了evaluate函数,是不是单独控制eval的过程,eval时,eval_dataset不经过data_collator

 

关于在训练过程中cuda oom的问题,可能是某个batch中有个很长的句子序列,由于pad=longest,会将当前batch中所有样本都pad到这个最长序列的长度,导致oom,解决方法:

1. 硬截断:绝对长度限制

方法:在分桶之前,直接丢弃或截断超过安全阈值的样本(核心理念:牺牲少量数据保训练稳定性)

 

python

max_safe_length = 1024  # 根据你的显存调整(例如 24GB 显存建议 ≤1024)

 

def filter_long_samples(example):

    return len(example["input_ids"]) <= max_safe_length

 

dataset = dataset.filter(filter_long_samples)  # 直接丢弃超长样本

# 或者强制截断(如果语义允许)

tokenizer(input_text, truncation=True, max_length=max_safe_length)

适用场景:长样本是少数异常值,且对任务影响不大时。

 

2. 动态批处理(Dynamic Batching)

原理:根据当前 batch 的实际序列长度动态调整 batch_size

实现方案:

 

python

from transformers import Trainer, TrainingArguments

 

# 自定义动态 batch 的 DataCollator

class DynamicBatchCollator:

    def __init__(self, tokenizer, max_tokens=8192):  # max_tokens = batch_size * max_len

        self.tokenizer = tokenizer

        self.max_tokens = max_tokens

 

    def __call__(self, features):

        features.sort(key=lambda x: len(x["input_ids"]), reverse=True)

        batches = []

        current_batch = []

        current_tokens = 0

       

        for feature in features:

            seq_len = len(feature["input_ids"])

            if current_tokens + seq_len > self.max_tokens:

                batches.append(current_batch)

                current_batch = []

                current_tokens = 0

            current_batch.append(feature)

            current_tokens += seq_len

       

        if current_batch:

            batches.append(current_batch)

       

        # 对每个小 batch 单独 pad

        return [self.tokenizer.pad(batch, return_tensors="pt") for batch in batches]

 

# 在 Trainer 中使用

trainer = Trainer(

    ...,

    data_collator=DynamicBatchCollator(tokenizer, max_tokens=8192),

)

 

 

已使用 OneNote 创建。