unilm 在解码时,是否有简单的方法输出每个源句子的前k个句子?

baubqpgj  于 5个月前  发布在  其他
关注(0)|答案(6)|浏览(67)

你好,
感谢提供的代码和帮助!我想知道在解码时是否有办法输出每个输入句子的多个(例如k)输出句子?
非常感谢!

0ejtzxu1

0ejtzxu11#

感谢您报告此问题。@addf400正在调查此事。

7vhp5slm

7vhp5slm2#

你好@donglixp,
我使用了这些超参数,但输出了一个空文件(我已经生成了分数跟踪文件):

python s2s-ft/gen_seq_from_trace.py \
--bert_model bert-base-cased --length_penalty 0 \
--tokenizer_name unilm1.2-base-uncased \
--is_roberta \
--do_lower_case \
--input ${OUTPUT_FILE}

经过一点调试,我发现这个for循环都被 if 判断跳过了。然而,我不太确定这是怎么发生的。

if fid <= last_frame_id and scores[fid][i] >= 0:
    # skip paddings
    print("skip paddings")
    continue

你好@yuchenlin,
我已经为此创建了一个PR( #94 )
你需要将运行命令更改为:

python gen_seq_from_trace.py \
--model_type unilm --length_penalty 0 \
--tokenizer_name unilm1.2-base-uncased \
--input ${OUTPUT_FILE}
qkf9rpyu

qkf9rpyu3#

感谢!@addf400 和 @donglixp,现在它可以工作了!我也尝试通过以下修改来保存前k个句子。然而,似乎存在一些小错误。

def get_best_sequence(.....):
    max_score = -math.inf
    frame_id = -1
    pos_in_frame = -1
    searched_results = []
    frame_set = set()

    for fid in range(last_frame_id + 1):
        for i, wid in enumerate(wids_list[fid]):
             ..... 
                if s > max_score:
                    # if (frame_id != -1) and min_len and (fid+1 < min_len):
                    #     continue
                    max_score = s
                    frame_id = fid
                    pos_in_frame = i
                # To ignore duplicate generations.
                if (frame_id, pos_in_frame) not in frame_set:
                    frame_set.add((frame_id, pos_in_frame))
                    searched_results.append((s, frame_id, pos_in_frame))

    searched_results.sort(key=lambda x:x[0], reverse=True)
    searched_results = searched_results[:top_k]

    seqs = []

    for s, frame_id, pos_in_frame in searched_results:
        if frame_id == -1:
            seq = []
        else:
            seq = [wids_list[frame_id][pos_in_frame]]
            for fid in range(frame_id, 0, -1):
                pos_in_frame = ptrs[fid][pos_in_frame]
                seq.append(wids_list[fid - 1][pos_in_frame])
            seq.reverse()
        seqs.append(seq)
    return seqs

以及

for s in samples:
        word_ids_list = get_best_sequence(s, eos_id, pad_id, alpha=args.alpha,
                                     length_penalty=args.length_penalty, expect=args.expect,
                                     min_len=args.min_len, top_k=args.top_k)

        for word_ids in word_ids_list:
            ......
            results.append(output_text)
        results.append("----")

最后,我发现大多数示例只有一个来自trace.pickle的唯一生成。只有少数几个可以有多个不同的生成。这是预期的吗,还是我犯了一些错误?
非常感谢你们的帮助!

wn9m85ua

wn9m85ua4#

参数 --need_score_traces 可以添加到 python decode_seq2seq.py 中,用于保存 beam search 的中间结果。接着,s2s-ft/gen_seq_from_trace.py 可以重新加载已保存的 beam search 结果。在 https://github.com/microsoft/unilm/blob/master/s2s-ft/gen_seq_from_trace.py#L63 中,我们使用了 if s > max_score: 来保存最佳的 beam search 结果。相反,我们可以维护一个排序列表来保存前 K 个结果(L67:frame_id 和 pos_in_frame)。然后 L69-L76 可以将它们恢复为 tokens。

u91tlkcl

u91tlkcl5#

非常感谢您的建议!我会尝试一下的!

qyzbxkaa

qyzbxkaa6#

你好,@donglixp,
我使用了这些超参数,但输出了一个空文件(我已经生成了分数跟踪文件):

python s2s-ft/gen_seq_from_trace.py \
--bert_model bert-base-cased --length_penalty 0 \
--tokenizer_name unilm1.2-base-uncased \
--is_roberta \
--do_lower_case \
--input ${OUTPUT_FILE}

经过一点调试,我发现这个 for 循环都被 if 判断跳过了。然而,我不太确定这是怎么发生的。

if fid <= last_frame_id and scores[fid][i] >= 0:
    # skip paddings
    print("skip paddings")
    continue

相关问题