大模型LLM微调的数据集及使用方法

微调大型语言模型(LLM)通常需要大量的标注数据。以下是一些常用的公开数据集,适用于微调各种任务,如文本分类、问答、命名实体识别等。同时,我将提供使用这些数据集的基本方法。

1. 公开数据集

1.1 文本分类
  • IMDB 数据集:用于情感分析任务,包含电影评论及其对应的情感标签(正面或负面)。
  • AG News 数据集:包含新闻文章及其对应的类别标签(如世界、体育、商业、科技)。
1.2 问答
  • SQuAD (Stanford Question Answering Dataset):包含大量的问题和对应的答案,适用于问答任务。
  • CoQA (Conversational Question Answering):包含对话形式的问答数据。
1.3 命名实体识别
  • CoNLL-2003:包含新闻文章及其对应的命名实体标签(如人名、地名、组织名)。
  • OntoNotes 5.0:包含多种文本类型及其对应的命名实体标签。

2. 使用方法

以下是使用这些数据集进行微调的基本步骤。假设你使用的是 Hugging Face 的 Transformers 库。

2.1 安装依赖

首先,确保你已经安装了必要的库:

pip install transformers datasets
2.2 加载数据集

使用 Hugging Face 的 datasets 库加载公开数据集。

2.2.1 文本分类

以 IMDB 数据集为例:

from datasets import load_dataset

# 加载 IMDB 数据集
dataset = load_dataset('imdb')

# 查看数据集结构
print(dataset)
2.2.2 问答

以 SQuAD 数据集为例:

from datasets import load_dataset

# 加载 SQuAD 数据集
dataset = load_dataset('squad')

# 查看数据集结构
print(dataset)
2.2.3 命名实体识别

以 CoNLL-2003 数据集为例:

from datasets import load_dataset

# 加载 CoNLL-2003 数据集
dataset = load_dataset('conll2003')

# 查看数据集结构
print(dataset)
2.3 数据预处理

在微调模型之前,需要对数据进行预处理,将其转换为模型输入格式。

2.3.1 文本分类

以 IMDB 数据集为例:

from transformers import BertTokenizer

# 加载预训练分词器
tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')

# 定义预处理函数
def preprocess_function(examples):
    return tokenizer(examples['text'], truncation=True, padding='max_length')

# 应用预处理函数
tokenized_datasets = dataset.map(preprocess_function, batched=True)
2.3.2 问答

以 SQuAD 数据集为例:

from transformers import BertTokenizer

# 加载预训练分词器
tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')

# 定义预处理函数
def preprocess_function(examples):
    questions = [q.strip() for q in examples['question']]
    inputs = tokenizer(
        questions,
        examples['context'],
        max_length=384,
        truncation="only_second",
        return_offsets_mapping=True,
        padding="max_length",
    )

    offset_mapping = inputs.pop("offset_mapping")
    answers = examples['answers']
    start_positions = []
    end_positions = []

    for i, offset in enumerate(offset_mapping):
        answer = answers[i]
        start_char = answer['answer_start'][0]
        end_char = start_char + len(answer['text'][0])
        sequence_ids = inputs.sequence_ids(i)

        # Find the start and end of the context
        idx = 0
        while sequence_ids[idx] != 1:
            idx += 1
        context_start = idx
        while sequence_ids[idx] == 1:
            idx += 1
        context_end = idx - 1

        # If the answer is not fully inside the context, label it (0, 0)
        if not (offset[context_start][0] <= start_char and offset[context_end][1] >= end_char):
            start_positions.append(0)
            end_positions.append(0)
        else:
            # Otherwise it's the start and end token positions
            idx = context_start
            while idx <= context_end and offset[idx][0] <= start_char:
                idx += 1
            start_positions.append(idx - 1)

            idx = context_end
            while idx >= context_start and offset[idx][1] >= end_char:
                idx -= 1
            end_positions.append(idx + 1)

    inputs["start_positions"] = start_positions
    inputs["end_positions"] = end_positions
    return inputs

# 应用预处理函数
tokenized_datasets = dataset.map(preprocess_function, batched=True, remove_columns=dataset['train'].column_names)
2.3.3 命名实体识别

以 CoNLL-2003 数据集为例:

from transformers import BertTokenizer

# 加载预训练分词器
tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')

# 定义预处理函数
def preprocess_function(examples):
    return tokenizer(examples['tokens'], is_split_into_words=True, truncation=True, padding='max_length')

# 应用预处理函数
tokenized_datasets = dataset.map(preprocess_function, batched=True)
2.4 模型微调

使用 Hugging Face 的 Trainer 类进行模型微调。

2.4.1 文本分类

以 IMDB 数据集为例:

from transformers import BertForSequenceClassification, Trainer, TrainingArguments

# 加载预训练模型
model = BertForSequenceClassification.from_pretrained('bert-base-uncased', num_labels=2)

# 配置训练参数
training_args = TrainingArguments(
    output_dir='./results',
    num_train_epochs=3,
    per_device_train_batch_size=16,
    per_device_eval_batch_size=64,
    warmup_steps=500,
    weight_decay=0.01,
    logging_dir='./logs',
)

# 创建 Trainer 实例
trainer = Trainer(
    model=model,
    args=training_args,
    train_dataset=tokenized_datasets['train'],
    eval_dataset=tokenized_datasets['test'],
)

# 开始训练
trainer.train()
2.4.2 问答

以 SQuAD 数据集为例:

from transformers import BertForQuestionAnswering, Trainer, TrainingArguments

# 加载预训练模型
model = BertForQuestionAnswering.from_pretrained('bert-base-uncased')

# 配置训练参数
training_args = TrainingArguments(
    output_dir='./results',
    num_train_epochs=3,
    per_device_train_batch_size=16,
    per_device_eval_batch_size=64,
    warmup_steps=500,
    weight_decay=0.01,
    logging_dir='./logs',
)

# 创建 Trainer 实例
trainer = Trainer(
    model=model,
    args=training_args,
    train_dataset=tokenized_datasets['train'],
    eval_dataset=tokenized_datasets['validation'],
)

# 开始训练
trainer.train()
2.4.3 命名实体识别

以 CoNLL-2003 数据集为例:

from transformers import BertForTokenClassification, Trainer, TrainingArguments

# 加载预训练模型
model = BertForTokenClassification.from_pretrained('bert-base-uncased', num_labels=len(dataset['train'].features['ner_tags'].feature.names))

# 配置训练参数
training_args = TrainingArguments(
    output_dir='./results',
    num_train_epochs=3,
    per_device_train_batch_size=16,
    per_device_eval_batch_size=64,
    warmup_steps=500,
    weight_decay=0.01,
    logging_dir='./logs',
)

# 创建 Trainer 实例
trainer = Trainer(
    model=model,
    args=training_args,
    train_dataset=tokenized_datasets['train'],
    eval_dataset=tokenized_datasets['validation'],
)

# 开始训练
trainer.train()

3. 总结

通过以上步骤,你可以使用公开数据集进行大型语言模型的微调。关键步骤包括数据加载、预处理、模型微调和评估。使用 Hugging Face 的 Transformers 库可以简化这些步骤,快速实现模型的微调。