首页 > 编程语言 >llamafactory/data/formatter.py [源码解析]

llamafactory/data/formatter.py [源码解析]

时间:2024-07-19 10:55:29浏览次数:16  
标签:slot llamafactory python self py 源码 str slots placeholder

import json
import re
from abc import ABC, abstractmethod
from dataclasses import dataclass, field
from typing import List, Literal, Optional, Tuple, Union

from .data_utils import SLOTS
from .tool_utils import DefaultToolUtils, GLM4ToolUtils


@dataclass
class Formatter(ABC):
    slots: SLOTS = field(default_factory=list)
    tool_format: Optional[Literal["default", "glm4"]] = None

    @abstractmethod
    def apply(self, **kwargs) -> SLOTS: ...

    def extract(self, content: str) -> Union[str, List[Tuple[str, str]]]:
        raise NotImplementedError


@dataclass
class EmptyFormatter(Formatter):
    def __post_init__(self):
        has_placeholder = False
        for slot in filter(lambda s: isinstance(s, str), self.slots):
            if re.search(r"\{\{[a-zA-Z_][a-zA-Z0-9_]*\}\}", slot):
                has_placeholder = True

        if has_placeholder:
            raise ValueError("Empty formatter should not contain any placeholder.")

    def apply(self, **kwargs) -> SLOTS:
        return self.slots

 

我会为您逐行解释这段代码:

python

复制

from .data_utils import SLOTS
from .tool_utils import DefaultToolUtils, GLM4ToolUtils

这些是导入语句,从当前包的其他模块导入所需的类型和工具。

python

复制

@dataclass
class Formatter(ABC):

定义了一个名为Formatter的抽象基类,使用了@dataclass装饰器。

python

复制

    slots: SLOTS = field(default_factory=list)

定义了一个名为slots的属性,类型为SLOTS,默认值是一个空列表。

python

复制

    tool_format: Optional[Literal["default", "glm4"]] = None

定义了一个名为tool_format的可选属性,可以是"default"或"glm4",默认为None。

python

复制

    @abstractmethod
    def apply(self, **kwargs) -> SLOTS: ...

定义了一个抽象方法apply,它接受任意关键字参数并返回SLOTS类型。子类必须实现这个方法。

python

复制

    def extract(self, content: str) -> Union[str, List[Tuple[str, str]]]:
        raise NotImplementedError

定义了一个extract方法,但默认实现抛出NotImplementedError。子类可以选择性地重写这个方法。

python

复制

@dataclass
class EmptyFormatter(Formatter):

定义了一个名为EmptyFormatter的类,它继承自Formatter

python

复制

    def __post_init__(self):

这是一个在对象初始化后自动调用的方法。

python

复制

        has_placeholder = False
        for slot in filter(lambda s: isinstance(s, str), self.slots):
            if re.search(r"\{\{[a-zA-Z_][a-zA-Z0-9_]*\}\}", slot):
                has_placeholder = True

这段代码检查self.slots中的字符串是否包含占位符(形如{{name}})。

python

复制

        if has_placeholder:
            raise ValueError("Empty formatter should not contain any placeholder.")

如果发现占位符,抛出ValueError异常。这是因为EmptyFormatter不应包含任何占位符。

python

复制

    def apply(self, **kwargs) -> SLOTS:
        return self.slots

EmptyFormatterapply方法简单地返回self.slots,不进行任何处理。

这段代码定义了一个格式化器的基础结构。Formatter是一个抽象基类,定义了格式化器应该具有的基本接口。EmptyFormatter是一个具体的实现,它不对输入进行任何处理,只是简单地返回原始的slots。这种设计允许在需要时创建更复杂的格式化器,同时保持了一个统一的接口。

@dataclass
class StringFormatter(Formatter):
    def __post_init__(self):
        has_placeholder = False
        for slot in filter(lambda s: isinstance(s, str), self.slots):
            if re.search(r"\{\{[a-zA-Z_][a-zA-Z0-9_]*\}\}", slot):
                has_placeholder = True

        if not has_placeholder:
            raise ValueError("A placeholder is required in the string formatter.")

    def apply(self, **kwargs) -> SLOTS:
        elements = []
        for slot in self.slots:
            if isinstance(slot, str):
                for name, value in kwargs.items():
                    if not isinstance(value, str):
                        raise RuntimeError("Expected a string, got {}".format(value))

                    slot = slot.replace("{{" + name + "}}", value, 1)
                elements.append(slot)
            elif isinstance(slot, (dict, set)):
                elements.append(slot)
            else:
                raise RuntimeError("Input must be string, set[str] or dict[str, str], got {}".format(type(slot)))

        return elements

我会为您逐行解释这段代码:

python

复制

@dataclass
class StringFormatter(Formatter):

这定义了一个名为StringFormatter的类,它继承自Formatter类。@dataclass装饰器用于自动生成一些常用的方法,如__init____repr__等。

python

复制

    def __post_init__(self):

这是一个特殊方法,在对象初始化后自动调用。它用于执行一些额外的初始化逻辑。

python

复制

        has_placeholder = False
        for slot in filter(lambda s: isinstance(s, str), self.slots):
            if re.search(r"\{\{[a-zA-Z_][a-zA-Z0-9_]*\}\}", slot):
                has_placeholder = True

这段代码检查self.slots中的字符串是否包含占位符(形如{{name}})。它使用正则表达式来查找这种模式。

python

复制

        if not has_placeholder:
            raise ValueError("A placeholder is required in the string formatter.")

如果没有找到占位符,抛出一个ValueError异常。

python

复制

    def apply(self, **kwargs) -> SLOTS:

定义apply方法,接受任意关键字参数,返回类型为SLOTS(这可能是在其他地方定义的类型)。

python

复制

        elements = []

初始化一个空列表来存储处理后的元素。

python

复制

        for slot in self.slots:
            if isinstance(slot, str):

遍历self.slots中的每个元素。如果元素是字符串:

python

复制

                for name, value in kwargs.items():
                    if not isinstance(value, str):
                        raise RuntimeError("Expected a string, got {}".format(value))

                    slot = slot.replace("{{" + name + "}}", value, 1)

用提供的关键字参数替换字符串中的占位符。如果值不是字符串,抛出RuntimeError

python

复制

                elements.append(slot)

将处理后的字符串添加到elements列表。

python

复制

            elif isinstance(slot, (dict, set)):
                elements.append(slot)

如果slot是字典或集合,直接添加到elements列表。

python

复制

            else:
                raise RuntimeError("Input must be string, set[str] or dict[str, str], got {}".format(type(slot)))

如果slot既不是字符串也不是字典或集合,抛出RuntimeError

python

复制

        return elements

返回处理后的elements列表。

总的来说,这个StringFormatter类用于处理包含占位符的字符串模板。它确保模板中至少有一个占位符,并提供了一个apply方法来用实际值替换这些占位符。这种formatter可能用于生成结构化的文本,如聊天模板或其他需要动态内容填充的场景。

标签:slot,llamafactory,python,self,py,源码,str,slots,placeholder
From: https://blog.csdn.net/sinat_37574187/article/details/140532988

相关文章

  • llamafactory/model/loader.py [源码解析]
    classTokenizerModule(TypedDict):tokenizer:"PreTrainedTokenizer"processor:Optional["ProcessorMixin"]def_get_init_kwargs(model_args:"ModelArguments")->Dict[str,Any]:r"""Getsargu......
  • CentOS6.5yum安装Python3⛱️
    CentOS6.5yum安装Python3⛱️ 1.在CentOS6.5上通过Webtatic仓库安装Python3[root@localhost~]#rpm-Uvhhttps://mirror.webtatic.com/yum/el6/latest.rpm[root@localhost~]#yum-yinstallpython34upython34u-devel2.安装pip[root@localhost~]#yum-yi......
  • 使用Python爬虫下载视频源码
    一、引言(●ˇ∀ˇ●)在当今互联网时代,视频内容已成为人们获取信息和娱乐的重要方式。有时,我们可能希望将这些视频下载到本地,以便在没有网络的情况下观看。本文将介绍如何使用Python编写一个简单的爬虫。二、环境准备......
  • Pytorch模型文件`*.pt`与`*.pth` 的保存与加载
    1.*.pt文件.pt文件保存的是模型的全部,在加载时可以直接赋值给新变量model=torch.load("filename.pt")。具体操作:(1).模型的保存torch.save(model,"Path/filename.pt")(2).模型的加载model=torch.load("filename.pt")注意:torch.load()的参数使用字符串参数。2..p......
  • 【蓝牙】Android 13 蓝牙源码分析
    Android13在蓝牙模块中进行了多项改进和优化。本文将详细分析其核心组件及其工作原理,包括BluetoothManagerService、AdapterService、AdapterProperties、蓝牙连接管理和JNI接口。1.BluetoothManagerServiceBluetoothManagerService是蓝牙管理的核心类,负责启动和停止蓝......
  • Python - Conda - 对比 conda 和 pip
    之前已经写过一篇和工具相关的文章:《工具篇:makeasparrowcmakebuildsystem》,本文继续这个话题,大家可能都用过conda和pip,但是对于他们的区别和关系,可能大家不一定很清楚,本文来尝试做一些总结。一、conda1.1简介conda是一个通用的包管理器,意思是什么语言的包都可以用它进行管......
  • 计算机毕业设计Python+Tensorflow小说推荐系统 K-means聚类推荐算法 深度学习 Kears
    2、基于物品协同过滤推荐算法2.1、基于⽤户的协同过滤算法(UserCF)该算法利⽤⽤户之间的相似性来推荐⽤户感兴趣的信息,个⼈通过合作的机制给予信息相当程度的回应(如评分)并记录下来以达到过滤的⽬的进⽽帮助别⼈筛选信息,回应不⼀定局限于特别感兴趣的,特别不感兴趣信息的纪录也相......
  • 计算机毕业设计PySpark+Django高考志愿填报推荐系统 高考预测 高考大数据分析 Hadoop
    摘要本文旨在设计与实现一个基于Spark的高考志愿填报推荐系统,旨在帮助高考生根据自身成绩和兴趣,精准推荐合适的大学和专业。系统采用大数据处理框架Spark,结合机器学习算法,实现了对高考数据的深度挖掘和分析,为考生提供科学、有效的志愿填报建议。系统捕捉考生个人特征、......
  • Python 文件操作与管理:Open函数、Json与Pickle、Os模块
    1.open函数的使用Python中的open()函数是处理文件的标准方法。它允许你打开一个文件,并对其进行读取、写入或追加操作open(file,mode,encoding)函数的格式:file:文件路径mode:打开方式(读:r写:w读完之后光标停留在最后读取的位置......
  • Python数据获取(网页视频、音频版)
    爬取数据,上一章有介绍,不懂流言私信或者评论交流即可,在Python中编写爬虫通常涉及以下几个步骤:发送HTTP请求:使用requests库向目标网站发送请求。解析网页内容:使用BeautifulSoup从HTML中解析出需要的数据。下载视频文件:使用requests下载视频文件。保存到本地:将下载的视频文件......