首页 > 其他分享 >分词器tokenizers

分词器tokenizers

时间:2024-04-20 21:01:34浏览次数:29  
标签:tokenizer Tokenizer gemma tokenizers chat 分词器 role

总览

为了让语言变为模型能够理解的形式(tokens),每个字词必须映射为独一无二的序号,这时需要使用分词器 tokenizer 对语言进行转换。例如对于 “are you ok”,gemma 模型的 tokenizer 会将之转换为一个 List:[2, 895, 692, 4634]

顺便一提,第一个序号 2 是开始标记 <bos>

本文是学习 chat 模型微调留下的学习笔记,只记录了自认为必要的知识点。写得很乱,可能以后会整理一下。

使用 transformers 库的 Tokenizers

HuggingFace 家的 Tokenizers 提供了当下最常用的 tokenizer 实现。

为了方便学习,先实例化一个 tokenizers。

from transformers import AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained("google/gemma-2b-it")

gemma 的使用需要 token,为了方便可以换为 facebook/blenderbot-400M-distill 之类的模型。本文是以 gemma 为例。

现在,就可以通过 tokenizer.encode("are you ok") 看转换效果了。

Tokenizer 与 PreTrainedTokenizer

上面使用 AutoTokenizer.from_pretrained("google/gemma-2b-it") 获得的是 GemmaTokenizerFast 类变量,这个类继承于 transformers.PreTrainedTokenizerFast

可以通过 Tokenizer 对象实例化一个 PreTrainedTokenizerFast 对象。

from transformers import PreTrainedTokenizerFast

wrapped_tokenizer = PreTrainedTokenizerFast(
    tokenizer_object=tokenizer,
    bos_token="<|endoftext|>",
    eos_token="<|endoftext|>",
)

通过 wrapped_tokenizer.save_pretrained("path") 可以将 tokenizer 的整体状态保存为三个文件:tokenizer_config.json、special_tokens_map.json 和 tokenizer.json。若要从文件加载,就使用 PreTrainedTokenizerFast.from_pretrained("path") 实例化。

tokenizers.Tokenizer 类

tokenizers 库中 Tokenizer 类能够涵盖转换 tokens 的四步骤。

要将字符串转换为 tokens,需要经过以下四步骤:

Normalization,让字符串更 “干净”,会进行像是删空格和统一大小写这样的操作。

若词表大小足够大,这一步就不需要太多处理了。对于 gemma,这一步仅将空格变为下划线。

Pre-Tokenization,将字符串分割为单词。对于英语,就是根据空格进行分词。

若 Model 步骤不使用 WordLevel 方法(现在一般都不用 WordLevel 了),则 Pre-Tokenization 步骤不是必须的。

Model,通过字典将字符映射为序号。是 Tokenizer 的核心。

Post-Processing,添加 CLS SEP 等标记,便于让模型知晓何字符串时开始何时结束。

Tokenizer 对象是 GemmaTokenizerFast 的一部分。对于本文一开始生成的 tokenizer,可以通过 tokenizer._tokenizer 获得其包含的 Tokenizer 对象。

Model 步骤

Model 步骤是 Tokenizer 的核心,是 Tokenizer 的唯一必需过程。

Model 通过字典将字符映射为序号。至于如何配合字典将字符串分段,有着不同的算法:

  • WordLevel,最为经典的分段方法,直接将单词进行字典映射。这会导致像是 happy happier happiest 一类词被映射到完全不同的 ID,显著增加字典所需大小
  • BPE(Byte Pair Encoding),整个单词被拆分为字节,并根据实际将常见的字节组合构成词典条目。如此,便可像搭积木一般构造单词,所需字典词汇表更小
  • WordPiece,与 BPE 算法很像,目标都是希望像搭积木一般构造单词。但 WordPiece 不是先拆分为字节,而是先分为长句,若字典中不含该条目再进一步拆分
  • Unigram,其输出的子词分段能够带概率。比起 BPE,Unigram 将概率纳入考虑,选择可能性最大的那一个分词方法

WordLevel 现在一般不会用了。gemma 使用的是 BPE。

本节参考:

对话模板

chat 模型本质上是下一词预测(next-token prediction)模型,但它遵循了一个对话模板。具体来说,差不多就是输入字符串 问: 1+1等于几?答: 然后让模型补全剩下的字符。

写成 json,这段对话应当长成这样:

[
    {
        "role": "user",
        "content": "1+1等于几?",
    },
    {
        "role": "model",
        "content": "2",
    },
]

能够通过 tokenizer 的对话模板将 json 转换为模型输入。

对话模板本质是一段以字符串形式存储的脚本,可以通过 tokenizer.chat_template 得到。gemma 的对话模板的脚本框架是这样:

{{ bos_token }}

{% for message in messages %}
    {% if (message['role'] == 'user') != (loop.index0 % 2 == 0) %}
        {{ raise_exception('Conversation roles must alternate user/assistant/user/assistant/...') }}
    {% endif %}
        {% if (message['role'] == 'assistant') %}
            {% set role = 'model' %}{% else %}{% set role = message['role'] %}
        {% endif %}
    {{ '<start_of_turn>' + role + '\n' + message['content'] | trim + '<end_of_turn>\n' }}
{% endfor %}

{% if add_generation_prompt %}
    {{'<start_of_turn>model\n'}}
{% endif %}

tokenizer.chat_template 返回的脚本被压成了一行,需要手动分段才能得到上面这样有较好可读性的形式。

脚本很易读。大致是先放一个 bos_token,然后遍历每段对话进行处理。最后选择是否添加 <start_of_turn>model\n 来引导模型生成回答(而不是续写问题)。

调用 tokenizer.apply_chat_template() 时,可以传入 add_generation_prompt=True 使得该脚本最后的判断为真。

准本好 json 对话 chat,就可以使用 tokenizer.apply_chat_template(chat, tokenize=False) 看一下模板生成效果。

tokenizer.apply_chat_template(chat, tokenize=False)
# <bos><start_of_turn>user\n1+1等于几?<end_of_turn>\n<start_of_turn>model\n2<end_of_turn>\n

参考来源

标签:tokenizer,Tokenizer,gemma,tokenizers,chat,分词器,role
From: https://www.cnblogs.com/chirp/p/18148151

相关文章

  • ES分词器
    1 normalization:文档规范化,提高召回率2 字符过滤器(characterfilter):分词之前的预处理,过滤无用字符HTMLStripCharacterFilter:html_strip参数:escaped_tags需要保留的html标签MappingCharacterFilter:typemappingPatternReplaceCharacterFilter:typepattern_repl......
  • Elasticsearch-定制分词器
    一、内置分词器分词步骤1).characterfilter:在一段文本进行分词之前,先进行预处理,eg:最常见的过滤html标签(hello->hello),&->and(I&you->Iandyou)2).tokenizer:分词,eg:helloyouandme->hello,you,and,me3).tokenfilter:一个个小单词标准化转换lower......
  • MAC M1使用docker 安装es kibana ik分词器
    1.拉取elasticsearch镜像资源,本人下载的是8.6.2版本dockerpullelasticsearch:8.6.22.在本机中提前创建好yml文件elasticsearch.ymlhttp:  host:0.0.0.0xpack.security.enabled:falsexpack.security.enrollment.enabled:truexpack.security.http.ssl: enabl......
  • jieba 分词器包的导入
    anaconda安装jieba(被折腾了很久)终于搞定_anaconda离线安装jieba-CSDN博客在命令窗口pip的时候老师说让更新后面并且更新失败  ......
  • ElasticSearch中使用ik分词器进行实现分词操作
    简介:在默认的情况下,ES中只存在Stander分词器,但是这个分词器往往不满足我们的分词需求,这里通过ik分词器进行自定义我们的分词操作1、第一步将ik分词器进行下载下载地址:https://github.com/medcl/elasticsearch-analysis-ik需要注意,需要选择和自己的ES版本对应的版本2、将ik分词......
  • 3.分词器(Analyzer)
    分词器有什么用?分词器是搜索引擎的一个核心组件,负责对文档内容进行分词(在ES 里面被称为Analysis),也就是将一个文档转换成单词词典(Term Dictionary)。单词词典是由文档中出现过的所有单词构成的字符串集合。为了满足不同的分词需求,分词器有很多种,不同的分词器分词逻辑可能......
  • tokenizer分词器中的BPE分词方法的原理、样例、代码示例
    BytePairEncoding(BPE):想象一下你正在玩一种叫做“文字乐高”的游戏。在这个游戏中,你有很多小块,每个小块上写着一个字母或汉字。你的任务是用这些小块来构建单词或句子。开始时,你只能用单个字母或汉字的小块。但是游戏规则允许你找出那些经常一起出现的字母或汉字对,然后把它......
  • ES笔记:IK分词器
    ES中文档按照分词进行检索,对于中文,ES默认按照单个字进行分词,非常低效,可以使用专门的中文分词器,如IK分词器。下载:https://github.com/medcl/elasticsearch-analysis-ik/releases安装:在ES的plugins目录下新建一个目录,将下载的IK分词压缩包解压到此目录即可,然后重启ES该分词器便......
  • (十):IK分词器
    ElasticSearch默认的内置分词器standard是针对英文等拉丁语系设计的,是不支持中文分词的。IK分词器是一个开源的中文分词器插件,丰富和优化了Elasticsearch的设计。ES默认分词器standard对中文分词结果如下:1、IK分词器的特点IK分词器是ES的一个插件,有如下特点:......
  • ES--自定义分词器
    默认的拼音分词器会将每个汉字单独分为拼音,而我们希望的是每个词条形成一组拼音,需要对拼音分词器做个性化定制,形成自定义分词器。 elasticsearch中分词器(analyzer)的组成包含三部分:characterfilters:在tokenizer之前对文本进行处理。例如删除字符、替换字符tokenizer:将文......