[fairseq] generate.py

[TOC]

generate.py

  • args.dataargs.gen_subset的区别?
task = tasks.setup_task(args)
task.load_dataset(args.gen_subset)
print('| {} {} {} examples'.format(args.data, args.gen_subset, len(task.dataset(args.gen_subset))))
  • 原来输入的path可以用:隔开可以完成ensemble,然后后面就是各自的model进行各种操作
# Load ensemble
print('| loading model(s) from {}'.format(args.path))
models, _model_args = utils.load_ensemble_for_inference(
    args.path.split(':'), task, model_arg_overrides=eval(args.model_overrides),
)
  • 需要ensemble的模型都有各自的操作。
# Optimize ensemble for generation
for model in models:
    model.make_generation_fast_(
        beamable_mm_beam_size=None if args.no_beamable_mm else args.beam,
        need_attn=args.print_alignment,
    )
    if args.fp16:
        model.half()
    if use_cuda:
        model.cuda()

replace_unk的原理

  • 可以指定一个字典加载
align_dict = utils.load_align_dict(args.replace_unk)
  • 函数里面,replace_unk在命令行可以传入一个参数,是一个字典,每行使用空格隔开表示源单词和要替换的目标单词。
  • 如果没有传入参数的话那么字典是空的,但是是使用源语言中的word来替代unk
def load_align_dict(replace_unk):
    if replace_unk is None:
        align_dict = None
    elif isinstance(replace_unk, str):
        # Load alignment dictionary for unknown word replacement if it was passed as an argument.
        align_dict = {}
        with open(replace_unk, 'r') as f:
            for line in f:
                cols = line.split()
                align_dict[cols[0]] = cols[1]
    else:
        # No alignment dictionary provided but we still want to perform unknown word replacement by copying the
        # original source word.
        align_dict = {}
    return align_dict
  • itrsample的关系
  • 可以通过.get_original_text将id转换成raw word
src_str = task.dataset(args.gen_subset).src.get_original_text(sample_id)
target_str = task.dataset(args.gen_subset).tgt.get_original_text(sample_id)
  • 现在的疑问src_dict.string在哪里定义的。
src_str = src_dict.string(src_tokens, args.remove_bpe)
  • 控制是否输出 sample_idsrc_str是通过args.quiet来控制的
if not args.quiet:
    if src_dict is not None:
        print('S-{}\t{}'.format(sample_id, src_str))
    if has_target:
        print('T-{}\t{}'.format(sample_id, target_str))
  • hypos = task.inference_step(generator, models, sample, prefix_tokens)这一句是干啥的
  • args.prefix_size,是将target的这么长的部分直接给generator看到,默认是0。
prefix_tokens = None
if args.prefix_size > 0:
    prefix_tokens = sample['target'][:, :args.prefix_size]

gen_timer.start()
hypos = task.inference_step(generator, models, sample, prefix_tokens)
  • 看到原来hypo是推断的结果,里面还存放者每个位置的的得分。
if not args.quiet:
    print('H-{}\t{}\t{}'.format(sample_id, hypo['score'], hypo_str))
    print('P-{}\t{}'.format(
        sample_id,
        ' '.join(map(
            lambda x: '{:.4f}'.format(x),
            hypo['positional_scores'].tolist(),
        ))
    ))
  • hyposdecoder得到的数据,args.nbest是推断的个数,即decoder句子的个数。
for i, hypo in enumerate(hypos[i][:min(len(hypos), args.nbest)]):
  • utils.post_process_prediction对已经decode出来的数据进行后处理。
# Process top predictions
for i, hypo in enumerate(hypos[i][:min(len(hypos), args.nbest)]):
    hypo_tokens, hypo_str, alignment = utils.post_process_prediction(
        hypo_tokens=hypo['tokens'].int().cpu(),
        src_str=src_str,
        alignment=hypo['alignment'].int().cpu() if hypo['alignment'] is not None else None,
        align_dict=align_dict,
        tgt_dict=tgt_dict,
        remove_bpe=args.remove_bpe,
    )
  • 可以看到generator里面就直接将score得到了因此不用再设置score
print('| Translated {} sentences ({} tokens) in {:.1f}s ({:.2f} sentences/s, {:.2f} tokens/s)'.format(
    num_sentences, gen_timer.n, gen_timer.sum, num_sentences / gen_timer.sum, 1. / gen_timer.avg))
if has_target:
    print('| Generate {} with beam={}: {}'.format(args.gen_subset, args.beam, scorer.result_string()))
  • args.print_alignment 可以看到每一个target string中的每一个单词对应source string中概率最大的那个单词。
if args.print_alignment:
    print('A-{}\t{}'.format(
        sample_id,
        ' '.join(map(lambda x: str(utils.item(x)), alignment))
    ))
  • 现在好奇是怎么算分数的即score的计算方法是什么

其他部分

  • build_progress_bar的时候可以选择args.log_format==tqdm
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,928评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,192评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,468评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,186评论 1 286
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,295评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,374评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,403评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,186评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,610评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,906评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,075评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,755评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,393评论 3 320
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,079评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,313评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,934评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,963评论 2 351