DTT: An Example-Driven Tabular Transformer……大型语言模型的示例驱动表格变换器2312

DTT: An Example-Driven Tabular Transformer for Joinability by Leveraging Large Language Models

标题: 使用大型语言模型的示例驱动表格变换器DTT:实现可连接性
作者: 阿拉什·达尔加希·诺巴里(加拿大阿尔伯塔大学)和达乌德·拉菲伊(加拿大阿尔伯塔大学)

方法: 我们的框架可以高效地学习从源格式到预期目标格式的映射模式,只需少量示例即可应用于表格连接、填补缺失值和错误检测等任务。与现有的映射和连接方法相比,我们的框架在真实世界和合成数据集上表现出更高的准确性和可扩展性。

实验结果: 我们的实验评估显示,使用我们微调模型的框架表现与GPT-3等大型语言模型相当或更好,尽管它们的大小有显著差异。此外,在我们的框架内使用大型语言模型能提升它们的表现。

目录

一、介绍

背景

挑战

研究内容

现有方法

本文贡献

举例说明

工作内容

二、相关内容补充

1. 示例驱动的表格数据转换

2. 语言建模和文本到文本转换

3. 应用于表格数据的语言模型

三、我们的框架

1. 分解器和序列化器

2. 标记器和模型

3.聚合器

4.下游任务

5. 实验与分析

背景与问题

训练数据的特点

合成数据生成

数据集用于评估

实验设置

评估指标

性能比较

详细分析

观察

知识库转换的性能

与DataXFormer的比较

运行时间和扩展性

与大型语言模型基线的性能比较


一、介绍

本文的重点是表格数据(例如,电子表格、网络表格和关系数据库)的自动转换

背景

  • 近年来,实体和政府推动数据发布与共享,使得许多组织依赖第三方数据源。然而,从多个来源收集数据会导致数据不匹配的问题。商业数据库系统在整合异构数据源方面支持不足,手动整合既费时又低效。
  • 现有的最新数据整合方法依赖相似性函数和文本转换,但通常无法处理需要多个映射的复杂情况,或者超出简单文本转换范围的映射。

挑战

  1. 数据格式转换难题: 将数据从一种格式转换为另一种格式一直是数据集成和管理中的挑战。传统方法依赖手动指南和规则,但现代数据库的规模和复杂性使手动方法不切实际。
  2. 巨大搜索空间: 转换的搜索空间非常大,随着编辑操作和参数空间的增加,搜索空间呈指数级增长。尽管有方法通过限制操作数量、抽样输入和应用剪枝策略来减少搜索空间,但仍然相对较大,导致找到映射所需时间过长。
  3. 示例的可用性和噪音处理: 示例通常由用户提供(有限但准确)或自动生成(丰富但不准确)。现实中不可避免会有噪音和数据不一致,模型需要在有限示例下表现良好,并能从大量示例中受益,同时对数据噪音和不准确性具有鲁棒性。

研究内容

  1. 表格数据转换: 自动化的表格数据转换,包括电子表格、网页表格和关系数据库。
  2. 映射关系学习: 给定源表和目标表之间的几个匹配行示例,学习映射关系。
  3. 应用场景: 数据连接、填补缺失值和自动完成、错误检测和校正。

现有方法

  1. 传统方法主要依赖于文本和语义相似性
  2. 近年来的方法则引入了机器学习和深度神经网络模型,用于处理表格数据中的格式不匹配问题。然而,这些模型存在一些局限性,比如不能预测缺失值、提供建议或检测异常值。
  3. 另一条研究路线侧重于找到源表和目标表之间的映射关系,从而将源数据的格式转换为目标数据的格式。
  4. 现有的方法通常依赖于基于字符串的转换和参数空间的穷举搜索。然而,面临的挑战是如何适应同一表格中不同行的多样化格式要求。

本文贡献

  1. 提出DTT: 一个新的基于示例驱动的表格数据转换方法,利用预训练语言模型的能力。
  2. 开发多样化数据集: 使用合成示例训练模型,实验表明在各种领域的真实数据上表现优异。
  3. 提出端到端框架: 包括分解器、序列化器、模型和聚合器,展示其在表连接中的有效性。
  4. 广泛评估: 在不同领域的大量数据集上,证明我们的方法在准确性和运行时间方面优于现有最先进基准。
  5. 资源公开: 提供代码、框架、预训练模型、合成数据生成器和真实世界基准供研究社区使用。

举例说明

我们的目标是为 S中的任何值找到目标格式。例如,值 'Jean Chretien' 和 'Kim Campbell' 可能被映射为 'jchretien' 和 'kcampbell'。

这种转换可以用于使表格可连接,例如允许源表格的一列与目标表格的一列连接。它还可以用于填充目标列中的缺失值。在本研究中,我们假设源值和示例已经提供。这是为了限制问题的范围,并集中精力在数据转换上。

如果用户未提供示例,则可以使用不等连接方法或基于token示例生成方法来提供示例集。但需要注意,自动生成的示例可能包含噪声和无效对,我们将讨论如何处理这些嘈杂的示例。

工作内容

  • 示例驱动的表格数据转换
  • 语言建模和文本到文本转换
  • 应用于表格数据的语言模型

二、相关内容补充

1. 示例驱动的表格数据转换

在表格数据转换的研究领域中,有多种方法旨在通过示例来实现源格式到目标格式的转换。这些方法主要集中在处理电子表格数据方面,以下是几种代表性方法的概述和比较:

  1. FlashFill 和 BlinkFill:是早期的方法,它们通过一组用户提供的示例构建输入图,然后遍历该图以生成基于子字符串的文本转换。这些转换将源值映射到相应的目标值。然而,它们严重依赖于用户提供的示例的准确性,无法有效处理示例中的噪声。
  2. Auto-join:为了解决示例中噪声的问题,Zhu等人提出了Auto-join方法。该方法使用预定义的基于字符串的转换单元(如子串和分割)来描述转换过程。它通过自动生成示例的子集来处理噪声,并应用递归回溯算法以找到最佳的转换。尽管Auto-join能够处理输入中的小噪声,并通过使用预定义的转换单元限制搜索空间,但在计算上可能会很昂贵,特别是在处理大量数据时。
  3. Common String-based Transformer (CST):CST利用源和目标示例之间的公共文本序列作为转换的骨架,进一步限制了基于字符串的转换的搜索空间。与Auto-join类似,CST也使用基于字符串的转换单元,但它采用独立生成每行转换的策略,以更好地处理输入中的噪声。转换根据其覆盖范围进行排序,以构建最终的转换集。相比Auto-join,CST提供了更好的噪声处理和运行时性能,但它仍然受限于基于子字符串的转换单元,并且通常只在源和目标示例之间存在长匹配序列时表现良好。
  4. DTT:示例驱动的表格转换器,旨在通过利用大型语言模型(LM),克服现有方法中对搜索空间的限制。DTT独立地为每生成转换,以更灵活地处理输入中的噪声,并通过LM生成预期的目标表示。这种方法有望提高转换的覆盖率和准确性,特别是在处理复杂数据转换时表现出色。

综上所述,各种方法在处理表格数据转换中都有其优缺点。未来的研究可以继续探索如何结合语言模型和更智能的搜索算法,以进一步提高表格数据转换的效率和准确性。

2. 语言建模和文本到文本转换

大型语言模型是我们框架的核心组成部分,下面简要介绍了这些模型的背景和发展:

  1. 屏蔽语言建模
  • LM)都基于屏蔽语言建模的概念。在这种方法中,给定序列中的一些标记被屏蔽(或损坏),模型被训练以预测这些被屏蔽的标记。这种训练方法帮助模型理解上下文并进行下一个词的预测。
  1. 早期的预训练模型
    • Word2Vec和GloVe:这些是最早用于预训练的模型,它们使用浅层神经网络生成每个词的静态矢量化嵌入,用于表示词汇的语义信息。
  2. 上下文化嵌入的引入
    • ELMo:为了提升嵌入的语境感知能力,ELMo使用两层双向LSTM来观察单词前后的上下文,生成单词的上下文化嵌入。与静态嵌入不同,ELMo的嵌入能够根据上下文变化而变化,提升了语义表示的质量。
  3. Transformer的引入
    • Transformer:Vaswani等人引入了基于自关注机制的Transformer模型,该模型能够更好地并行化处理文本数据,不会给附近的单词赋予过多的权重。Transformer主要由编码器、解码器或两者组成,适用于各种自然语言处理任务。
  4. 不同类型的语言模型
    • BERT:仅编码器模型,专注于学习输入文本的潜在表示,适用于需要理解输入文本的任务,如分类、命名实体识别等。
    • GPT-2和GPT-3:仅解码器模型,广泛用于生成给定上下文的自然语言文本,例如对话生成、文章写作等。
    • 序列到序列模型:例如T5和BART,这些模型使用编码器生成输入的潜在表示,并将其传递给解码器,以生成所需任务的新文本。这种结构在文本生成和机器翻译等任务中表现出色。

通过利用这些先进的语言模型,我们的框架能够更有效地处理表格数据的转换任务,提高了转换的准确性和泛化能力。

3. 应用于表格数据的语言模型

我们提出的模型也遵循编码器-解码器架构,专门设计用于DTT中的生成任务。

在应用方面,这些模型被广泛应用于不同的数据处理任务,包括实体匹配、文本到SQL 、问答系统和数据生成文本。这些任务与我们的任务有所区别,但表格序列化已经成为许多这些任务中的通用模块。为了在保留所需结构关系的同时将表格转换为序列,已经开发出多种序列化技术。由于需要保留的结构关系可能依赖于具体任务,因此选择合适的序列化方法也可能是任务相关的。例如,Iida等人将行和列分别作为两个单独的序列传递给两个变压器块,并对每个单元格的行和列值进行平均,以生成单元格的表示。而在RPT 中,使用两个特殊的令牌 [A] 和 [V] 对表格进行序列化,分别编码属性名称和其对应的值。

三、我们的框架

1. 分解器和序列化器

用于通过例子集将源表中的每一行转化为目标表中的行。这个过程使用大型语言模型(LLM),例如BERT和GPT-3,这些模型对输入长度有一定的限制。由于表格数据可能非常大,需要对问题进行分解,将大问题拆解成多个小任务,从而在不超过模型输入长度限制的情况下处理数据。

  1. 输入长度限制:大型语言模型(LLM)通常对输入长度有限制,例如BERT限制在512个tokens内,GPT-3限制在2048个tokens内。然而,对于大表格和大量示例,这个长度限制可能不够用。因此,需要将问题拆分成小任务,每个任务都能适应模型的输入长度限制。
  2. 任务分解:将一个大的转换任务分解成多个小的子任务,每个子任务只包含少量的上下文示例。例如,假设我们选取两个例子作为上下文,每个子任务就只包含两个示例和一个要转换的源行。
  3. 选择上下文示例:对于每一个需要转换的源行,从示例集中选择两个示例作为上下文。所有可能的上下文示例组合可以表示为 E2E_2E2 ,即所有从示例集中选取两个示例的组合。然后,对于每一行 sis_isi ,可以有 ∣E2∣|E_2|∣E2∣ 种可能的上下文组合。
  4. 示例编码:为了编码输入数据,使用特殊符号来标记源和目标行的开始和结束。例如,用 <tr> 标记源和目标,用 <eoe> 分隔两个示例,用 <sos> 和 <eos> 标记输入的开始和结束。举个例子,假设我们有两个上下文示例和一个要转换的源行,编码可以表示为 <sos> 示例1源行 <tr> 示例1目标行 <eoe> 示例2源行 <tr> 示例2目标行 <eoe> 要转换的源行 <tr> <eos>。
  5. 多次提示模型:每个源行可以与不同的上下文组合一起多次输入模型。每次输入模型都会生成一个预测的目标行,这些预测结果可以在后续步骤中进行聚合。
  6. 子任务的大小:子任务的大小取决于源行和目标行的长度、模型的输入长度限制以及转换的复杂性。一般来说,更复杂的转换需要更多的示例来更好地描述操作。为了减少歧义,通常选择两个示例作为上下文。

总的来说,这种方法通过分解大任务、选择适当的上下文示例、使用特殊符号编码输入以及多次提示模型,来处理大表格数据的转换问题,确保每次输入都在模型的长度限制内,并通过聚合多个预测结果来提高准确性和一致性。

2. 标记器和模型

如何将表格数据转化为适合大语言模型(LLM)处理的形式,特别是在选择合适的分词器和模型架构方面的一些技术细节。以下是对这段文字的分解和解释:

在自然语言处理(NLP)中,模型通常期望输入是向量,因此需要首先对输入进行分词(tokenization),然后将每个词元(token)分配给一个向量。对于传统的NLP任务,分词是非常明确的步骤,但在处理表格数据时,如何选择分词方式就不那么显而易见了。

  1. 分词器的选择

传统的NLP模型(如word2vec、GloVe)使用词汇中的单词作为分词单位,并且将词汇表中没有的单词统一处理为一个未知词元。现代的深度学习模型更倾向于使用能更好处理词语形态结构的分词方式,比如WordPiece或Byte Pair Encoding (BPE)。

  1. WordPiece和BPE

这两种分词方式会将频率更高的连续字节对作为新符号加入词汇表,即将单词分解成子词元(subword tokens)。这种方法在处理自然语言时非常有效,因为常见单词会作为单个词元处理,而罕见单词会被分解成多个词元。

  1. 表格数据的特殊性

在处理表格数据时,使用子词级分词器可能并不合适,因为表格中的值可能来自任何领域,并不一定是特定语言的单词。理解单词的意义或将它们分解成小的有意义的部分并不一定对预测输出有帮助。例如,对于“Justin Trudeau”和“J.Trudeau”这对,首字母“J”决定了输出中的“J”,而在另一个例子“Justin Trudeau”和“Trudeau, Justin”中,“Justin”作为一个整体出现在输出中。

  1. 字节级分词器

为了应对这些问题,采用字节级分词器(如ByT5)可能是更好的选择。字节级分词器在处理短文本任务时表现出色,表格单元格通常存储的是短文本内容。ByT5模型使用UTF-8字节编码器作为分词器,这结合了字符级分词器的准确性和相对较短的输入长度。

  1. 模型架构

将输入表示为一系列词元后,问题变成了文本到文本的转换任务。适合的模型架构是一个包含编码器和解码器的序列到序列模型(sequence-to-sequence model)。大多数表格嵌入模型使用WordPiece和BPE分词器并且仅使用编码器架构,或者依赖表格的元数据和结构,这使得它们不适用于当前的问题设置。

  1. 不平衡架构

研究表明,当输入是字符序列时,使用更深层的编码器比平衡模型表现更好。ByT5模型是一个字节级模型,其编码器部分比解码器部分深三倍,这被用作训练的起点。这意味着编码器有更多层,可以更深入地处理输入数据,而解码器层数较少,更专注于生成输出。与原始模型不同的是,我们对目标中的所有字符进行掩码,训练目标是预测被掩码的字节。解码器是自回归的,仅将初始词元传递给解码器。

3.聚合器

如何在多个上下文中使用序列到序列模型(sequence-to-sequence model)来预测目标表中的行,并结合这些预测来生成最终结果。

通过这种方法,利用不同的上下文多次输入模型并生成多个候选输出,然后通过统计这些候选输出的频率,选择出现频率最高的输出作为最终预测结果。这种方法能够缓解由于数据噪声和不一致性带来的影响,并提高预测的准确性。

4.下游任务

如何使用所提出的模型在各种下游任务中生成目标行,并着重讨论了异构表格的连接(join)任务。

模型的应用:给定一个源行和一组源-目标示例对,所提出的模型能够生成一个符合这些示例的目标行。这个框架在许多下游任务中都很有用,如自动完成和自动填充电子表格、预测缺失值、错误纠正以及表格连接等。

通过这种方法,模型可以在源表和目标表之间建立连接,即使源表和目标表的列格式不同。关键在于利用模型生成的近似目标值和目标表中的值进行字符串相似性匹配,使用编辑距离来寻找最佳匹配。这种方法允许一定程度的预测误差,仍然能够有效地实现表格连接。

5. 实验与分析

背景与问题

尽管使用T5、BERT和GPT-2等预训练生成模型可以处理大量未标记的数据,但对于我们特定的任务,依赖这些模型的预训练知识并不足够。真实世界的表格数据通常较短,且同列的不同条目之间关联性较低。这使得预训练语言模型的知识在这种任务中作用有限。因此,我们提出生成合成数据来训练模型。

训练数据的特点

训练数据需要具备以下几个关键特征:

  1. 源-目标对组织:数据应以源-目标对的形式组织,并根据相应的转换进行分类。
  2. 数据量大:数据集必须足够大,以便训练拥有数亿参数的模型。
  3. 广泛的文本转换模式:数据应覆盖各种文本转换模式和不同输入长度。
  4. 不限语言:生成的数据不应局限于特定语言中的单词,因为表格中的许多术语并非词典中的单词,且可能不限于某一种语言。

合成数据生成

我们通过构建一组文本转换(包括子字符串、拆分、大小写转换和常量等基本转换单元),随机选择单元和参数,生成多样化的例子。每个转换的输出由其单元的输出拼接而成。此外,我们允许最多三个转换单元的随机堆叠,以增加数据的多样性。源文本随机生成,包括字母、数字、符号和特殊字符。生成的源文本长度也随机选择。

数据集用于评估

我们使用三组真实世界的数据集和四组合成数据集来评估方法的有效性:

  1. Web表格数据集(WT:包括31对表格,来自17个不同主题,平均每表92.13行,每行31个字符。
  2. 电子表格数据集(SS:包括108对表格,主要来自微软Excel产品团队和用户帮助论坛,平均每表34.43行,每行19个字符。
  3. 知识库Web表格数据集(KBWT:包括从知识库中获取的81对表格,平均每表113行,每行13个字符。
  4. 一般合成数据集(Syn:包括10对表格,通过随机文本转换生成,包含10个表,每个表100行。
  5. 简单合成数据集(Syn-RP:包括5对表格,通过随机替换一个字符生成,输入长度8到35个字符。
  6. 中等难度合成数据集(Syn-ST:类似于Syn-RP,但使用单个子字符串转换单元。
  7. 困难合成数据集(Syn-RV:包括5对表格,通过反转所有字符生成,输入长度8到35个字符。

实验设置

我们训练了一个包含2000组转换的合成数据集,每组生成10对源-目标样本,输入长度随机在8到35之间。80%的样本用于训练,20%用于验证。在评估中,每个输入表的行被分成两等份,一份作为上下文输入模型,另一份用于测试。我们使用五次不同上下文输入的平均结果来提高预测的鲁棒性。

评估指标

对于每个样本对 (𝑠, 𝑡),我们将模型预测与目标 𝑡 的编辑距离最小化视为正确预测。具体评估指标包括:

  • 准确率 (Precision):正确预测的比例。
  • 召回率 (Recall):源行正确映射的比例。
  • F1-Score:准确率和召回率的调和平均数。
  • 平均编辑距离 (AED):预测与目标之间的编辑距离平均值。
  • 平均归一化编辑距离 (ANED):根据目标长度归一化的平均编辑距离。

性能比较

我们将DTT的性能与三种最先进的基线方法进行了比较:

  1. Common String-based Transformer (CST)【31】:
    • 基于一组示例寻找文本转换以实现表格连接。
  2. Auto-FuzzyJoin (AFJ)【25】:
    • 使用一组相似性函数检测最可能连接的行。
  3. Ditto【27】:
    • 对预训练的大规模语言模型 (DistilBERT) 进行微调以匹配实体。

表1总结了DTT与基线方法在准确率、召回率和F1-Score上的性能。结果表明,在真实世界数据集上,DTT在F1-Score和召回率方面优于所有基线方法。在合成数据集上,我们的方法在四个数据集中的三个上表现优异。对于Syn-RP和Syn-ST数据集,我们的方法性能与基线方法相当或略逊一筹,原因是这些数据集相对简单,源与目标之间具有显著的文本相似性。

详细分析

  1. 真实世界数据集
    • DTT在所有真实世界数据集上的F1-Score和召回率均优于基线方法,展示了其在处理复杂表格转换任务中的优势。
  2. 合成数据集
    • Syn-RPSyn-ST数据集:由于这些数据集的文本相似性较高,CST和AFJ利用其文本相似性检测优势表现出色。然而,DTT在Syn-ST数据集上仍然达到了88%的F1-Score,在Syn-RP数据集上达到了100%的F-Score,与AFJ表现相同,且优于CST和Ditto。
    • Syn-RV数据集:目标通过反转源文本获得,CST无法识别这种转换,因此在该数据集上的F1-Score为0%。AFJ和Ditto由于依赖相似性函数,在源与目标相似性不大时表现不佳。相比之下,DTT不依赖文本相似性,能在没有显著相似性的情况下生成目标文本,表现更好。
观察
  1. 不需要精确预测每个字符
    • 为了实现良好的连接性能,框架不需要预测每个字符都正确。通过聚合多个示例的结果并使用基于编辑距离的度量来形成连接候选,框架可以容忍一些不准确。例如,在Syn-RV数据集中,尽管平均归一化编辑距离超过80%,连接预测的F1-Score仍达到63%。
  2. 对未见过的变换具有良好表现
    • DTT在所有真实世界数据集和两个合成数据集Syn-RP和Syn-RV上表现优异,尽管其训练数据中不包括任何模拟反转输入或替换字符的操作,也未包含任何真实世界示例或变换。这表明模型不仅限于给定的变换集合,而是能够从输入示例中提取字符级别的模式。
知识库转换的性能

尽管模型仅在文本变换上进行了微调,但实验表明它可以涵盖一些需要知识库信息的语义变换。在需要利用知识库信息进行转换的KBWT数据集上,DTT在所有表格上的F1-Score达到了0.25,超过了所有基线模型。

与DataXFormer的比较

我们将DTT与DataXFormer的无监督模型进行了比较,因为我们的模型在训练过程中没有遇到任何基准数据集中的变换,只在合成的文本变换上进行了训练。尽管DataXFormer为优化知识库中的关系和表格而设计,我们的方法仍能与其媲美。观察表明,DTT在需要一般知识进行转换的场景中表现优异,例如‘Country To Citizen’和‘State To Abbreviation’任务。然而,在需要更多知识库参数化知识的任务中,如‘ISBN To Author’和‘City To Zip’,模型表现不如前者。这一限制可以通过利用通用大型语言模型(LLMs)来缓解。

运行时间和扩展性

由于DTT和Ditto需要GPU架构,而CST和AFJ需要CPU和内存,直接比较它们的运行时间是不可能的。然而,可以对模型的可扩展性做出一些观察。对于每行的映射预测时间,DTT是独立于行数的,并且随行长线性增长,而CST的时间随行数平方增长,随行长多项式增长。实验表明,当输入长度增加时,DTT的运行时间增长明显小于CST。例如,在我们的机器设置中,处理一个行长为5字符的合成数据集表格,DTT需要5秒,CST需要3秒。然而,当输入长度增加到50字符时,DTT需要不到17秒,而CST需要约90秒来完成连接。需要注意的是,DTT的运行时间包括分解、所有5次试验和聚合时间。

在行数可扩展性方面,我们比较了在“phone-10-short”和“phone-10-long”两个电子表格数据集上的性能,前者有7行,后者有100行,平均每行17个字符。DTT分别需要3和22秒完成短表和长表的处理,而CST分别需要4和366秒,AFJ分别需要4和38秒,Ditto分别需要1和10秒。虽然Ditto运行时间较短(由于其模型较小),但当输入长度增加时,其增长与DTT更为接近。此外,DTT在准确性上优于Ditto。这表明当输入在水平或垂直方向上增长时,我们的框架在运行时间上的可扩展性更好。

与大型语言模型基线的性能比较

大型语言模型(LLM)可以用于包括异构表连接在内的许多下游任务。研究表明,最新模型在零样本或少量样本设置下表现相对较好【5,6】。因此,它们设立了一个强有力的基线。在本节中,我们将我们的模型与GPT-3【5】进行比较,这是一种在许多任务中表现优异的最先进的LLM。相比于我们仅在20,000个合成生成样本上进行微调的ByT5-base模型,该模型包含约582M参数,GPT-3模型在数十亿的文档和资源(如网络表格)上进行了训练,参数量至少多一个数量级。我们在少样本设置下对GPT-3进行了实验,给定每个表中的1、2、3、5和10个随机选择的样本作为示例。由于输入源行可以映射到无限数量的目标,因此零样本设置在我们的情况下不适用。

在撰写本文时,GPT-3模型尚未公开发布,仅通过OpenAI商业API可访问4。我们使用了GPT-3的Curie模型。Curie被认为是非常强大、快速并能够执行许多高级任务的5。然而,模型规范和参数数量尚未公开。通过将Curie模型的一般性能与各种规模的GPT-3【5】的性能进行比较,可以假设Curie模型具有约70亿参数,并且在来自不同数据集的巨大文本数据上进行了训练。

  • 9
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值