Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Latest commit

 

History

History
 
 

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 

README.md

FasterGeneration

FasterGeneration是PaddleNLP v2.2版本加入的文本生成高性能加速功能,其支持GPT、OPT、BART、UnifiedTransformer等多种NLP生成类预训练模型,并且支持多种解码策略,可以用于机器翻译、文本续写、文本摘要、对话生成等多种NLG任务的GPU场景预测加速。

功能底层依托于NV FasterTransformer,该库针对标准的Transformer和GPT模型、beam search和sampling解码策略进行了性能优化。PaddleNLP FasterGeneration在其之上进行了扩展,实现了更多模型和生成策略的优化支持,并将功能入口封装于model.generate函数。功能的开启和关闭通过传入use_faster参数进行控制(默认为关闭状态)。通过调用generate函数,用户可以简单的使用模型高性能推理功能。下图展示了FasterGeneration的启动流程:

Featrues

  • 全面支持生成式预训练模型。包括GPT、OPT、CodeGen、GPTJ、BART、mBART、UnifiedTransformer和UNIMO-text。
  • 支持大多数主流解码策略。包括Beam Search、Sampling、Greedy Search。以及Diverse Sibling Search、Length Penalty等子策略。
  • 解码速度快。最高可达非加速版generate函数的18倍并支持FP16混合精度计算
  • 易用性强。功能的入口为model.generate,与非加速版生成api的使用方法相同,当满足加速条件时使用jit即时编译高性能算子并用于生成,不满足则自动切换回非加速版生成api。
  • GPT、UnifiedTransformer和UNIMO-text模型支持高性能并行推理,在具备MPI和NCCL的环境中一行代码即可开启使用,允许通过多张小显存容量的 GPU 使用百亿大模型,预测速度较单卡也进一步提升。百亿模型四卡并行高性能推理速度达单卡高性能推理速度2+倍。

Inference Model Support

下表为PaddleNLP FasterGeneration对预训练模型和解码策略的支持情况(GPU)。

Model Name GPT2 OPT CodeGen GPTJ BART mBART UnifiedTransformer
Model Structure Decoder Decoder Decoder Decoder Encoder-Decoder Encoder-Decoder Prefix-LM
Beam Search
Top-K Sampling
Top-P Sampling
Diverse Sibling Search
Forced Decoding
Length Penalty
Temperature
Repetition Penalty

Performence

FasterGeneration的高性能解码相比原版generate方法加速明显,并且与竞品相比有也有极大的速度优势。以下为性能对比图:

  • batch_size = 4, out_seq_len = 32
  • Device: Tesla V100-SXM2-16GB
  • CUDA version 11.2
  • cudnn version 8
  • torch version 1.10.0+cu113
  • transformers version 4.12.5

BART (bart-base, batch_size=4, max_length=32)

GPT (gpt2, batch_size=4, max_length=32)

OPT (opt, batch_size=4, max_length=32)

CodeGen:

  • 环境和超参
    • Platform: Tesla V100-SXM2-32GB
    • CUDA 10.1
    • CUDNN 7.6.5
    • PaddlePaddle-gpu 2.3.1.post101
    • transformers==4.21.1
    • torch==1.11.0
    • Batch Size: 1
    • Input Length: 60
    • Output Length: 20

  • Platform: A100-40G

Pegasus

  • 环境和超参
    • Platform: Tesla V100-SXM2-32GB
    • CUDA 10.1
    • CUDNN 7.6.5
    • PaddlePaddle-gpu 2.3.2.post101
    • transformers==4.21.1
    • torch==1.11.0
    • Batch Size: 4
    • Input Length: 60
    • Output Length: 20
    • Decode_strategy: beam search
    • num_beams: 4

更详细的性能数据请参见这里

Quick Start

高性能推理

为体现FasterGeneration的易用性,我们在samples文件夹中内置了几个典型任务示例,下面以基于GPT模型的中文文本续写任务为例:

python samples/gpt_sample.py

如果是第一次执行,PaddleNLP会启动即时编译(JIT Compile)自动编译高性能解码算子。

...
2021-11-17 13:42:56,771 - INFO - execute command: cd /10.2/hub/PaddleNLP/paddlenlp/ops/extenstions && /usr/local/bin/python FasterTransformer_setup.py build
INFO:utils.cpp_extension:execute command: cd /10.2/hub/PaddleNLP/paddlenlp/ops/extenstions && /usr/local/bin/python FasterTransformer_setup.py build
grep: warning: GREP_OPTIONS is deprecated; please use an alias or script
running build
running build_ext
-- The C compiler identification is GNU 8.2.0
-- The CXX compiler identification is GNU 8.2.0
-- The CUDA compiler identification is NVIDIA 10.2.89
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr
...

编译过程通常会花费几分钟的时间编译只会进行一次,之后再次使用高性能解码就不需要重新编译了,编译完成后会继续运行,可以看到生成的结果如下:

Model input: 花间一壶酒,独酌无相亲。举杯邀明月,
Result: 对影成三人。

打开示例代码 samples/gpt_sample.py ,我们可以看到如下代码:

...
model = GPTLMHeadModel.from_pretrained(model_name)
...
outputs, _ = model.generate(
    input_ids=inputs_ids, max_length=10, decode_strategy='greedy_search',
    use_faster=True)
...

可以看到,FasterGeneration的使用方法与 model.generate() 相同,只需传入输入tensor和解码相关参数即可,使用非常简便。如果要使用非加速版的 model.generate() 方法,只需传入 use_faster=False 即可,示例如下:

...
outputs, _ = model.generate(
    input_ids=inputs_ids, max_length=10, decode_strategy='greedy_search', use_faster=False)
...

NOTE: 需要注意的是,如果传入 model.generate() 的参数不满足高性能版本的要求。程序会做出提示并自动切换为非加速版本,例如我们在上面的例子中传入 min_length=1 ,会得到如下提示:

...
[2021-11-17 14:21:06,132] [ WARNING] - 'min_length != 0' is not supported yet in the faster version
[2021-11-17 14:21:06,132] [ WARNING] - FasterGeneration is not available, and the original version would be used instead.
...

关于该函数的详细介绍可以参考API文档generateAistudio教程文本生成任务实战:如何使用PaddleNLP实现各种解码策略samples文件夹中的其他示例的使用方法相同。

并行推理

FasterGeneration对GPT、UnifiedTransformer和UNIMO-text模型在高性能推理的基础上还实现了模型并行功能,其中GPT支持Tensor Parallel和Layer Parallel(Pipeline Parallel)两种并行策略的组合,UnifiedTransformer和UNIMO-text支持Tensor Parallel。关于这两种并行策略的详细介绍请参考Megatron论文

并行推理当前依赖MPI(MPICHOpenMPI均可)和NCCL,如需使用还请先安装依赖。在使用时,相比上面的单卡高性能加速代码中也只增加了from_pretrained创建加载模型之前加上enable_ft_para()一行。

GPT 并行推理

GPT高性能并行推理的完整使用示例已在gpt_mp_sample.py中提供,按照如下方式启动即可:

mpirun -n 4 python gpt_mp_sample.py --tensor_para_size 4 --layer_para_size 1

其中-n 4指明使用的进程和GPU数,tensor_para_sizetensor_para_size分别指明Tensor Parallel和Layer Parallel各自使用的GPU数,均设置为1则进行单卡预测。另外加上--use_fp16以使用FP16,加上--profile可以进行相应设置的性能测试。其他生成相关的参数设置释义如下:

  • model_name 指定使用的GPT模型,默认为gpt-cpm-larg-cn
  • max_length 指定生成的最大长度,默认为50。
  • topk 用于Top-K采样策略,采样时将只从概率最高K个token中采样,默认为1,即greedy search。
  • topp 用于Top-P采样策略,采样时将只从概率最高且累加概率不超过该值的token中采样,默认为1.0。
  • temperature 用于调整预测概率分布,默认为1.0,即保持模型原有的预测概率。

使用gpt-cpm-larg-cn(2.6B)和默认设置,在V100上4卡Tensor Parallel较单卡高性能预测速度提升约40%。

PLATO-XL 并行推理

PLATO-XL百亿对话预训练模型(11B UnifiedTransformer模型)高性能并行推理的完整使用示例已在plato_xl_sample.py中提供(当前只支持Tensor Parallel),按照如下方式启动即可:

mpirun -n 4 python plato_xl_sample.py

参数释义基本同上。在V100上4卡Tensor Parallel高性能预测为单卡高性能预测速度的2倍。

Generate Examples

除了以上示例之外,PaddleNLP的examples中大多使用了model.generate的示例都可以通过调整到合适的参数使用高性能推理。具体如下:

下面我们以基于 Unified Transformer 的任务型对话为例展示一下FasterGeneration的加速效果:

打开以上链接中Unified Transformer对应的example,找到README中对应预测的脚本。稍作修改如下:

export CUDA_VISIBLE_DEVICES=0
    python infer.py \
    --model_name_or_path=unified_transformer-12L-cn-luge \
    --output_path=./predict.txt \
    --logging_steps=10 \
    --seed=2021 \
    --max_seq_len=512 \
    --max_knowledge_len=256 \
    --batch_size=4 \
    --min_dec_len=1 \
    --max_dec_len=64 \
    --num_return_sequences=1 \
    --decode_strategy=sampling \
    --top_k=5 \
    --faster
    --device=gpu

由于这里只是展示性能,我们直接在 model_name_or_path 填入PaddleNLP预训练模型名称 unified_transformer-12L-cn-luge

可以看到,由于该任务为对话任务,我们为了防止模型生成过多安全回复(如:哈哈哈、不错等),保证生成结果具有更多的随机性,我们选择TopK-sampling作为解码策略,并让k=5。

打开 infer.py ,可以看到我们传入的脚本参数大多都提供给了 model.generate() 方法:

output = model.generate(
        input_ids=input_ids,
        token_type_ids=token_type_ids,
        position_ids=position_ids,
        attention_mask=attention_mask,
        seq_len=seq_len,
        max_length=args.max_dec_len,
        min_length=args.min_dec_len,
        decode_strategy=args.decode_strategy,
        temperature=args.temperature,
        top_k=args.top_k,
        top_p=args.top_p,
        num_beams=args.num_beams,
        length_penalty=args.length_penalty,
        early_stopping=args.early_stopping,
        num_return_sequences=args.num_return_sequences,
        use_fp16_decoding=args.use_fp16_decoding,
        use_faster=args.faster)

运行脚本,输出结果如下:

step 10 - 1.695s/step
step 20 - 1.432s/step
step 30 - 1.435s/step

可以看到,非加速版 generate() 方法的预测速度为每个step耗时1.5秒左右。

下面我们在启动脚本中传入 --faster 参数,该参数会向 generate() 方法传入 use_faster=True ,启动加速模式。同时我们需要设置 --min_dec_len=0 ,因为FasterGeneration当前还不支持该参数。新的脚本启动参数如下:

export CUDA_VISIBLE_DEVICES=0
    python infer.py \
    --model_name_or_path=unified_transformer-12L-cn-luge \
    --output_path=./predict.txt \
    --logging_steps=10 \
    --seed=2021 \
    --max_seq_len=512 \
    --max_knowledge_len=256 \
    --batch_size=4 \
    --min_dec_len=0 \
    --max_dec_len=64 \
    --num_return_sequences=1 \
    --decode_strategy=sampling \
    --top_k=5 \
    --device=gpu \
    --faster

再次运行脚本,输出结果如下(由于我们已经编译过高性能算子,所以这里不会重新编译):

[2021-11-23 13:38:09,200] [   DEBUG] - skipping 'FasterTransformer' extension (up-to-date) build
step 10 - 0.250s/step
step 20 - 0.156s/step
step 30 - 0.141s/step

可以看到,FasterGeneration的预测速度为每个step耗时0.15秒左右,相比非加速版提速超过9倍。