ImportError: /usr/lib/x86_64-linux-gnu/libstdc++.so.6: version `CXXABI_1.3.11′

报错信息

在docker中安装faiss后,测试可以正常导入,但是程序跑起来就会报错,报错信息如下:

ImportError: /usr/lib/x86_64-linux-gnu/libstdc++.so.6: version `CXXABI_1.3.11′ not found (required by /root/anaconda3/envs/cpu/lib/python3.6/site-packages/faiss/../../../libfaiss.so)

解决方案

首先查看导入错误的目录上有什么文件,发现确实没有需要的“`CXXABI_1.3.11”

strings /usr/lib/x86_64-linux-gnu//libstdc++.so.6 | grep CXXABI

ll /usr/lib/x86_64-linux-gnu//libstdc++.so.6

find /usr -name “libstdc++.so.*”

find / -name “libstdc++.so.*”

cp /root/anaconda3/envs/cpu/lib/libstdc++.so.6.0.29 /usr/lib/x86_64-linux-gnu/

cd /usr/lib/x86_64-linux-gnu/

find /usr -name “libstdc++.so.*”

rm libstdc++.so.6

ln -s libstdc++.so.6.0.29 libstdc++.so.6

strings /usr/lib/x86_64-linux-gnu/libstdc++.so.6 | grep CXXABI

参考

https://blog.csdn.net/wenroudebaozi/article/details/107564647

论文笔记:Label Semantic Aware Pre-training for Few-shot Text Classification

前言

论文:https://aclanthology.org/2022.acl-long.570.pdf

代码:https://github.com/amazon-research/label-aware-pretrain

摘要

在文本分类任务中,有用的信息编码在标签名称中。标签语义感知系统利用这些信息在微调和预测期间提高了文本分类性能。然而,标签语义在预训练中的应用还没有得到广泛的探讨。因此,作者提出标签语义感知预训练(LSAP)来提高文本分类系统的泛化和数据效率。LSAP通过对来自不同领域的带有标签的句子进行二次预训练,将标签语义整合到预训练生成模型中。由于预训练需要大量的数据,作者开发了一个过滤和标注pipline来自动从未标记的文本创建sentence-label对。

模型架构

标签语义感知预训练(LSAP)
  1. 在预训练阶级将标签语义融入生成模型的方法。
  2. 一种从无标记噪声数据中为标签语义感知预训练创建话语-意图对的方法。

方法

LSAP方法在(伪)标记样本的大规模集合上使用T5进行二次预训练。

  1. 使用对话行为分类器(dialogue act classifier)过滤未标记的数据。
  2. 使用意图生成器(intent generator)对通过过滤器的话语进行伪标记。
  3. 使用T5对标记数据和伪标记数据进行二次预训练
pipeline for creating utterance-intent pairs

Pre-training Formats

label denoising is best
  • Random span denoising,将每个意图标签(以自然语言格式)连接到其相关的话语。然后,我们随机干扰语音意图输入序列中15%的tokens,重建输出序列中连续的noised spans。这与T5使用的目标相同。
  • Intent classification,用下游监督微调使用的相同格式的话语和意图来监督微调T5。在这里,输入顺序是“intent classification: ”,然后是话语。输出序列是目的。
  • Label denoising,在训练话语和它们各自的意图前,确定性地对输入序列中的整个标签序列进行噪声化,并在输出序列中重构它。这是一种将意图分类任务框定为无监督去噪任务的方法。

总结

提出了一种利用标签中固有语义信息的预训练方法。提高了跨域小样本文本分类性能,同时在全资源设置下保持高性能。

论文笔记:Differentiable Prompt Makes Pre-trained Language Models Better Few-shot Learners

前言

论文:https://arxiv.org/pdf/2108.13161.pdf

代码:https://github.com/zjunlp/DART

动机

优化prompt是提高预训练语言模型在小样本学习中是很有必要的。离散标记的模板可能陷入局部最优,并且不能充分表示特定的类别。为了提高prompt方法在各个领域的适用性,论文提出了可微分提示(DifferentiAble pRompT),简称DART,可以减少提示工程的要求。

模型框架

利用语言模型中的一些参数作为模板和标签标记,并通过反向传播对它们进行优化,而不引入模型之外的其他参数。因为有限样本的微调可能会受到不稳定性的影响。进一步引入了一个辅助流畅性约束对象,以确保prompt嵌入之间的关联。减少提示工程(包括模板和标签)和外部参数优化。此外,该算法可以使用任何预训练的语言模型并可扩展到广泛的分类任务。

模型架构

Differentiable Template Optimization

由于语言token是离散变量,用token搜索找到最优提示并不简单,很容易陷入局部极小值.为了克服这些限制,作者利用伪标记(pseudo tokens)构造模板,然后用反向传播优化它们。可微模板优化可以获得超越原始词汇V的表达模板。将模板映射为如下形式:

DART利用辅助流畅性约束目标将提示嵌入彼此关联起来,从而促进模型专注于上下文表示学习。

Differentiable Label Optimization

暴力强制标签搜索:(1)由于验证集通常非常大,需要进行多轮评估,计算量大且繁琐。(2)可扩展性差,随着类数的增加呈指数型增长,因此很难处理。此外,类别的标签包含丰富而复杂的语义知识,一个离散的标记可能不足以表示这些信息。

DART将Yj映射到一个连续词汇空间,如下所示:

为了避免优化任何外部参数,{h1,…,hm,..,hm+n}替换为未使用的token

Training Objectives

由于提示模板中的伪标记必须彼此相互依赖,作者引入了辅助的流畅性约束训练,而没有优化任何其他参数。总体而言,有两个目标:the class discrimination objective(LC)和the fluency constraint objective(LF)

Class Discrimination Objective

是对句子进行分类的主要目标,CE是交叉熵损失函数。

Fluency Constraint Objective

为了确保模板标记之间的关联,并维护从PLMs继承来的语言理解能力,作者利用MLM的流畅性约束对象,对输入语句中的一个标记进行随机掩码,并进行掩码语言预测。该语言模型可以通过模板标记之间的丰富关联获得更好的上下文表示。

为了小样本微调的不稳定性,作者联合优化模板和标签。

结论

论文介绍了一种简单而有效的优化方法DART,它改进了fast-shot learning预训练语言模型。与传统的优化方法相比,所提出的方法可以在小样本的情况下产生令人满意的改进。该方法还可用于其他语言模型(如BART),并可扩展到其他任务,如意图检测和情感分析。

论文笔记:Unified Structure Generation for Universal Information Extraction

前言

论文:https://arxiv.org/pdf/2203.12277.pdf

代码:https://github.com/universal-ie/UIE

动机

  1. 信息抽取旨在从非结构化文本中识别并结构化用户指定的信息(user-specified information)
  1. IE任务是高度多样化的,由于:
  • varying targets(entity / relation / event / sentiment…)
  • heterogeneous structures(span / triplet / record…)
  • demand-specific schemas
  1. 然而,目前,多数方法是任务特定的(task-specialized),导致对于不同的IE任务需要构建:
  • dedicated architectures(专门的结构
  • isolated models(孤立的模型)
  • specialized knowledge sources(利用专门的知识源)
  1. 上述,任务特定的解决方案,阻碍了IE系统的
  • rapid architecture development(快速的结构发展):为大量的IE tasks / settings / scenarios 构建专门的结构过于复杂
  • effective knowledge sharing(有效的知识共享):孤立的模型限制了相关任务或者设置之间的知识共享
  • quick cross-domain adaptation(快速的跨领域适应):为不同的任务构建数据集:成本高、耗时
  1. 由此,论文提出Universal IE,即:
  • 统一建模不同的IE任务
  • 自适应地预测异构的结构
  • 有效从不同数据源进行学习
  1. 挑战:如何自适应地控制抽取过程?
  • 不同的目标结构
  • 不同的schema

主要贡献

  • 提出了a unified text-to-structure generation architecture
  • 设计structured extraction language和structural schema instructor(SSI)
  • 首个text-to-generation的预训练抽取模型,对后续研究有益
  • 在低资源、少样本场景中表现出on-demand adaptation ability,验证了方法的有效性、通用性、可迁移性

方法创新(SSI+Text⇒SEL)

UIE结构图

UIE方法

  1. 将所有的IE任务都建模为 text-to-structure transformations
    • 将不同的任务都分解为一系列的原子转化操作,包括:
      • spotting:
        • 定位与给定的语义类型相关的span
        • 例如:steve是一个person实体
      • associating:
        • 链接不同的span,并给他们分配预定义的schema涉及的语义角色
        • 例如:将steve和apple链接,分别将其视为work-for关系的arg1和arg2
    • 上述做法可以使所有的IE任务都共享相同的、底层的spotting和associating操作
  2. structured extraction language(SEL)(为了建模不同的IE结构)
    •  基本元素:
      • SpotName:span的类型
      • AssoName:association的类型
      • InfoSpan:具体的span内容
    •  结构:( Spot Name:Info Span (Asso Name:Info Span) )
SEL结构
  1. structural schema instructor(SSI)(为了自适应地生成不同的目标结构)
    • a schema-based prompt mechanism,用来控制:
      • what to spot
      • what to associate
      • what to generate
    • 构建提示作为输入,基本元素:
      • SpotName
      • AssoName
      • special symbols([spot] / [asso] / [text])
    • 结构:[spot] xx [spot] xx … [asso] xx [asso] xx … [text] x_1, x_2, … , x_n
  2. A large-scale pre-trained text-to-structure model(为了从不同数据源学习通用的IE能力)
    • 三个预训练数据集
      • D_pair
      • D_text
      • D_record
    • 三个任务,联合训练
      • D_pair:同时优化编码器、解码器
      • D_text:同时优化编码器、解码器(masked生成)
      • D_record:仅优化解码器(语言模型)
    • 微调:防止暴露偏差,引入rejection mechanism (RM),即引入噪音,例如(facility: [NULL])
  3. 整体的流程
  • 根据任务 / schema,构建SSI
  • 拼接SSI和text,输入模型
  • 生成SEL
  • 后处理形成最终结果

论文笔记:FlipDA: Effective and Robust Data Augmentation for Few-Shot Learning

前言

论文:https://arxiv.org/abs/2108.06332

代码:https://github.com/zhouj8553/FlipDA

背景和挑战

大多数以前的文本数据增强方法都局限于简单的任务和弱基线。作者在困难任务(小样本的自然语言理解)和强基线(具有超过10亿个参数的预训练模型)上做数据增强。

在困难任务和强基线模型下,很多以前的文本数据增强方法,最多只带来边际增益,有时会大大降低性能。在许多情况下,使用数据增强会导致性能不稳定,甚至进入故障模式。

方法

作者提出了一种新的数据增强方法FlipDA,该方法联合使用生成模型和分类器来生成标签翻转数据。FlipDA的核心思想是发现生成标签翻转数据比生成标签保留数据对性能更重要。与保留原始标签的增强数据相比,标签翻转数据往往大大提高了预训练模型的泛化能力。实验表明,FlipDA在有效性和鲁棒性之间实现了很好的权衡,它在不影响其他任务的同时,极大地改善了许多任务。在小样本的设定下,有效性和鲁棒性是数据增强两个关键要求。

有效性(Effectiveness)

数据增强应该在某些特定任务上显著提高性能。

FlipDA: Automatic Label Flipping

1、在不使用数据增强的条件下,训练分类器(对预训练的模型进行微调)

2、生成标签保留和标签翻转的增强样本

首先使用完形填空模式将x和y组合成一个序列,然后随机mask一定百分比的输入的tokens。然后使用预训练的T5模型来填补空白,形成一个新的样本。如果T5不能预测出新样本的y值,删除这个样本是有益的。使用T5生成增强样本确实引入了额外的知识并减少了语法错误,但仅使用T5进行增强而不进行标签翻转和选择效果不佳。

基于prompt的增强算法保存/翻转标签数据

3、使用分类器为每个标签选择概率最大的生成样本

Si 是从原始样本 (xi , yi ) 增强的数据集合,y 不等于 yi

样本 xi 的数据增强集合
删除预测为 yi 的增强的数据,保留标签翻转的增强的数据
增强的标签反转的数据
数据选择政策

4、用原始样本和附加的增强样本重新训练分类器

鲁棒性(Robustness)

数据增强方法在任何时候不应该遇到故障模式(failure mode)。故障模式在小样本学习中很常见,在这种情况下,一些微小的更改可能会导致性能大幅下降。

What Contribute to Failure Modes?

大多数增强方法都是基于标签保留的假设,而自动方法生成标签保留的样本是一个挑战。如果模型在保持标签的假设下,在有噪声的增强数据上进行训练,性能下降是可能的。作者将噪音数据总结为两类,一类是导致理解困难的语法错误,另一类是改变标签关键信息的修改。

结论

标签翻转提高了小样本的泛化性,论文提出具有自动标签翻转和数据选择的FilpDA算法。实验证明了FlipDA的优越性,在有效性和鲁棒性方面都优于以往的方法。在未来,从理论上理解在现有数据点附近生成标签翻转数据为什么以及如何提高泛化将是至关重要的。此外,增加增强数据生成的多样性和质量也是一个重要的长期目标。

代码运行顺序

1、运行基线模型(Run Baseline)

bash scripts/run_pet.sh <task_name> <gpu_id> baseline

结果会保存在results/baseline/pet/<task_name>_albert_model/result_test.txt文件中

2、产生增强的文件(Produce augmented files)

CUDA_VISIBLE_DEVICES=0 python -m genaug.total_gen_aug --task_name <task_name> --mask_ratio <mask_ratio> --aug_type <aug_type> --label_type <label_type> --do_sample --num_beams <num_beams> --aug_num <aug_num>

备选方案:使用不带分类器的增强文件运行基线模型,如果希望将增强文件中的所有增强数据添加到模型中(不希望根据训练过的分类器更改标签或过滤增强样本),可以运行如下命令。

bash scripts/run_pet.sh boolq 0 <augmented_file_name>

3、用增强的文件运行FlipDA(Run FlipDA with augmented files)

如果允许分类器对增广数据的标签进行校正,则执行如下命令,其中<augmented_file_name>是增强文件名,例如,”t5_flip_0.5_default_sample0_beam1_augnum10″。

bash scripts/run_pet.sh boolq 0 genaug_<augmented_file_name>_filter_max_eachla

如果不允许分类器纠正增强数据的标签,则运行如下命令

bash scripts/run_pet.sh boolq 0 genaug_<augmented_file_name>_filter_max_eachla_sep

选择哪个命令取决于增强模型和分类模型的relative power。如果增强模型足够精确,选择带有“sep”的命令会更好。否则,选择第一个。如果不确定,就两种都试试。

论文笔记:STraTA: Self-Training with Task Augmentation for Better Few-shot Learning

前言

论文:https://arxiv.org/pdf/2109.06270.pdf

代码:https://github.com/google-research/google-research/tree/master/STraTA

STraTASelf-Training with Task Augmentation,基于任务增强的自训练

亮点

  1. STraTA使用任务增强技术,首先训练一个生成模型,然后使用给定目标任务的无标签文本合成大量域内训练数据,用于辅助任务微调,得到辅助任务模型。
  2. STraTA自训练算法使用标记和伪标记的样本迭代学习更好的模型。在每次迭代中,利用teacher-student方法,从任务扩展产生的辅助任务模型开始,并在广泛分布的伪标记数据上进行训练。

模型

模型架构

模型主要分为两个部分,一个是Task augmentation,生成Auxiliary-task Model;另一个是Self-training,利用teacher-student模式迭代训练。

任务描述

假设给定任务T,包括带标签的数据集L和无标签的数据集U,无标签的数据集U可以通过L人工制造,或者可以来自目标域或相关数据集/域的未标记文本。

任务增强(Task augmentation)

任务增强模块使用自然语言推理(NLI)作为辅助(中间)训练任务,以提高下游性能。

任务增强建立在最近的关于中间任务训练的NLP研究的基础上,其中预先训练的语言模型(如BERT)在目标任务之前对辅助任务进行微调。

论文关于中间微调的工作,使用的辅助数据集是一个固定目标任务无关的数据集,如MNLI或SQuAD。这种选择的一个明显的限制是辅助任务和目标任务之间的域不匹配,使用任务增强方法解决这一问题。对于给辅助任务A,利用无标签数据U结合微调的预训练生成语言模型合成大量的目标任务T域内的数据,来提高目标任务T的性能。

Generating synthetic NLI data

使用预训练的T5模型在带标签的句子对上做微调。训练样本将(sentA, sentB)→label 转化为(label, sentA)→sentB,获得微调的样本。将目标任务的数据集的数据经过微调的T5数据生成器生成增强样本。在推理时,向模型输入一个NLI标签label 和一个来自目标域的未标注的句子xj,以生成一些输出句子xk : (label,xj)→xk 。然后通过创建(xj, xk)→label 这样的样本来形成用于中间任务(Synthetic In-domain Auxiliary-task Data)微调的数据。

自训练(Self-training)

任务增强使用未标注的文本为中间辅助任务生成合成数据,而自训练是一种补充方法,它通过使用伪标记示例直接在目标任务上进行训练来改进模型。

self-training伪代码

Starting with a strong base model

自训练算法的一个重要组成部分是基础模型f0。成功的自训练通常需要一个良好的基础模型,它可以在未标注的样本上提供很大比例的“正确”预测或伪标记;否则,错误会在后期的自训练中传播或放大。在每次自训练迭代中,总是从相同的基础模型f0开始,该模型使用来自预训练/中间微调阶段(例如,任务增强中的辅助任务训练阶段),然后使用标注数据和伪标注数据对模型进行微调。

Self-training on a broad distribution of pseudolabeled data

通过在每次自训练迭代中向原始标记数据集L中添加整个U伪标记示例集,鼓励从伪标记数据的“自然”广泛分布中学习在每次迭代t >1时,我们也用ft重新注释原始未标记数据池U中的所有示例,因为我们预期ft优于ft−1

GPU资源释放

摘要

问题描述:起服务时没有占用gpu资源,但是程序执行一次后存在线程占用gpu显存的问题

解决方案一:手动释放gpu资源(未解决)

torch.cuda.empty_cache()

解决方案二:升高scikit-learn版本,以为是版本较低设置n_jobs造成的,但应该不是(未解决)

解决方案三:不确定是否为异步程序造成,修改异步程序,异步从方案一修改到方案二(未解决)

python异步执行

异步方案一:装饰器

from threading import Thread

def async(f):
    def wrapper(*args, **kwargs):
        thr = Thread(target=f, args=args, kwargs=kwargs)
        thr.start()
    return wrapper

@async   
def restart_fun():  # 需要异步执行的方法
    pass

异步方案二:线程池

from concurrent.futures import ThreadPoolExecutor

thread_pool = ThreadPoolExecutor(2)

def exception_callback(fur):
    if fur.exception() != None:  # 若线程正常退出,返回None
        logging.error(fur.result())  # 判断是否存在异常,存在则打印返回的值

def wait_f():
    fur = thread_pool.submit(restart_fun,)  # restart_fun为需要异步执行的方法
    fur.add_done_callback(exception_callback)

wait_f() 

方案一和方案二是启了一个子进程,所以会显存会释放不掉

方案三是方案二的改进版本:使用os.system启了一个进程。bingo

import os
from concurrent.futures import ThreadPoolExecutor

thread_pool = ThreadPoolExecutor(2)

def exception_callback(fur):
    if fur.exception() != None:  # 若线程正常退出,返回None
        logging.error(fur.result())  # 判断是否存在异常,存在则打印返回的值

def restart_fun(a, b):
    os.system("python xxx.py %s %s" % (a, b))

def wait_f(a, b):
    fur = thread_pool.submit(restart_fun, a, b)
    fur.add_done_callback(exception_callback)

wait_f(a, b) 

# 如果有参数,一下为xxx.py代码文件
# ......
if __name__ == "__main__":
    import sys
    a = sys.argv[1]
    b = sys.argv[2]
    fun(a, b)

方案三在进程结束时会释放gpu资源,但在执行过程中会遇到一个问题,import numpy要在import torch之前,否则会报一下错误。

Error: mkl-service + Intel(R) MKL: MKL_THREADING_LAYER=INTEL is incompatible with libgomp-7c85b1e2.so.1 library.
Try to import numpy first or set the threading layer accordingly. Set MKL_SERVICE_FORCE_INTEL to force it.

使用的查看gpu和进程的linux命令

nvidia-smi
fuser -v /dev/nvidia*
ps -ef | grep 端口号