在魔乐社区创建一个基于MiniLM的应用

360影视 2025-01-06 17:47 3

摘要:MiniLM作为一种通用的面向Transformer-based预训练模型的压缩方法,旨在通过知识蒸馏等技术减小模型的大小,同时保持或提高模型的精度。这使得MiniLM能够在资源受限的环境下,如移动设备或嵌入式系统中,高效地运行。

本文将以MiniLM为测试,分享笔者在魔乐社区上传模型,以及应用的创建。

MiniLM作为一种通用的面向Transformer-based预训练模型的压缩方法,旨在通过知识蒸馏等技术减小模型的大小,同时保持或提高模型的精度。这使得MiniLM能够在资源受限的环境下,如移动设备或嵌入式系统中,高效地运行。

同时,由于MiniLM是基于Transformer架构的预训练模型,因此它适用于各种自然语言处理任务,包括但不限于:

· 文本分类:对文本进行自动分类,如情感分析、新闻分类等。

· 命名实体识别:识别文本中的实体,如人名、地名、机构名等。

· 问答系统:基于MiniLM的中文问答系统可以处理用户输入的问题,并从数据库中检索相关信息以生成答案。

· 语言生成:在给定文本或上下文的情况下,生成自然语言文本,如机器翻译、文本摘要等。

魔乐社区提供了多种上传和管理模型的工具,简化了模型分享的过程,通过共享模型,开发者可以推动整个社区的技术进步和创新。值得一提的是,魔乐社区提供了模型测试的流程。在模型训练到发布这个过程中,需要对模型进行测试来保证模型稳定性和可用性,测试也能反映在与个人开发机不同的环境下模型是否会出现问题。

通过测试的模型可以帮助后来的使用者更好的配置模型,减少出错的可能性。

在魔乐社区上传模型后,就可以通过openMind拉取模型和进行测试,有两种方法,第一种是在魔乐社区进行可用性测试,第二种是本地进行测试,两种方法大同小异。

· 可用性测试

首先是在魔乐社区进行测试,首先需要在上传模型的时候附带上 example 文件夹,以及其中的测试脚本和配置文件,目录形式如下:

然后在魔乐社区自己的模型库中运行可用性测试,当测试出现失败时需要结合日志进行错误排查。

from openmind import AutoModel, AutoTokenizer
model = AutoModel.from_pretrained("Congruent/MiniLM-L12-H384-uncased")

tokenizer = AutoTokenizer.from_pretrained("Congruent/MiniLM-L12-H384-uncased")

inputs = tokenizer("Hello world!", return_tensors="pt")
outputs = model(**inputs)

print(outputs)

上述脚本测试结果:

通过以上操作,我们就可以通过自己的训练集进行模型训练了,这里笔者导入了一个开源情感分析数据集用于测试:

使用Iris数据集,它是一个经典的多类分类问题数据集。训练了一个逻辑回归模型,并对测试集进行了预测,最后计算了模型的准确率

import torch
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
from transformers import AutoModel, AutoTokenizer, pipeline
from datasets import load_dataset

# 加载模型和分词器
model = AutoModel.from_pretrained("Congruent/MiniLM-L12-H384-uncased")
tokenizer = AutoTokenizer.from_pretrained("Congruent/MiniLM-L12-H384-uncased")

# 加载数据集(这里以IMDb为例)
dataset = load_dataset('imdb')
texts = [doc['text'] for doc in dataset['train']]
labels = [int(doc['label']) for doc in dataset['train']]

# 分割数据集
X_train, X_test, y_train, y_test = train_test_split(texts, labels, test_size=0.2, random_state=42)

# 使用模型提取特征
def extract_features(texts):
inputs = tokenizer(texts, padding=True, truncation=True, return_tensors="pt", max_length=512)
with torch.no_grad:
outputs = model(**inputs)
# 取[CLS]标记的隐藏状态作为特征
cls_embeddings = outputs.last_hidden_state[:, 0, :]
return cls_embeddings.cpu.numpy

X_train_features = extract_features(X_train)
X_test_features = extract_features(X_test)

# 训练逻辑回归分类器
clf = LogisticRegression(max_iter=1000)
clf.fit(X_train_features, y_train)

# 预测和评估
y_pred = clf.predict(X_test_features)
accuracy = accuracy_score(y_test, y_pred)
print(f'Accuracy: {accuracy:.4f}')

由于笔者水平有限,故这里只做最简单的问答:

基本过程:

(1)编码问题与答案:使用MiniLM模型对问题和答案进行编码,提取其特征表示。

(2)计算相似度:通过计算问题与答案特征表示之间的余弦相似度,找出与问题最相关的答案。

import torch
from openmind import AutoModel, AutoTokenizer
from sklearn.metrics.pairwise import cosine_similarity
import numpy as np

# 加载 MiniLM 模型和分词器
model_name = "Congruent/MiniLM-L12-H384-uncased"
model = AutoModel.from_pretrained(model_name)
tokenizer = AutoTokenizer.from_pretrained(model_name)

qa_pairs = [
{"question": "What is the capital of France?", "answer": "Paris"},
{"question": "Who is the CEO of Apple?", "answer": "Tim Cook"},
{"question": "How many legs does a spider have?", "answer": "Eight"}
]

def encode_question_and_answers(question, answers, tokenizer, model):
# 编码问题
inputs = tokenizer(question, return_tensors="pt", padding=True, truncation=True, max_length=512)
with torch.no_grad:
question_outputs = model(**inputs)
question_embedding = torch.mean(question_outputs.last_hidden_state, dim=1).detach.cpu.numpy # 一维数组

# 编码答案
answer_embeddings =
for answer in answers:
inputs = tokenizer(answer, return_tensors="pt", padding=True, truncation=True, max_length=512)
with torch.no_grad:
answer_outputs = model(**inputs)
answer_embedding = torch.mean(answer_outputs.last_hidden_state, dim=1).squeeze.detach.cpu.numpy # 确保是一维数组
answer_embeddings.append(answer_embedding)

# 直接将列表转换为 NumPy 数组,它将是一个二维数组(样本数 x 嵌入维度)
answer_embeddings_array = np.array(answer_embeddings)

return question_embedding, answer_embeddings_array

def find_best_answer(question, all_qa_pairs, tokenizer, model):
answers = [qa_pair["answer"] for qa_pair in all_qa_pairs]
question_embedding, answer_embeddings = encode_question_and_answers(question, answers, tokenizer, model)

# 计算相似度时,确保 question_embedding 是二维的
similarities = cosine_similarity(question_embedding[0].reshape(1, -1), answer_embeddings)
best_index = np.argmax(similarities)

return all_qa_pairs[best_index]["answer"]

# 测试问答系统
test_questions = [
"What is the capital of France?",
"Who leads Apple?",
"How many legs do spiders have?"
]

for question in test_questions:
best_answer = find_best_answer(question, qa_pairs, tokenizer, model)
print(f"Question: {question}\nAnswer: {best_answer}\n")

笔者在魔乐空间创建了一个体验空间,用于对上述问答的测试体验。

可以在这个问答系统中输入问题,会收到对应的匹配结果,如:

来源:DataFunTalk

相关推荐