基于XiaothinkT6语言模型的文本相似度计算:轻量方案实现文本匹配与去重

在自然语言处理(NLP)领域,文本相似度计算是一项基础且高频的任务——无论是问答系统中匹配相似问题、内容平台实现文本去重,还是智能检索时筛选相关结果,都需要精准判断两段文本的语义关联程度。今天为大家介绍一款低门槛解决方案:基于Xiaothink框架与Xiaothink-T6-0.15B-ST模型,通过极少代码实现高效文本相似度计算,普通电脑无GPU也能流畅运行。

一、为什么选择Xiaothink的文本相似度方案?

Xiaothink框架专注于“端侧低算力AI”,其推出的文本相似度方案基于预训练的Xiaothink-T6-0.15B-ST模型(代码中MT='t6_standard'对应模型),相比传统方案有三大核心优势:

  1. 零额外训练成本:无需单独训练相似度模型或分类头,直接复用T6-0.15B-ST预训练模型的文本嵌入能力,节省数据标注与训练时间;
  2. 轻量高效:适配0.15B参数或0.08B参数的小模型,内存占用低(普通电脑8GB内存即可运行),无GPU也能快速生成文本向量;
  3. 即插即用:封装完整的预处理、嵌入提取、相似度计算流程,代码可直接复用,新手也能10分钟上手。

二、准备工作:安装与模型下载

1. 安装Xiaothink核心模块

首先通过pip安装依赖:

# 安装基础模块
pip install xiaothink

2. 下载Xiaothink-T6-0.15B-ST模型

方案核心依赖Xiaothink-T6-0.15B-ST模型(ST即“SingleTurn”,专为单文本嵌入、短文本匹配优化),该模型经过指令微调,文本语义编码能力更适配相似度任务。

  • 模型下载地址https://www.modelscope.cn/models/ericsjq/Xiaothink-T6-0.15B
  • 下载与存储步骤
    1. 访问上述ModelScope链接,进入模型详情页;
    2. 下载词汇表文件(需与代码中vocab_lx3.txt对应,建议直接命名为vocab_lx3.txt);
    3. 进入Xiaothink-T6-0.15B-ST文件夹,下载全部模型权重文件(ckpt格式);
    4. 将文件保存到本地目录,例如:
      • 模型权重路径:G:\大模型\models\ckpt_test_t6_standard_cloud_3epoch(与代码中ckpt_dir对应);
      • 词汇表路径:E:\小思框架\论文\ganskchat\vocab_lx3.txt(与代码中vocab对应)。

三、快速上手:4步实现文本相似度计算

下面基于提供的完整代码,演示如何加载模型、预处理文本、提取嵌入向量,并最终计算两段文本的相似度。

步骤1:导入核心模块

首先导入TensorFlow、NumPy及Xiaothink框架的模型加载模块(代码中xiaothink.llm.inference.test需替换为实际文件路径):

import tensorflow as tf
import numpy as np
from xiaothink.llm.inference.test import load  

步骤2:加载模型与词表

通过load函数加载T6-0.15B-ST模型权重与词汇表,同时定义模型关键参数(需与训练时保持一致,代码中已通过dic字典预设):

# 模型类型(对应Xiaothink-T6-0.15B-ST)
MT = 't6_standard'  

# 加载模型(m)与词表(d:包含char2idx和idx2char)
m, d = load(
    ckpt_dir=r'G:\大模型\models\ckpt_test_t6_standard_cloud_3epoch',  # 替换为你的模型权重路径
    vocab=r'E:\小思框架\论文\ganskchat\vocab.txt',  # 替换为你的词汇表路径
    model_type=MT,
    print_out=False
)
char2idx, idx2char = d[0], d[1]

# 模型关键参数(与训练时一致,不可修改)
dic = {
    't6_standard': [int(512), {'rnn_units': int(1100), 'n_layer': 1, 'embed_q': 0.4, 'router_units': 128,
                               'trans_layers': 33, 'dff_factor': 4, 'num_heads': 8,
                               'trans_window': 140,
                               'all_maxlen': 2048,
                               },
                    512],
}
seq_length = dic[MT][2]  # 序列长度(文本截断/填充的基准)

步骤3:理解核心功能函数

代码中已封装4个核心函数,无需修改即可直接调用,功能如下:

  • preprocess_text:文本预处理(将文本转为索引、按seq_length截断/填充);
  • build_embedding_extractor:构建嵌入提取子模型(跳过Input层,取第一个有效层输出文本嵌入);
  • get_text_embedding:生成文本向量(对嵌入结果做均值池化,得到单句向量);
  • calculate_similarity:计算余弦相似度(将结果归一化到0~1,值越近1表示文本越相似);
  • xsd:相似度判断函数(以0.65为阈值,返回两段文本是否“相似”)。

完整函数代码如下(直接复用,无需修改):

# --------------------------
# 2. 文本预处理(保持与训练逻辑对齐)
# --------------------------
def preprocess_text(text, char2idx, seq_length, pad_char='▩'):
    pad_idx = char2idx.get(pad_char, 0)
    tokens = [char2idx.get(c, pad_idx) for c in text]
    
    # 截断/填充
    if len(tokens) > seq_length:
        tokens = tokens[:seq_length]
    else:
        tokens += [pad_idx] * (seq_length - len(tokens))
    
    return tf.convert_to_tensor(tokens, dtype=tf.int32)[tf.newaxis, :]


# --------------------------
# 3. 构建嵌入提取模型:跳过Input层,取第一个非Input层
# --------------------------
def build_embedding_extractor(model):
    """
    跳过所有Input层,找到第一个非Input层作为自定义嵌入层
    """
    custom_embedding_layer = None
    
    # 遍历层,跳过Input层,取第一个有效层
    for layer in model.layers:
        # 判断是否为Input层(Keras中Input层类型为InputLayer)
        if isinstance(layer, tf.keras.layers.InputLayer):
            print(f"跳过Input层:{layer.name}")
            continue  # 继续找下一层
        else:
            # 找到第一个非Input层,作为嵌入层
            custom_embedding_layer = layer
            break  # 跳出循环
    
    # 校验:确保找到有效层
    if custom_embedding_layer is None:
        raise ValueError("模型中未找到非Input层,请检查模型结构")
    
    # 构建子模型
    input_tokens = model.input
    embedding_output = custom_embedding_layer(input_tokens)  # 传入输入张量
    
    return tf.keras.Model(inputs=input_tokens, outputs=embedding_output)


# --------------------------
# 4. 生成文本向量(保持不变)
# --------------------------
def get_text_embedding(text, embedding_extractor, char2idx, seq_length):
    preprocessed_tokens = preprocess_text(text, char2idx, seq_length)
    char_embeddings = embedding_extractor(preprocessed_tokens, training=False)
    
    # 均值池化(根据实际输出形状调整axis)
    text_embedding = tf.reduce_mean(char_embeddings, axis=1)
    return tf.squeeze(text_embedding).numpy()


# --------------------------
# 5. 计算相似度(保持不变)
# --------------------------
def calculate_similarity(text1, text2, embedding_extractor, char2idx, seq_length):
    emb1 = get_text_embedding(text1, embedding_extractor, char2idx, seq_length)
    emb2 = get_text_embedding(text2, embedding_extractor, char2idx, seq_length)
    
    dot_product = np.dot(emb1, emb2)
    norm1 = np.linalg.norm(emb1)
    norm2 = np.linalg.norm(emb2)
    
    if norm1 == 0 or norm2 == 0:
        return 0.0
    
    cos_sim = dot_product / (norm1 * norm2)
    return (cos_sim + 1) / 2  # 归一化到0~1


def xsd(a, b, z=0.65):
    seq_length=max([len(a), len(b)])
    # 步骤1:构建嵌入提取子模型(用第一层自定义嵌入层)
    embedding_extractor = build_embedding_extractor(m)
    v=calculate_similarity(a, b, embedding_extractor, char2idx, seq_length)
    print(v)
    return v>z

步骤4:测试相似度计算与准确率

直接运行代码即可查看结果:

if __name__ == "__main__":
    # 步骤1:构建嵌入提取子模型(用第一层自定义嵌入层)
    embedding_extractor = build_embedding_extractor(m)
    
    # 步骤2:定义待比对的文本(可替换为你的需求)
    text1 = "自然语言处理是人工智能的重要分支"
    text2 = "NLP是AI的重要分支"
    text3 = "今天的气温是25摄氏度"
    seq_length=max([len(text1), len(text2), len(text3)])
    # 步骤3:计算并打印相似度
    sim_12 = calculate_similarity(text1, text2, embedding_extractor, char2idx, seq_length)
    sim_13 = calculate_similarity(text1, text3, embedding_extractor, char2idx, seq_length)
    
    print(f"\n=== 文本相似度结果 ===")
    print(f"文本1:{text1}")
    print(f"文本2:{text2}")
    print(f"文本3:{text3}")
    print(f"\n文本1与文本2的相似度:{sim_12:.4f} {sim_12>0.75}")  # 预期:高相似度(如0.85+)
    print(f"文本1与文本3的相似度:{sim_13:.4f}")  # 预期:低相似度(如0.25-)

四、功能详解:文本相似度计算的核心逻辑

该方案的核心是“从预训练模型中提取文本嵌入,再通过余弦相似度判断语义关联”,具体流程可拆解为3步:

1. 文本预处理:统一输入格式

通过preprocess_text函数将文本转为模型可识别的索引:

  • char2idx将字符映射为索引(未知字符用填充符的索引替代);
  • seq_length(代码中为512)截断过长文本、填充过短文本,确保输入长度一致。

2. 文本嵌入提取:捕捉语义信息

build_embedding_extractor函数从T6-0.15B-ST模型中筛选有效层:

  • 跳过Keras的InputLayer,取第一个非Input层作为嵌入层(该层输出字符级嵌入,包含语义信息);
  • 构建子模型,输入为文本索引,输出为字符级嵌入张量(形状为[1, seq_length, 嵌入维度])。

3. 相似度计算:量化语义关联

  • 均值池化:通过tf.reduce_mean对字符级嵌入按“序列长度”维度(axis=1)求平均,得到单句的全局文本向量;
  • 余弦相似度:计算两个文本向量的点积与模长比值,再归一化到0~1(0表示完全不相似,1表示完全相似);
  • 阈值判断:xsd函数用0.65作为阈值,大于阈值则判定为“相似”(可根据业务场景调整阈值)。

五、注意事项

  1. 路径必须正确ckpt_dir(模型权重路径)和vocab(词汇表路径)需使用绝对路径,避免因相对路径解析错误导致模型加载失败;
  2. 模型类型匹配:T6-0.15B的模型的MT必须设为't6_standard',与dic字典中的参数及Xiaothink-T6-0.15B-ST模型匹配;
  3. 序列长度适配seq_lengthdic[MT][2]获取(默认512),xsd函数中会动态取两段文本的最大长度,确保预处理后长度合理;

六、总结

基于Xiaothink框架与Xiaothink-T6-0.15B-ST模型的文本相似度方案,无需复杂训练与配置,即可实现高效的文本匹配任务。该方案轻量、低耗,适合问答系统、文本去重、智能检索等场景,尤其适合资源有限的端侧环境。

如果需要扩展功能,例如支持批量计算、调整相似度阈值,或适配更多业务场景,可基于现有代码灵活修改。

再次附上模型下载链接:
Xiaothink-T6-0.15B-ST模型(ModelScope)

若在使用中遇到模型加载、相似度计算等问题,欢迎在评论区交流,也可联系Xiaothink官方邮箱:xiaothink@foxmail.com。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值