1. 项目简介
Transformers.js是一个强大的JavaScript库,允许在浏览器和Node.js环境中运行预训练的Transformer模型。它基于ONNX Runtime,提供了与Hugging Face Transformers库类似的API,使开发者能够在前端应用中直接使用先进的NLP模型,无需服务器端依赖。
1.1 核心功能
- 浏览器端运行:在浏览器中直接运行Transformer模型,无需服务器后端
- Node.js支持:也可以在Node.js环境中使用
- 多种预训练模型:支持Hugging Face上的多种预训练模型
- ONNX格式:使用ONNX格式的模型,提高推理效率
- 与Hugging Face兼容:API设计与Hugging Face Transformers库类似
1.2 项目特点
- 无需服务器依赖:模型在客户端运行,保护用户隐私
- 轻量级:优化的模型加载和推理
- 易于集成:简单的API接口,易于集成到现有项目
- 跨平台:支持浏览器和Node.js环境
- 持续更新:不断添加新模型和功能
2. 安装与配置
2.1 在浏览器中使用
<!-- 通过CDN引入 -->
<script src="https://cdn.jsdelivr.net/npm/@xenova/transformers@2.17.0"></script>
<!-- 或者通过npm安装后使用 -->
<!-- npm install @xenova/transformers -->2.2 在Node.js中使用
# 安装依赖
npm install @xenova/transformers
# 验证安装
node -e "require('@xenova/transformers'); console.log('Transformers.js installed successfully');"3. 核心概念
3.1 模型加载
Transformers.js使用pipeline函数加载和使用预训练模型。模型会自动从Hugging Face Hub下载并缓存到本地。
3.2 管道(Pipeline)
管道是Transformers.js的核心概念,它封装了模型的加载和推理过程,提供了简单的API接口。支持多种任务类型,如文本分类、命名实体识别、翻译等。
3.3 模型缓存
Transformers.js会自动缓存下载的模型,避免重复下载,提高性能。缓存位置在浏览器中为IndexedDB,在Node.js中为本地文件系统。
3.4 ONNX Runtime
Transformers.js基于ONNX Runtime运行模型,提供高效的推理性能。ONNX Runtime针对不同硬件和平台进行了优化。
4. 基本用法
4.1 文本分类
// 在浏览器中
async function runTextClassification() {
// 加载文本分类管道
const classifier = await pipeline('sentiment-analysis');
// 分类文本
const result = await classifier('I love Transformers.js!');
console.log(result);
// 输出: [{ label: 'POSITIVE', score: 0.9998 }]
}
runTextClassification();
// 在Node.js中
const { pipeline } = require('@xenova/transformers');
async function runTextClassification() {
const classifier = await pipeline('sentiment-analysis');
const result = await classifier('I love Transformers.js!');
console.log(result);
}
runTextClassification();4.2 命名实体识别
async function runNER() {
// 加载命名实体识别管道
const ner = await pipeline('ner');
// 识别实体
const result = await ner('My name is John and I live in New York.');
console.log(result);
/* 输出:
[
{ entity: 'PER', score: 0.9995, index: 3, word: 'John', start: 11, end: 15 },
{ entity: 'LOC', score: 0.9996, index: 7, word: 'New', start: 25, end: 28 },
{ entity: 'LOC', score: 0.9998, index: 8, word: 'York', start: 29, end: 33 }
]
*/
}
runNER();4.3 文本生成
async function runTextGeneration() {
// 加载文本生成管道
const generator = await pipeline('text-generation');
// 生成文本
const result = await generator('Once upon a time', {
max_new_tokens: 50,
temperature: 0.7
});
console.log(result[0].generated_text);
// 输出: 生成的文本内容
}
runTextGeneration();4.4 翻译
async function runTranslation() {
// 加载翻译管道(英语到法语)
const translator = await pipeline('translation', 'Xenova/opus-mt-en-fr');
// 翻译文本
const result = await translator('Hello, how are you?');
console.log(result[0].translation_text);
// 输出: 'Bonjour, comment allez-vous?'
}
runTranslation();5. 高级特性
5.1 自定义模型
async function useCustomModel() {
// 加载自定义模型
const classifier = await pipeline('sentiment-analysis', {
model: 'Xenova/distilbert-base-uncased-finetuned-sst-2-english',
// 可选配置
quantized: true, // 使用量化模型减小大小
cache_dir: './models' // 自定义缓存目录
});
// 使用模型
const result = await classifier('I hate this product.');
console.log(result);
}
useCustomModel();5.2 模型缓存管理
// 清除缓存
await pipeline('sentiment-analysis', {
clear_cache: true
});
// 自定义缓存策略
const classifier = await pipeline('sentiment-analysis', {
cache_dir: './my-models',
use_cache: true
});5.3 批量处理
async function batchProcessing() {
const classifier = await pipeline('sentiment-analysis');
// 批量处理多个文本
const texts = [
'I love this movie!',
'This is the worst film I have ever seen.',
'The acting was fantastic.'
];
const results = await classifier(texts);
console.log(results);
/* 输出:
[
{ label: 'POSITIVE', score: 0.9998 },
{ label: 'NEGATIVE', score: 0.9991 },
{ label: 'POSITIVE', score: 0.9997 }
]
*/
}
batchProcessing();5.4 进度跟踪
async function trackProgress() {
const classifier = await pipeline('sentiment-analysis', {
progress_callback: (progress) => {
console.log(`Model loading progress: ${Math.round(progress * 100)}%`);
}
});
// 使用模型
const result = await classifier('Hello world!');
console.log(result);
}
trackProgress();6. 实际应用案例
6.1 情感分析Web应用
场景:创建一个Web应用,允许用户输入文本并分析其情感
步骤:
- 创建HTML页面
- 引入Transformers.js
- 实现情感分析功能
- 显示结果
代码示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>情感分析应用</title>
<script src="https://cdn.jsdelivr.net/npm/@xenova/transformers@2.17.0"></script>
<style>
body {
font-family: Arial, sans-serif;
max-width: 800px;
margin: 0 auto;
padding: 20px;
}
.container {
background-color: #f5f5f5;
padding: 20px;
border-radius: 8px;
}
textarea {
width: 100%;
height: 100px;
padding: 10px;
border: 1px solid #ddd;
border-radius: 4px;
resize: vertical;
}
button {
margin-top: 10px;
padding: 10px 20px;
background-color: #4CAF50;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
button:hover {
background-color: #45a049;
}
.result {
margin-top: 20px;
padding: 10px;
border-radius: 4px;
}
.positive {
background-color: #d4edda;
color: #155724;
}
.negative {
background-color: #f8d7da;
color: #721c24;
}
</style>
</head>
<body>
<div class="container">
<h1>情感分析应用</h1>
<p>输入文本,点击分析按钮查看情感分析结果:</p>
<textarea id="text-input" placeholder="请输入要分析的文本..."></textarea>
<button onclick="analyzeSentiment()">分析情感</button>
<div id="result" class="result" style="display: none;"></div>
</div>
<script>
let classifier;
// 初始化模型
async function initModel() {
console.log('正在加载情感分析模型...');
classifier = await pipeline('sentiment-analysis');
console.log('模型加载完成!');
}
// 分析情感
async function analyzeSentiment() {
const text = document.getElementById('text-input').value;
if (!text.trim()) {
alert('请输入要分析的文本');
return;
}
if (!classifier) {
await initModel();
}
console.log('正在分析情感...');
const result = await classifier(text);
console.log('分析结果:', result);
// 显示结果
const resultDiv = document.getElementById('result');
resultDiv.style.display = 'block';
resultDiv.className = `result ${result[0].label.toLowerCase()}`;
resultDiv.innerHTML = `
<strong>情感分析结果:</strong>${result[0].label}<br>
<strong>置信度:</strong>${(result[0].score * 100).toFixed(2)}%
`;
}
// 页面加载时初始化模型
window.onload = initModel;
</script>
</body>
</html>6.2 实时聊天机器人
场景:创建一个基于Transformers.js的实时聊天机器人
步骤:
- 创建HTML页面
- 引入Transformers.js
- 加载对话模型
- 实现聊天功能
代码示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>聊天机器人</title>
<script src="https://cdn.jsdelivr.net/npm/@xenova/transformers@2.17.0"></script>
<style>
body {
font-family: Arial, sans-serif;
max-width: 800px;
margin: 0 auto;
padding: 20px;
}
.chat-container {
background-color: #f5f5f5;
padding: 20px;
border-radius: 8px;
height: 400px;
overflow-y: scroll;
margin-bottom: 10px;
}
.message {
margin-bottom: 10px;
padding: 10px;
border-radius: 4px;
}
.user-message {
background-color: #e3f2fd;
align-self: flex-end;
margin-left: 50px;
}
.bot-message {
background-color: #e8f5e8;
align-self: flex-start;
margin-right: 50px;
}
.input-container {
display: flex;
}
input {
flex: 1;
padding: 10px;
border: 1px solid #ddd;
border-radius: 4px 0 0 4px;
}
button {
padding: 10px 20px;
background-color: #4CAF50;
color: white;
border: none;
border-radius: 0 4px 4px 0;
cursor: pointer;
}
button:hover {
background-color: #45a049;
}
.loading {
font-style: italic;
color: #666;
}
</style>
</head>
<body>
<h1>聊天机器人</h1>
<div class="chat-container" id="chat-container">
<div class="message bot-message">
你好!我是基于Transformers.js的聊天机器人。有什么我可以帮助你的吗?
</div>
</div>
<div class="input-container">
<input type="text" id="user-input" placeholder="输入消息..." onkeypress="if(event.key === 'Enter') sendMessage()">
<button onclick="sendMessage()">发送</button>
</div>
<script>
let generator;
// 初始化模型
async function initModel() {
console.log('正在加载对话模型...');
generator = await pipeline('text-generation', 'Xenova/distilgpt2');
console.log('模型加载完成!');
}
// 发送消息
async function sendMessage() {
const userInput = document.getElementById('user-input').value;
if (!userInput.trim()) return;
// 添加用户消息
addMessage(userInput, 'user');
document.getElementById('user-input').value = '';
// 添加加载中消息
const loadingId = addMessage('正在思考...', 'bot', true);
if (!generator) {
await initModel();
}
// 生成回复
const prompt = `User: ${userInput}\nAssistant:`;
const result = await generator(prompt, {
max_new_tokens: 100,
temperature: 0.7,
stop_sequence: ['User:']
});
// 移除加载中消息
document.getElementById(loadingId).remove();
// 添加机器人回复
const response = result[0].generated_text.replace(prompt, '').trim();
addMessage(response, 'bot');
}
// 添加消息到聊天界面
function addMessage(text, sender, isLoading = false) {
const chatContainer = document.getElementById('chat-container');
const messageDiv = document.createElement('div');
const messageId = `message-${Date.now()}`;
messageDiv.id = messageId;
messageDiv.className = `message ${sender}-message ${isLoading ? 'loading' : ''}`;
messageDiv.textContent = text;
chatContainer.appendChild(messageDiv);
chatContainer.scrollTop = chatContainer.scrollHeight;
return messageId;
}
// 页面加载时初始化模型
window.onload = initModel;
</script>
</body>
</html>6.3 多语言翻译应用
场景:创建一个支持多语言翻译的Web应用
步骤:
- 创建HTML页面
- 引入Transformers.js
- 实现翻译功能
- 支持多种语言对
代码示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>多语言翻译应用</title>
<script src="https://cdn.jsdelivr.net/npm/@xenova/transformers@2.17.0"></script>
<style>
body {
font-family: Arial, sans-serif;
max-width: 800px;
margin: 0 auto;
padding: 20px;
}
.container {
background-color: #f5f5f5;
padding: 20px;
border-radius: 8px;
}
textarea {
width: 100%;
height: 100px;
padding: 10px;
border: 1px solid #ddd;
border-radius: 4px;
resize: vertical;
margin-bottom: 10px;
}
.controls {
margin-bottom: 10px;
}
select {
padding: 8px;
border: 1px solid #ddd;
border-radius: 4px;
margin-right: 10px;
}
button {
padding: 8px 16px;
background-color: #4CAF50;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
button:hover {
background-color: #45a049;
}
.result {
margin-top: 20px;
padding: 10px;
border-radius: 4px;
background-color: #e3f2fd;
}
</style>
</head>
<body>
<div class="container">
<h1>多语言翻译应用</h1>
<div class="controls">
<select id="source-lang">
<option value="en">英语</option>
<option value="fr">法语</option>
<option value="de">德语</option>
<option value="es">西班牙语</option>
</select>
<span>→</span>
<select id="target-lang">
<option value="fr">法语</option>
<option value="de">德语</option>
<option value="es">西班牙语</option>
<option value="en">英语</option>
</select>
</div>
<textarea id="input-text" placeholder="请输入要翻译的文本..."></textarea>
<button onclick="translateText()">翻译</button>
<div id="result" class="result" style="display: none;">
<h3>翻译结果:</h3>
<div id="translation-result"></div>
</div>
</div>
<script>
let translators = {};
// 翻译文本
async function translateText() {
const sourceLang = document.getElementById('source-lang').value;
const targetLang = document.getElementById('target-lang').value;
const inputText = document.getElementById('input-text').value;
if (!inputText.trim()) {
alert('请输入要翻译的文本');
return;
}
// 生成模型名称
const modelName = `Xenova/opus-mt-${sourceLang}-${targetLang}`;
// 加载翻译器
if (!translators[modelName]) {
console.log(`正在加载翻译模型: ${modelName}...`);
translators[modelName] = await pipeline('translation', modelName);
console.log('模型加载完成!');
}
// 执行翻译
console.log('正在翻译...');
const result = await translators[modelName](inputText);
console.log('翻译结果:', result);
// 显示结果
const resultDiv = document.getElementById('result');
const translationDiv = document.getElementById('translation-result');
resultDiv.style.display = 'block';
translationDiv.textContent = result[0].translation_text;
}
</script>
</body>
</html>7. 总结与展望
Transformers.js为前端开发者提供了在浏览器和Node.js环境中直接使用Transformer模型的能力,无需服务器后端。它的出现极大地扩展了AI模型的应用场景,使得更多的AI功能可以在客户端实现,保护用户隐私的同时提高响应速度。
7.1 主要优势
- 客户端运行:模型在客户端运行,无需服务器依赖
- 易于集成:简单的API接口,易于集成到现有项目
- 跨平台:支持浏览器和Node.js环境
- 轻量级:优化的模型加载和推理
- 与Hugging Face兼容:API设计与Hugging Face Transformers库类似
7.2 未来发展
- 更多模型支持:持续添加对更多预训练模型的支持
- 性能优化:进一步提高模型推理速度和内存使用效率
- 功能扩展:添加更多NLP任务和功能
- 工具链完善:提供更多开发工具和示例
- 生态系统建设:构建更丰富的开发者生态
Transformers.js正在改变前端开发的格局,使得AI能力可以更直接地集成到前端应用中。通过掌握Transformers.js,开发者可以创建更加智能、响应迅速且保护用户隐私的Web应用。