improve lexical warmup and standardize stopword pipeline

This commit is contained in:
2026-02-17 14:49:47 +08:00
parent 246eb7a7e2
commit 94eceaed96
14 changed files with 4840 additions and 330 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2020 Gene Diaz
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -0,0 +1,15 @@
# stopwords sources for story-summary
- Dataset: `stopwords-iso` (npm package, version 1.1.0)
- Repository: https://github.com/stopwords-iso/stopwords-iso
- License: MIT
- Snapshot date: 2026-02-16
- Languages used: `zh`, `ja`, `en`
- Local snapshot files:
- `stopwords-iso.zh.txt`
- `stopwords-iso.ja.txt`
- `stopwords-iso.en.txt`
Generation note:
- `modules/story-summary/vector/utils/stopwords-base.js` is generated from these snapshot files.
- Keep `stopwords-patch.js` for tiny domain overrides only.

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,134 @@
あそこ
あっ
あの
あのかた
あの人
あり
あります
ある
あれ
いう
います
いる
うち
および
おり
おります
かつて
から
ここ
こちら
こと
この
これ
これら
さらに
しかし
する
せる
そこ
そして
その
その他
その後
それ
それぞれ
それで
ただし
たち
ため
たり
だっ
だれ
でき
できる
です
では
でも
という
といった
とき
ところ
として
とともに
とも
と共に
どこ
どの
ない
なお
なかっ
ながら
なく
なっ
など
なに
なら
なり
なる
なん
において
における
について
にて
によって
により
による
に対して
に対する
に関する
ので
のみ
ほか
ほとんど
ほど
ます
また
または
まで
もの
ものの
よう
より
られ
られる
れる
及び
彼女
我々
特に
私達
貴方
貴方方

View File

@@ -0,0 +1,794 @@
一个
一些
一何
一切
一则
一方面
一旦
一来
一样
一种
一般
一转眼
万一
上下
不仅
不但
不光
不单
不只
不外乎
不如
不妨
不尽
不尽然
不得
不怕
不惟
不成
不拘
不料
不是
不比
不然
不特
不独
不管
不至于
不若
不论
不过
不问
与其
与其说
与否
与此同时
且不说
且说
两者
个别
为了
为什么
为何
为止
为此
为着
乃至
乃至于
之一
之所以
之类
乌乎
也好
也罢
二来
于是
于是乎
云云
云尔
人们
人家
什么
什么样
介于
仍旧
从此
从而
他人
他们
他们们
以上
以为
以便
以免
以及
以故
以期
以来
以至
以至于
以致
任何
任凭
似的
但凡
但是
何以
何况
何处
何时
余外
作为
你们
使
使得
例如
依据
依照
便于
俺们
倘使
倘或
倘然
倘若
借傥然
假使
假如
假若
先不先
光是
全体
全部
关于
关于具体地说
其一
其中
其二
其他
其余
其它
其次
具体地说
具体说来
兼之
再其次
再则
再有
再者
再者说
再说
况且
几时
凡是
凭借
出于
出来
分别
则甚
别人
别处
别是
别的
别管
别说
前后
前此
前者
加之
加以
即令
即使
即便
即如
即或
即若
又及
及其
及至
反之
反而
反过来
反过来说
受到
另一方面
另外
另悉
只当
只怕
只是
只有
只消
只要
只限
叮咚
可以
可是
可见
各个
各位
各种
各自
同时
后者
向使
向着
否则
吧哒
呜呼
呵呵
呼哧
咱们
哈哈
哎呀
哎哟
哪个
哪些
哪儿
哪天
哪年
哪怕
哪样
哪边
哪里
哼唷
唯有
啪达
啷当
喔唷
嗡嗡
嘎登
嘿嘿
因为
因了
因此
因着
因而
固然
在下
在于
基于
处在
多么
多少
大家
她们
如上
如上所述
如下
如何
如其
如同
如是
如果
如此
如若
始而
孰料
孰知
宁可
宁愿
宁肯
它们
对于
对待
对方
对比
尔后
尔尔
尚且
就是
就是了
就是说
就算
就要
尽管
尽管如此
岂但
已矣
巴巴
并且
庶乎
庶几
开外
开始
归齐
当地
当然
当着
彼时
彼此
得了
怎么
怎么办
怎么样
怎奈
怎样
总之
总的来看
总的来说
总的说来
总而言之
恰恰相反
惟其
慢说
我们
或则
或是
或曰
或者
截至
所以
所在
所幸
所有
才能
打从
抑或
按照
换句话说
换言之
据此
接着
故此
故而
旁人
无宁
无论
既往
既是
既然
时候
是以
是的
替代
有些
有关
有及
有时
有的
朝着
本人
本地
本着
本身
来着
来自
来说
极了
果然
果真
某个
某些
某某
根据
正值
正如
正巧
正是
此地
此处
此外
此时
此次
此间
毋宁
每当
比及
比如
比方
没奈何
沿
沿着
漫说
然则
然后
然而
照着
犹且
犹自
甚且
甚么
甚或
甚而
甚至
甚至于
用来
由于
由是
由此
由此可见
的确
的话
直到
相对而言
省得
眨眼
着呢
矣乎
矣哉
竟而
等到
等等
简言之
类如
紧接着
纵令
纵使
纵然
经过
结果
继之
继后
继而
综上所述
罢了
而且
而况
而后
而外
而已
而是
而言
能否
自个儿
自从
自各儿
自后
自家
自己
自打
自身
至于
至今
至若
般的
若夫
若是
若果
若非
莫不然
莫如
莫若
虽则
虽然
虽说
要不
要不是
要不然
要么
要是
譬喻
譬如
许多
设使
设或
设若
诚如
诚然
说来
诸位
诸如
谁人
谁料
谁知
贼死
赖以
起见
趁着
越是
较之
还是
还有
还要
这一来
这个
这么
这么些
这么样
这么点儿
这些
这会儿
这儿
这就是说
这时
这样
这次
这般
这边
这里
进而
连同
逐步
通过
遵循
遵照
那个
那么
那么些
那么样
那些
那会儿
那儿
那时
那样
那般
那边
那里
鄙人
鉴于
针对
除了
除外
除开
除此之外
除非
随后
随时
随着
难道说
非但
非徒
非特
非独
顺着
首先
︿

View File

@@ -0,0 +1,9 @@
// Small domain-level tuning surface.
// Keep this file tiny: add/remove only words that are repeatedly noisy in real logs.
// Extra stopwords on top of BASE_STOP_WORDS.
export const DOMAIN_STOP_WORDS = [];
// High-value words that must never be filtered as stopwords.
// Default to empty for plugin-wide deployment; entity names are already protected dynamically.
export const KEEP_WORDS = [];

View File

@@ -18,6 +18,8 @@
import { extensionFolderPath } from '../../../../core/constants.js';
import { xbLog } from '../../../../core/debug-core.js';
import { BASE_STOP_WORDS } from './stopwords-base.js';
import { DOMAIN_STOP_WORDS, KEEP_WORDS } from './stopwords-patch.js';
const MODULE_ID = 'tokenizer';
@@ -61,44 +63,30 @@ let entityList = [];
/** @type {Set<string>} 已注入结巴的实体(避免重复 add_word */
let injectedEntities = new Set();
let entityKeepSet = new Set();
// ═══════════════════════════════════════════════════════════════════════════
// 停用词
// ═══════════════════════════════════════════════════════════════════════════
const STOP_WORDS = new Set([
// 中文高频虚词
'的', '了', '在', '是', '我', '有', '和', '就', '不', '人',
'都', '一', '一个', '上', '也', '很', '到', '说', '要', '去',
'你', '会', '着', '没有', '看', '好', '自己', '这', '他', '她',
'它', '吗', '什么', '那', '里', '来', '吧', '呢', '啊', '哦',
'嗯', '呀', '哈', '嘿', '喂', '哎', '唉', '哇', '呃', '嘛',
'把', '被', '让', '给', '从', '', '对', '跟', '比', '但',
'而', '或', '如果', '因为', '所以', '虽然', '但是', '然后',
'可以', '这样', '那样', '怎么', '为什么', '什么样', '哪里',
'时候', '现在', '已经', '还是', '只是', '可能', '应该', '知道',
'觉得', '开始', '一下', '一些', '这个', '那个', '他们', '我们',
'你们', '自己', '起来', '出来', '进去', '回来', '过来', '下去',
// 日语常见虚词≥2字匹配 TinySegmenter 产出粒度)
'です', 'ます', 'した', 'して', 'する', 'ない', 'いる', 'ある',
'なる', 'れる', 'られ', 'られる',
'この', 'その', 'あの', 'どの', 'ここ', 'そこ', 'あそこ',
'これ', 'それ', 'あれ', 'どれ',
'ても', 'から', 'まで', 'ので', 'のに', 'けど', 'だけ',
'もう', 'まだ', 'とても', 'ちょっと', 'やっぱり',
// 英文常见停用词
'the', 'a', 'an', 'is', 'are', 'was', 'were', 'be', 'been',
'being', 'have', 'has', 'had', 'do', 'does', 'did', 'will',
'would', 'could', 'should', 'may', 'might', 'can', 'shall',
'and', 'but', 'or', 'not', 'no', 'nor', 'so', 'yet',
'in', 'on', 'at', 'to', 'for', 'of', 'with', 'by', 'from',
'it', 'its', 'he', 'she', 'his', 'her', 'they', 'them',
'this', 'that', 'these', 'those', 'i', 'me', 'my', 'you', 'your',
'we', 'our', 'if', 'then', 'than', 'when', 'what', 'which',
'who', 'how', 'where', 'there', 'here', 'all', 'each', 'every',
'both', 'few', 'more', 'most', 'other', 'some', 'such',
'only', 'own', 'same', 'just', 'very', 'also', 'about',
]);
const STATIC_KEEP_WORDS = new Set((KEEP_WORDS || [])
.map(w => String(w || '').trim().toLowerCase())
.filter(Boolean));
// Standard source only: stopwords-iso snapshot + small domain patch.
const EFFECTIVE_STOP_WORDS = new Set(
[...BASE_STOP_WORDS, ...DOMAIN_STOP_WORDS]
.map(w => String(w || '').trim().toLowerCase())
.filter(Boolean),
);
function shouldKeepTokenByWhitelist(token) {
const t = String(token || '').trim().toLowerCase();
if (!t) return false;
if (STATIC_KEEP_WORDS.has(t)) return true;
if (entityKeepSet.has(t)) return true;
return false;
}
// ═══════════════════════════════════════════════════════════════════════════
// Unicode 分类
@@ -571,6 +559,7 @@ export function getState() {
export function injectEntities(lexicon, displayMap) {
if (!lexicon?.size) {
entityList = [];
entityKeepSet = new Set();
return;
}
@@ -586,6 +575,7 @@ export function injectEntities(lexicon, displayMap) {
// 按长度降序(最长匹配优先)
entities.sort((a, b) => b.length - a.length);
entityList = entities;
entityKeepSet = new Set(entities.map(e => String(e || '').trim().toLowerCase()).filter(Boolean));
// 如果结巴已就绪,注入自定义词
if (wasmState === WasmState.READY && jiebaAddWord) {
@@ -656,7 +646,7 @@ export function tokenize(text) {
if (!cleaned) continue;
if (cleaned.length < 2) continue;
if (STOP_WORDS.has(cleaned)) continue;
if (EFFECTIVE_STOP_WORDS.has(cleaned) && !shouldKeepTokenByWhitelist(cleaned)) continue;
if (seen.has(cleaned)) continue;
// 过滤纯标点/特殊字符
@@ -728,7 +718,7 @@ export function tokenizeForIndex(text) {
.map(t => t.trim().toLowerCase())
.filter(t => {
if (!t || t.length < 2) return false;
if (STOP_WORDS.has(t)) return false;
if (EFFECTIVE_STOP_WORDS.has(t) && !shouldKeepTokenByWhitelist(t)) return false;
if (/^[\s\x00-\x1F\p{P}\p{S}]+$/u.test(t)) return false;
return true;
});
@@ -744,6 +734,7 @@ export function tokenizeForIndex(text) {
*/
export function reset() {
entityList = [];
entityKeepSet = new Set();
injectedEntities.clear();
// 不重置 WASM 状态(避免重复加载)
}