NLP实践——使用Llama-2进行中文对话

NLP实践------使用Llama-2进行中文对话

  • [1. 前言](#1. 前言)
  • [2. 利用prompt](#2. 利用prompt)
  • [3. 利用Logit Processor](#3. 利用Logit Processor)
    • [3.1 修改1](#3.1 修改1)
    • [3.2 修改2](#3.2 修改2)
    • [3.3 修改3](#3.3 修改3)
    • [3.4 修改4](#3.4 修改4)

1. 前言

在之前的博客 NLP实践------Llama-2 多轮对话prompt构建中,介绍了如何构建多轮对话的prompt,本文将介绍如何使用Llama-2进行中文对话。

现有的很多项目,在开源的Llama-2基础上,进行了中文场景的训练,然而Llama-2本身就具有多语种的能力,理论上是可以直接运用于中文场景的。

本文所举例使用的模型为Llama-2-7b-chat-hf。

2. 利用prompt

首先可以想到的是,使用prompt。可是即便是在prompt中添加了要求模型回答中文的提示,模型仍然回答的是英文。

从对话内容可以看到,模型可以理解用户的问题,却没有输出中文:

复制代码
>> '你好'
>> "Hello! 😊 I'm here to help answer any questions you may have. Is there something specific you'd like to know or discuss? Please feel free to ask, and I'll do my best to assist you. 🤖"

3. 利用Logit Processor

在之前另一篇博客 以Llama-2为例,在生成模型中使用自定义LogitsProcessor中,介绍了怎样使用logits processor来改变生成过程中的概率,进而改变生成的结果。那么可以直接想到的是,把tokenizer中所有中文字符的概率调大一些,就可以强行要求模型生成中文了。

3.1 修改1

首先利用unicode范围获取常见的汉字:

python3 复制代码
import re
def is_chinese(word):
    """
    判断一个字符串是否为汉字
    """
    if re.match('[\u4e00-\u9fff]', word):
        return True
    else:
        return False

CHINESE_TOKEN_IDS = [token_id for token, token_id in tokenizer.vocab.items() if is_chinese(token)]

然后就可以实现一个processor来提高这些token对应的概率:

python3 复制代码
from transformers.generation.logits_process import LogitsProcessor, LogitsProcessorList

class ChineseLogitsProcessor(LogitsProcessor):
    """
    生成中文字符
    ---------------
    ver: 2023-08-02
    by: changhongyu
    """
    def __init__(self, 
                 chinese_token_id_list: List[int] = None,
                 alpha: float = 5):
        """
        :param chinese_token_id_list: 中文token的token的id列表
        :param alpha: 放大倍数
        """
        self.chinese_token_id_list = chinese_token_id_list
        self.alpha = alpha
    
    def __call__(self, input_ids: torch.LongTensor, scores: torch.FloatTensor) -> torch.FloatTensor:
        for id_ in self.chinese_token_id_list:
            scores[:, id_] *= self.alpha
        return scores

在生成之前,按照之前博客中介绍的方法,创建processor:

python3 复制代码
logits_processor = LogitsProcessorList()
logits_processor.append(ChineseLogitsProcessor(CHINESE_TOKEN_IDS))

3.2 修改2

然而,模型却生成起来停不下了。这是因为没有将EOS token的概率也做相应的放大。

python3 复制代码
CHINESE_TOKEN_IDS.append(tokenizer.eos_token_id)

这下,模型可以输出中文了:

复制代码
>> '你好'
>> '好的好的大家好的我是一个智能问题机器人我可以回应你的问题请问你有任何问题或需要我的服务'

可是看起来好像哪里怪怪的,原来是没有标点。

3.3 修改3

既然没有标点,那我们再把标点符号的概率也放大就好了:

python3 复制代码
puncs = [',', '。', '?', '!', '"', '"', ':', ',', '.', '?', '!', '"', "'", ':']
CHINESE_TOKEN_IDS = [token_id for token, token_id in tokenizer.vocab.items() if is_chinese(token)]
CHINESE_TOKEN_IDS.extend(tokenizer.convert_tokens_to_ids(puncs))
CHINESE_TOKEN_IDS.append(tokenizer.eos_token_id)

现在,eos也有了,标点符号也有了,然而还是出意外了:

复制代码
>> '你好'
>> '::你好!我是一个智能问题机器人,我的任务是回应用户的问题。请问你有任何问题?'

3.4 修改4

现在模型倒是可以说中文,也带标点了,但标点出现在了最开头。这样的话,我们可以再添加一个processor,不让这些标点出现在最开始就可以了。

python3 复制代码
class SuppressSpecificBOSTokenLogitsProcessor(LogitsProcessor):
    """
    防止生成的第一个token是某些特定的token
    ---------------
    ver: 2023-08-02
    by: changhongyu
    """
    def __init__(self, bad_bos_token_id_list: List[int] = None):
        """
        :param bad_bos_token_id_list: 不可以作为第一个token的token的id列表
        """
        self.bad_bos_token_id_list = bad_bos_token_id_list
    
    def __call__(self, input_ids: torch.LongTensor, scores: torch.FloatTensor) -> torch.FloatTensor:
        new_token_len = input_ids.shape[-1] - current_token_len
        if new_token_len == 0:
            for id_ in self.bad_bos_token_id_list:
                scores[:, id_] = -float('inf')
        return scores

将两个processor放在一起:

python3 复制代码
logits_processor = LogitsProcessorList()
logits_processor.append(ChineseLogitsProcessor(CHINESE_TOKEN_IDS))
logits_processor.append(SuppressSpecificBOSTokenLogitsProcessor([tokenizer.convert_tokens_to_ids(punc) for punc in puncs]))

终于,可以让模型实现中文对话了:

复制代码
>> '你好'
>> '好的,好的!你好!对不起,我不知道你问的问题,请问你想问些事情?'

虽然回答的还是有点奇怪,但使用中文与模型进行对话的目的,也的的确确是达到了。

相关推荐
可触的未来,发芽的智生28 分钟前
触摸未来2025.10.06:声之密语从生理构造到神经网络的声音智能革命
人工智能·python·神经网络·机器学习·架构
动能小子ohhh42 分钟前
AI智能体(Agent)大模型入门【6】--编写fasteAPI后端请求接口实现页面聊天
人工智能·python·深度学习·ai编程
SCBAiotAigc1 小时前
huggingface里的数据集如何下载呢?
人工智能·python
我是Feri1 小时前
机器学习之线性回归的特征相关性:避免“双胞胎特征“干扰模型
人工智能·机器学习
SaN-V1 小时前
针对 OpenMMLab 视频理解(分类)的 MMAction2 的环境配置
人工智能·openmmlab·mmcv·视频理解·mmaction2
拉姆哥的小屋1 小时前
深度学习图像分类实战:从零构建ResNet50多类别分类系统
人工智能·深度学习·分类
深瞳智检2 小时前
YOLO算法原理详解系列 第007期-YOLOv7 算法原理详解
人工智能·算法·yolo·目标检测·计算机视觉·目标跟踪
神奇的代码在哪里2 小时前
基于【讯飞星火 Spark Lite】轻量级大语言模型的【PySide6应用】开发与实践
人工智能·大语言模型·pyside6·讯飞星火spark·spark lite
蒋星熠2 小时前
反爬虫机制深度解析:从基础防御到高级对抗的完整技术实战
人工智能·pytorch·爬虫·python·深度学习·机器学习·计算机视觉
qq_340474022 小时前
0.6 卷积神经网络
人工智能·神经网络·cnn·卷积神经网络