Huggingface tokenizer decode batch_decode报错解决思路与分析

news2024/11/25 20:39:08

文章目录

    • 摘要
    • 引出原因
    • 最初报错的解决办法
    • batch_decode 源码
      • decode 和 batch_decode 都可以成功运行的例子
      • decode 和 batch_decode 不能同时成功运行的例子
      • 源码将输入转成 python list

摘要

本篇文章,由笔者最初遇到的decode报错开始,叙述笔者如何解决这个bug,并深入源码理清 decode 与 batch_decode的区别。

引出原因

最开始遇到了一个如下的报错,如果你运行我在下述给出的代码,你也能得到一个这样的报错信息。这个问题是由batch_decode引起的。
在这里插入图片描述
报错信息

  File "C:\Users\anaconda3\envs\lib\site-packages\transformers\tokenization_utils_base.py", line 3047, in <listcomp>
    self.decode(
  File "C:\Users\anaconda3\envs\lib\site-packages\transformers\tokenization_utils_base.py", line 3085, in decode
    return self._decode(
  File "C:\Users\anaconda3\envs\lib\site-packages\transformers\tokenization_utils_fast.py", line 507, in _decode
    text = self._tokenizer.decode(token_ids, skip_special_tokens=skip_special_tokens)
TypeError: Can't convert 0 to Sequence

通用代码部分:

import numpy as np
from transformers import AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained("任意一个预训练模型")

一个会报错的代码

arr = np.array(
    [0]
)
print(tokenizer.batch_decode(arr))

笔者刚开始想:
既然报错信息是decode函数报错,故我直接

print(tokenizer.decode(arr))

然而我惊讶的发现,这行代码居然能成功执行并输出 <pad>
凭借笔者现在给出的精简代码,读者可以很容易的发现是 batch_decode的问题。但笔者当时所在的项目代码量有点大,于是笔者一步步debug,才最终发现程序在 batch_decode这个函数所在位置崩溃。(我绝对不会告诉你们,当天晚上遇到这个bug之后,我直接放弃了,打游戏去了。)

我们在使用 decode 与 batch_decode 的过程中,发现任何可以使用 decode 的地方,都可以用 batch_decode 来代替。其实这种观点并不总是正确的。举个反例:numpy的一维数据,就不适用。笔者在下文会详细解释这个原因 。

最初报错的解决办法

将 numpy 的一维转成多维数据,即可解决这个bug。

arr = np.array(
    [[0]]
)
print(tokenizer.batch_decode(arr))

希望此方法,已经解决了您的问题,若您对该bug的细节感兴趣,可以继续往下阅读。
这是一个 numpy 类型的 bug。其他的 torch.tensor,python list,皆不存在此问题。

batch_decode 源码

   def batch_decode(
       self,
       sequences: Union[List[int], List[List[int]], "np.ndarray", "torch.Tensor", "tf.Tensor"],
       skip_special_tokens: bool = False,
       clean_up_tokenization_spaces: bool = True,
       **kwargs
   ) -> List[str]:
       return [
           self.decode(
               seq,
               skip_special_tokens=skip_special_tokens,
               clean_up_tokenization_spaces=clean_up_tokenization_spaces,
               **kwargs,
           )
           for seq in sequences
        ]

decode: 解码一维数据
batch_decode:解码多维数据
通过浏览源码发现,batch_decode 使用了一个列表推导式调用 decode 进行解码。所以这就是: 我们时常将batch_decode 与 decode混用的原因。

decode 和 batch_decode 都可以成功运行的例子

tensor_arr = [0, 1, 2, 3]
print(tokenizer.decode(tensor_arr))
print(tokenizer.batch_decode(tensor_arr))

输出结果

<pad></s><unk> 
['<pad>', '</s>', '<unk>', '']

decode 和 batch_decode 不能同时成功运行的例子

不支持 numpy 的一维数据

np_arr = np.array([0, 1, 2, 3])
print(tokenizer.decode(np_arr))
print(tokenizer.batch_decode(np_arr))

只需要将上述的列表转成 numpy,就会报错。(转成 torch.tensor 不会报错)

源码将输入转成 python list

这里给出的一些函数都是源码,若您不感兴趣,建议直接看后面的结论。

# Convert inputs to python lists
token_ids = to_py_obj(token_ids)
def to_py_obj(obj):
    """
    Convert a TensorFlow tensor, PyTorch tensor, Numpy array or python list to a python list.
    """
    if isinstance(obj, (dict, UserDict)):
        return {k: to_py_obj(v) for k, v in obj.items()}
    elif isinstance(obj, (list, tuple)):
        return [to_py_obj(o) for o in obj]
    elif is_tf_available() and _is_tensorflow(obj):
        return obj.numpy().tolist()
    elif is_torch_available() and _is_torch(obj):
        return obj.detach().cpu().tolist()
    elif isinstance(obj, np.ndarray):
        return obj.tolist()
    else:
        return obj

tokenizer.decode 会将输入 (类型为:TensorFlow tensor, PyTorch tensor, Numpy array or python list) 都转成 list,再进行解码操作。

_decode中,会将int型的整数也转成 python list。

if isinstance(token_ids, int):
    token_ids = [token_ids]

将对象转成 python list时,使用isinstance 根据对象类型转成 python list。

np_arr = np.array([0, 1, 2, 3])
for item in np_arr:
	print(item, type(item))

numpy 一维数据,单个item 的类型是 numpy.int32, 源码没有把这个类型转成list, 从而引发错误。(笔者觉得huggingface 可以专门针对 numpy.int32这个类型, 实现将其转成list,但是huggingface并没有做这项工作。)

(在此感谢您的浏览,若您觉得这些工作帮助到了您,可以给我们一个赞,这样笔者会感到他工作是有意义的!)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/765756.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

继连续亏损后,软银依然下注机器人,今年能否在人工智能浪潮中分一杯羹?

原创 |文 BFT机器人 近日&#xff0c;将近7个月没露面的孙正义&#xff0c;现身软银集团年度股东大会并表示&#xff0c;软银目前账面现金有5万亿日元&#xff08;约合人民币2547亿元&#xff09;&#xff0c;已准备好将防守模式转变为进攻模式&#xff0c;All in AI&#xff…

imazing怎么导出app,Imazing修改APP存档的方法【2023详解】

相信很多小伙伴都不清楚Imazing导出APP及能够帮助我们更好地去管理手机&#xff0c;还能够替换从网上下载的游戏存档&#xff0c;让用户可以有一个更好地体验&#xff0c;那么具体要如何去操作呢&#xff1f;下面就跟着小编一起来看看Imazing修改APP存档的方法吧。 使用软件 iM…

修改windows文件没有权限

一、问题描述&#xff1a;有时候我们在修改windows文件时&#xff0c;提示没有修改权限。 二、解决方案 修改windows的hosts文件 为例

Android平台GB28181设备接入侧音频采集推送示例

技术背景​ GB/T28181是广泛应用于视频监控行业的标准协议规范&#xff0c;可以在不同设备之间实现互联互通。今天我们主要探讨Android平台的Audio采集部分。 先说如何拿到数据源&#xff0c;在Android平台上采集音频&#xff0c;常用的方式如下&#xff1a; 1. 使用MediaRe…

LeetCode206.反转链表

LeetCode206.反转链表 一、双指针法 这道题如果再定义一个新的链表&#xff0c;实现链表元素的反转&#xff0c;其实是对内存空间的浪费 我们只需要改变链表的next指针的指向&#xff0c;直接将链表反转 之前链表头节点是元素1&#xff0c;反转之后头节点是元素5&#xff0c;…

Qt与Web混合开发:实现双向通信

引言 在当今的软件开发中&#xff0c;将Qt和Web技术结合起来进行混合开发变得越来越流行。Qt作为强大的C框架&#xff0c;提供了丰富的图形界面和功能库&#xff0c;而Web技术则提供了灵活性和跨平台的优势。结合这两种技术&#xff0c;我们可以开发出功能强大、具有吸引力的应…

【电路原理学习笔记】第4章:能量与功率:4.2 电路中的功率

第4章&#xff1a;能量与功率 4.2 电路中的功率 电能转换成热能所产生的热量&#xff0c;通常是电流通过电路中的电阻而产生的不必要的副产品。然而&#xff0c;在某些情况下&#xff0c;产生热量是电路的主要目的&#xff0c;例如&#xff0c;电阻式加热器。 当有电流通过电…

NLP 开源形近字算法之相似字列表(番外篇)

需求 有时候我们并不是需要返回两个字的相似&#xff0c;而是需要返回一个汉字的相似列表。 实现思路 我们可以分别计算所有的汉字之间的相似度&#xff0c;然后保留最大的前100个&#xff0c;放在字典中。 然后实时查询这个字典即可。 实现方式 bihuashu_2w.txt 中我们主…

BUG解决Button类不能从UnityEngine.UI中引用

Button does not contain a definition for onClick and no accessible extension method onClick accepting a first argument of type Button could be found (are you missing a using directive or an assembly reference?) 一个非常奇葩的问题;突然!!!!! using UnityEn…

什么是低代码开发平台(apaas)?低代码开发平台的价值有哪些

手码6500字&#xff0c;带你快速看懂&#xff1a;什么是低代码开发平台&#xff08;apaas&#xff09;&#xff0c;低代码有哪些价值&#xff0c;以及低代码平台的使用逻辑和心得。 一、什么是低代码开发平台&#xff08;apaas&#xff09;&#xff1f; 低代码开发平台是一种a…

【C++ 学习记录】(一)--你好,C++

写在前面 工作需要&#xff0c;重学C&#xff0c;实在是太痛苦了&#xff0c;大二的时候应试就没学会&#xff01;&#xff01; 进入正题 1.编程是怎么回事 C在百科上的解释是一种静态数据类型检查 的、支持多种编程范式&#xff08;面向过程与面向对象等&#xff09;的通用…

BTP Integration Suite学习笔记 - (Unit3) Developing with SAP Integration Suite

BTP Integration Suite学习笔记 - (Unit1) Developing with SAP Integration Suite BTP Integration Suite学习笔记 - (Unit2) Developing with SAP Integration Suite 带着一个问题去学&#xff1a;明明可以直接访问一个后端系统的OData服务&#xff0c;为什么还要再多绕一道C…

UE学习记录02----UMG创建控件模板+事件分发器

官网4.27&#xff1a; 创建控件模板 | 虚幻引擎文档 (unrealengine.com) 使用UMG创建的每个 控件蓝图 都被视为 用户控件&#xff0c;其可在其他控件蓝图中重复使用和放置。 其视觉效果和脚本功能都将延续到该蓝图中。 利用某些蓝图脚本&#xff0c;可创建UI控件的运行方式或…

echarts——环形图

const value_ze 60 const value2_ze 30 var myChart echarts.init(document.getElementById(myChart)); var option {title: {text: 目标完成率,subtext: [{a|${value_ze}}, {b|%}].join(),itemGap: 10,textStyle: {fontSize: 14,color: #fff,fontWeight: 500},subtextStyl…

springboot拦截器无法进行属性注入

文章目录 问题描述问题原因问题解决解决方法一解决方法二 总结 问题描述 今天在使用拦截器的时候遇见了一个奇怪的错误&#xff0c;就是在对拦截器进行属性注入的时候为null&#xff0c;具体如下 运行代码出现空指针异常 就是注入的Gson为null&#xff0c;这个问题很奇怪&a…

STM32 HAL库定时器输入捕获SlaveMode脉宽测量

STM32 HAL库定时器输入捕获SlaveMode脉宽测量 SlaveMode模式简介 ✨SlaveMode复位模式&#xff1a;在发生一个触发输入事件时&#xff0c;计数器和它的预分频器能够重新被初始化&#xff1b;同时&#xff0c;如果TIMx_CR1寄存器的URS位为低&#xff0c;还会产生一个更新事件UEV…

SQLSERVER中exec 与 exec sp_executesql 的用法及比较

SQLSERVER 提供 exec 与 exec sp_executesql &#xff08;2005版本开始&#xff09;执行动态sql。 一、EXEC 命令有两种用法 1、执行存储过程 exec 存储过程 参数 值 --或 exec 存储过程 值 exec 存储过程 存储过程中的参数参数{接受参数返回值} outputCREATE PROC…

空气净化器触摸屏中应用的电容式触摸芯片

现在人们对于居住环境要求较高&#xff0c;许多家庭会选用空气净化器吸咐污物。那么空气净化器原理是什么&#xff1f;空气净化器工作原理分为两种&#xff1a; 被动式空气净化器原理&#xff1a;是用风机将空气抽入机器&#xff0c;通过内部的滤网过滤空气&#xff0c;起到过滤…

亚马逊气候友好碳中和认证

CLIMATE PLEDGE FRIENDLY AND CARBON NEUTRAL Climate Pledge Friendly气候友好认证&#xff0c;亚马逊推出的气候友好认证是一种自愿性&#xff0c;倡导性的认证。那么这个Climate Pledge Friendly是个什么样的认证&#xff0c;如何才能获得这个气候友好认证标签呢&#xff1…

使用onnx和onnxruntime完成模型部署

模型部署定义 深度学习模型部署是指训练好的模型在特定环境中运行的过程。 模型部署的流水线如下&#xff1a; 使用任意一种深度学习框架来定义网络结构并训练模型训练好的模型的网络结构和参数会被转换成一种只描述网络结构的中间表示&#xff08;如&#xff0c;onnx、torch…