Files

57 lines
2.0 KiB
C++

#include "lattice_rerank.h"
#include "../neural/rescore_worker.h"
#include <optional>
#include <vector>
namespace quanpin
{
LatticeReranker make_neural_reranker(const neural::SentenceModel *model, const std::string &context,
const neural::RerankOptions &options)
{
if (model == nullptr)
{
return {};
}
// 在这里就把前文裁到模型真正会看的那几十个字:后台重排的结果表以「前文 + 候选句」为键,
// 拿没裁过的整段历史当键的话,每上屏一个字键就变了,缓存永远打不中。
const std::string trimmed = neural::last_characters(context, options.context_chars);
return [model, context = trimmed, options](std::vector<LatticePath> &paths) -> bool {
if (paths.size() < 2)
{
return false;
}
std::vector<std::string> sentences;
std::vector<double> scores;
sentences.reserve(paths.size());
scores.reserve(paths.size());
for (const LatticePath &path : paths)
{
sentences.push_back(path.sentence);
scores.push_back(path.log_prob);
}
// 不在这里打分:交给后台线程,第一次必然落空,按词格的静态顺序先出候选。线程算完会叫
// 醒会话重查一次,那一次才在结果表里拿到顺序。
const std::optional<std::vector<std::size_t>> order =
neural::RescoreWorker::instance().order_for(*model, context, sentences, scores, options);
if (!order || order->size() != paths.size())
{
return false; // 还没算出来,或者模型自己弃权了:词格的顺序原样留着
}
std::vector<LatticePath> reordered;
reordered.reserve(paths.size());
for (std::size_t index : *order)
{
reordered.push_back(paths[index]);
}
paths = std::move(reordered);
return true;
};
}
} // namespace quanpin