tokenizer的group_texts

数据集

文本生成几乎是可以随便选择数据集的,毕竟建立语言模型不需要人工标注,只要是序列数据,哪怕是Latex公式,程序代码,都可以进行训练与生成。为了生成效果的有趣,我用水浒传进行了训练,看看模型能不能像绿林好汉一样说话。水浒传虽然有85万字,但只有2.5M的大小,比起各种论文中用来训练语言模型的文本来说实在是太小了。

Huggingface关于文本生成的官方教程里预处理部分我觉得写的不太清楚,推荐看这个Colab。在这我会分析一下其中最难懂的一个函数:

def group_texts(examples):
    block_size = 128
    # Concatenate all texts.
    concatenated_examples = {k: sum(examples[k], []) for k in examples.keys()}
    total_length = len(concatenated_examples[list(examples.keys())[0]])
    # We drop the small remainder, we could add padding if the model supported it instead of this drop, you can
    # customize this part to your needs.
    total_length = (total_length // block_size) * block_size
    # Split by chunks of max_len.
    result = {
        k: [t[i: i + block_size] for i in range(0, total_length, block_size)]
        for k, t in concatenated_examples.items()
    }
    result["labels"] = result["input_ids"].copy()
    return result
lm_datasets = tokenized_datasets.map(group_texts, batched=True)

明白这个函数的关键在于,examples的格式是什么样子的。Huggingface里单个样本的格式是一个字典,常见key比如"text","label","input_ids"。而在dataset.map()加了batched=True以后,group_texts函数收到的是多个样本组合而成的一个字典。具体来说,key与单个样本是一样的,但value是一个列表,列表的元素是单个元素的对应元素。

这样就很好理解函数的功能了。首先它会对于各个key,分别将batch内样本的对应value拼接在一起。因为value一般是列表,这里用sum()利用的是列表将+重载为拼接。接着它会按照block_size将拼接在一起的value再分割开。注意这里result的格式其实与输入是相同的,即key与单个样本是一样的,但value是一个列表。所以lm_datasets会将其重新拆为多个样本。此时样本个数已发生变化,变成了block个数。

转载:

【NLP入门】文本生成:水浒传 - 知乎 (zhihu.com)

你可能感兴趣的:(python,开发语言,深度学习,人工智能)