- 新增 engine/neural:移植 chinese-ime-lm 的字符级 Transformer 推理,在词格解出的最多 12 条 n-best 里重排挑选整句,desktop / keyboard 两档模型各出一条首选,后台 worker 异步打分 - 词格支持 n-best 输出与重排(quanpin/lattice_rerank),全拼、双拼共用 - 新增 SentenceAssociationOptions,经 QueryRequest 传给各 provider;四个来源默认全关 - 资源契约登记两个 safetensors 与 NOTICE;模型二进制不进仓库,由 scripts/fetch-neural-model.ps1 按 neural-model/lock.json 下载并校验 SHA256 - 新增 neural_sentence 测试
57 lines
2.0 KiB
C++
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
|