feat: Implement AI consultation feature with local LLM support
- Add consultation modal component with chat interface - Create LLM service for connecting to local Ollama - Integrate Qwen model support (7B/14B/32B variants) - Add knowledge base preparation script - Create comprehensive Qwen training documentation - Add Ollama setup and configuration script - Update translations for consultation feature (zh/en/de) - Generate OmniVerse company knowledge base data Features: - Real-time chat with AI health consultant - Support for multiple Qwen model sizes - RAG-ready knowledge base structure - Complete deployment and training guide 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
This commit is contained in:
@@ -0,0 +1,481 @@
|
||||
# Qwen模型训练与部署指南
|
||||
|
||||
本文档详细介绍如何训练和部署Qwen模型用于OmniVerse智能健康咨询服务。
|
||||
|
||||
## 目录
|
||||
- [环境准备](#环境准备)
|
||||
- [使用Ollama部署](#使用ollama部署)
|
||||
- [知识库准备](#知识库准备)
|
||||
- [模型微调](#模型微调)
|
||||
- [LangChain集成](#langchain集成)
|
||||
- [性能优化](#性能优化)
|
||||
|
||||
## 环境准备
|
||||
|
||||
### 硬件要求
|
||||
- **Qwen2.5-32B**: 至少64GB内存,建议使用GPU(VRAM 24GB+)
|
||||
- **Qwen2.5-14B**: 至少32GB内存,建议使用GPU(VRAM 16GB+)
|
||||
- **Qwen2.5-7B**: 至少16GB内存,可在CPU上运行
|
||||
|
||||
### 软件环境
|
||||
```bash
|
||||
# 安装Python环境
|
||||
python -m venv venv
|
||||
source venv/bin/activate # Linux/Mac
|
||||
# venv\Scripts\activate # Windows
|
||||
|
||||
# 安装依赖
|
||||
pip install transformers torch datasets accelerate
|
||||
pip install ollama langchain chromadb
|
||||
```
|
||||
|
||||
## 使用Ollama部署
|
||||
|
||||
### 1. 安装Ollama
|
||||
|
||||
```bash
|
||||
# macOS/Linux
|
||||
curl -fsSL https://ollama.ai/install.sh | sh
|
||||
|
||||
# Windows
|
||||
# 下载安装包:https://ollama.ai/download/windows
|
||||
```
|
||||
|
||||
### 2. 下载Qwen模型
|
||||
|
||||
```bash
|
||||
# 下载不同版本的Qwen模型
|
||||
ollama pull qwen2.5:32b # 32B参数版本(推荐,效果最好)
|
||||
ollama pull qwen2.5:14b # 14B参数版本(平衡性能)
|
||||
ollama pull qwen2.5:7b # 7B参数版本(轻量级)
|
||||
|
||||
# 查看已安装的模型
|
||||
ollama list
|
||||
```
|
||||
|
||||
### 3. 启动Ollama服务
|
||||
|
||||
```bash
|
||||
# 启动服务(默认端口11434)
|
||||
ollama serve
|
||||
|
||||
# 测试模型
|
||||
curl http://localhost:11434/api/generate -d '{
|
||||
"model": "qwen2.5:32b",
|
||||
"prompt": "介绍一下OmniVerse公司"
|
||||
}'
|
||||
```
|
||||
|
||||
### 4. 创建定制化模型
|
||||
|
||||
创建 `Modelfile` 文件:
|
||||
|
||||
```dockerfile
|
||||
FROM qwen2.5:32b
|
||||
|
||||
# 设置系统提示词
|
||||
SYSTEM """你是OmniVerse(灵境万象)公司的智能健康顾问助手。OmniVerse是一家专注于AI+健康领域的科技公司。
|
||||
|
||||
公司核心产品:
|
||||
1. 智能穿戴设备:24/7健康监测,心率、血氧、睡眠分析
|
||||
2. 护理机器人:智能陪伴、健康提醒、远程医疗
|
||||
3. 健康数据平台:AI预测、数据分析、医疗协作
|
||||
|
||||
请专业、友好地回答用户问题。"""
|
||||
|
||||
# 设置参数
|
||||
PARAMETER temperature 0.7
|
||||
PARAMETER top_p 0.9
|
||||
PARAMETER num_predict 2048
|
||||
```
|
||||
|
||||
创建定制模型:
|
||||
|
||||
```bash
|
||||
# 基于Modelfile创建新模型
|
||||
ollama create omniverse-assistant -f ./Modelfile
|
||||
|
||||
# 运行定制模型
|
||||
ollama run omniverse-assistant
|
||||
```
|
||||
|
||||
## 知识库准备
|
||||
|
||||
### 1. 生成知识库数据
|
||||
|
||||
```bash
|
||||
# 运行知识库准备脚本
|
||||
node scripts/prepare-knowledge-base.js
|
||||
|
||||
# 生成的文件:
|
||||
# - knowledge-base/knowledge-base.json(完整知识库)
|
||||
# - knowledge-base/training-data.jsonl(训练数据)
|
||||
# - knowledge-base/chat-data.jsonl(对话数据)
|
||||
```
|
||||
|
||||
### 2. 数据格式说明
|
||||
|
||||
**训练数据格式(JSONL)**:
|
||||
```json
|
||||
{"instruction": "介绍OmniVerse公司", "input": "", "output": "OmniVerse是..."}
|
||||
{"instruction": "智能手表有哪些功能", "input": "", "output": "我们的智能手表..."}
|
||||
```
|
||||
|
||||
**对话数据格式**:
|
||||
```json
|
||||
{"messages": [
|
||||
{"role": "user", "content": "你们的产品有哪些?"},
|
||||
{"role": "assistant", "content": "我们有三大产品线..."}
|
||||
]}
|
||||
```
|
||||
|
||||
## 模型微调
|
||||
|
||||
### 方法1:使用Ollama的RAG(推荐)
|
||||
|
||||
不需要真正微调模型,而是使用RAG(检索增强生成)技术:
|
||||
|
||||
```python
|
||||
from langchain.llms import Ollama
|
||||
from langchain.embeddings import OllamaEmbeddings
|
||||
from langchain.vectorstores import Chroma
|
||||
from langchain.text_splitter import RecursiveCharacterTextSplitter
|
||||
from langchain.chains import RetrievalQA
|
||||
import json
|
||||
|
||||
# 初始化Ollama
|
||||
llm = Ollama(model="qwen2.5:32b", base_url="http://localhost:11434")
|
||||
embeddings = OllamaEmbeddings(model="qwen2.5:32b")
|
||||
|
||||
# 加载知识库
|
||||
with open("knowledge-base/knowledge-base.json", "r", encoding="utf-8") as f:
|
||||
knowledge = json.load(f)
|
||||
|
||||
# 转换为文本
|
||||
documents = []
|
||||
for category, content in knowledge.items():
|
||||
text = json.dumps(content, ensure_ascii=False, indent=2)
|
||||
documents.append(text)
|
||||
|
||||
# 分割文本
|
||||
text_splitter = RecursiveCharacterTextSplitter(
|
||||
chunk_size=1000,
|
||||
chunk_overlap=200
|
||||
)
|
||||
splits = text_splitter.create_documents(documents)
|
||||
|
||||
# 创建向量数据库
|
||||
vectorstore = Chroma.from_documents(
|
||||
documents=splits,
|
||||
embedding=embeddings,
|
||||
persist_directory="./chroma_db"
|
||||
)
|
||||
|
||||
# 创建检索QA链
|
||||
qa_chain = RetrievalQA.from_chain_type(
|
||||
llm=llm,
|
||||
chain_type="stuff",
|
||||
retriever=vectorstore.as_retriever(search_kwargs={"k": 3})
|
||||
)
|
||||
|
||||
# 使用
|
||||
response = qa_chain.run("OmniWatch Pro的价格是多少?")
|
||||
print(response)
|
||||
```
|
||||
|
||||
### 方法2:LoRA微调(高级)
|
||||
|
||||
如果需要深度定制,可以使用LoRA进行参数高效微调:
|
||||
|
||||
```python
|
||||
from transformers import AutoModelForCausalLM, AutoTokenizer, TrainingArguments
|
||||
from peft import LoraConfig, get_peft_model, TaskType
|
||||
from datasets import load_dataset
|
||||
|
||||
# 加载基础模型
|
||||
model_id = "Qwen/Qwen2.5-7B" # 使用较小版本进行微调
|
||||
model = AutoModelForCausalLM.from_pretrained(model_id, device_map="auto")
|
||||
tokenizer = AutoTokenizer.from_pretrained(model_id)
|
||||
|
||||
# LoRA配置
|
||||
lora_config = LoraConfig(
|
||||
task_type=TaskType.CAUSAL_LM,
|
||||
r=16,
|
||||
lora_alpha=32,
|
||||
lora_dropout=0.1,
|
||||
target_modules=["q_proj", "v_proj"]
|
||||
)
|
||||
|
||||
# 应用LoRA
|
||||
model = get_peft_model(model, lora_config)
|
||||
|
||||
# 加载数据
|
||||
dataset = load_dataset("json", data_files="knowledge-base/training-data.jsonl")
|
||||
|
||||
# 训练参数
|
||||
training_args = TrainingArguments(
|
||||
output_dir="./qwen-omniverse",
|
||||
num_train_epochs=3,
|
||||
per_device_train_batch_size=1,
|
||||
gradient_accumulation_steps=4,
|
||||
warmup_steps=100,
|
||||
logging_steps=10,
|
||||
save_strategy="epoch",
|
||||
evaluation_strategy="no",
|
||||
learning_rate=1e-4,
|
||||
)
|
||||
|
||||
# 训练(需要GPU)
|
||||
# trainer = Trainer(model=model, args=training_args, train_dataset=dataset)
|
||||
# trainer.train()
|
||||
```
|
||||
|
||||
## LangChain集成
|
||||
|
||||
### 完整的聊天应用示例
|
||||
|
||||
```python
|
||||
import os
|
||||
from langchain.llms import Ollama
|
||||
from langchain.memory import ConversationBufferMemory
|
||||
from langchain.chains import ConversationChain
|
||||
from langchain.prompts import PromptTemplate
|
||||
|
||||
# 配置
|
||||
os.environ["OLLAMA_HOST"] = "http://localhost:11434"
|
||||
|
||||
# 初始化LLM
|
||||
llm = Ollama(
|
||||
model="qwen2.5:32b",
|
||||
temperature=0.7,
|
||||
num_predict=2048
|
||||
)
|
||||
|
||||
# 自定义提示模板
|
||||
template = """你是OmniVerse公司的智能健康顾问。请基于以下对话历史,专业友好地回答用户问题。
|
||||
|
||||
对话历史:
|
||||
{history}
|
||||
|
||||
用户:{input}
|
||||
助手:"""
|
||||
|
||||
prompt = PromptTemplate(
|
||||
input_variables=["history", "input"],
|
||||
template=template
|
||||
)
|
||||
|
||||
# 创建对话链
|
||||
memory = ConversationBufferMemory()
|
||||
conversation = ConversationChain(
|
||||
llm=llm,
|
||||
memory=memory,
|
||||
prompt=prompt,
|
||||
verbose=True
|
||||
)
|
||||
|
||||
# 使用示例
|
||||
def chat():
|
||||
print("OmniVerse智能健康顾问已就绪,输入'退出'结束对话")
|
||||
while True:
|
||||
user_input = input("\n用户: ")
|
||||
if user_input.lower() in ['退出', 'exit', 'quit']:
|
||||
break
|
||||
|
||||
response = conversation.predict(input=user_input)
|
||||
print(f"\n助手: {response}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
chat()
|
||||
```
|
||||
|
||||
## 性能优化
|
||||
|
||||
### 1. 量化优化
|
||||
|
||||
使用量化版本减少内存占用:
|
||||
|
||||
```bash
|
||||
# 下载量化版本
|
||||
ollama pull qwen2.5:32b-q4_0 # 4-bit量化
|
||||
ollama pull qwen2.5:32b-q8_0 # 8-bit量化
|
||||
```
|
||||
|
||||
### 2. 批处理优化
|
||||
|
||||
```python
|
||||
# 批量处理请求
|
||||
import asyncio
|
||||
from ollama import AsyncClient
|
||||
|
||||
async def batch_generate(prompts):
|
||||
client = AsyncClient()
|
||||
tasks = []
|
||||
|
||||
for prompt in prompts:
|
||||
task = client.generate(
|
||||
model='qwen2.5:32b',
|
||||
prompt=prompt,
|
||||
stream=False
|
||||
)
|
||||
tasks.append(task)
|
||||
|
||||
responses = await asyncio.gather(*tasks)
|
||||
return responses
|
||||
|
||||
# 使用
|
||||
prompts = [
|
||||
"介绍智能手表",
|
||||
"养老解决方案",
|
||||
"数据安全措施"
|
||||
]
|
||||
results = asyncio.run(batch_generate(prompts))
|
||||
```
|
||||
|
||||
### 3. 缓存策略
|
||||
|
||||
```python
|
||||
from functools import lru_cache
|
||||
import hashlib
|
||||
|
||||
class CachedLLM:
|
||||
def __init__(self, llm):
|
||||
self.llm = llm
|
||||
self.cache = {}
|
||||
|
||||
def generate(self, prompt):
|
||||
# 生成缓存键
|
||||
cache_key = hashlib.md5(prompt.encode()).hexdigest()
|
||||
|
||||
# 检查缓存
|
||||
if cache_key in self.cache:
|
||||
return self.cache[cache_key]
|
||||
|
||||
# 生成响应
|
||||
response = self.llm.generate(prompt)
|
||||
self.cache[cache_key] = response
|
||||
|
||||
return response
|
||||
```
|
||||
|
||||
### 4. 流式响应
|
||||
|
||||
```python
|
||||
import ollama
|
||||
|
||||
def stream_chat(prompt):
|
||||
stream = ollama.generate(
|
||||
model='qwen2.5:32b',
|
||||
prompt=prompt,
|
||||
stream=True
|
||||
)
|
||||
|
||||
for chunk in stream:
|
||||
print(chunk['response'], end='', flush=True)
|
||||
```
|
||||
|
||||
## 部署建议
|
||||
|
||||
### 开发环境
|
||||
- 使用 Qwen2.5-7B 进行快速迭代
|
||||
- 单机部署,使用CPU即可
|
||||
|
||||
### 测试环境
|
||||
- 使用 Qwen2.5-14B
|
||||
- 配置8GB+ GPU加速
|
||||
- 启用响应缓存
|
||||
|
||||
### 生产环境
|
||||
- 使用 Qwen2.5-32B 或量化版本
|
||||
- 多GPU服务器部署
|
||||
- 负载均衡 + 缓存层
|
||||
- 监控响应时间和准确率
|
||||
|
||||
## 监控与维护
|
||||
|
||||
### 监控指标
|
||||
```python
|
||||
import time
|
||||
import psutil
|
||||
import GPUtil
|
||||
|
||||
class ModelMonitor:
|
||||
def __init__(self):
|
||||
self.metrics = {
|
||||
'request_count': 0,
|
||||
'total_latency': 0,
|
||||
'error_count': 0
|
||||
}
|
||||
|
||||
def log_request(self, latency, success=True):
|
||||
self.metrics['request_count'] += 1
|
||||
self.metrics['total_latency'] += latency
|
||||
if not success:
|
||||
self.metrics['error_count'] += 1
|
||||
|
||||
def get_stats(self):
|
||||
avg_latency = self.metrics['total_latency'] / max(1, self.metrics['request_count'])
|
||||
|
||||
# 系统资源
|
||||
cpu_percent = psutil.cpu_percent()
|
||||
memory = psutil.virtual_memory()
|
||||
|
||||
# GPU资源(如果有)
|
||||
gpus = GPUtil.getGPUs()
|
||||
gpu_stats = []
|
||||
for gpu in gpus:
|
||||
gpu_stats.append({
|
||||
'name': gpu.name,
|
||||
'load': gpu.load * 100,
|
||||
'memory': gpu.memoryUtil * 100
|
||||
})
|
||||
|
||||
return {
|
||||
'requests': self.metrics['request_count'],
|
||||
'avg_latency': avg_latency,
|
||||
'error_rate': self.metrics['error_count'] / max(1, self.metrics['request_count']),
|
||||
'cpu_usage': cpu_percent,
|
||||
'memory_usage': memory.percent,
|
||||
'gpu_stats': gpu_stats
|
||||
}
|
||||
```
|
||||
|
||||
## 常见问题
|
||||
|
||||
### Q1: Ollama服务无法启动
|
||||
```bash
|
||||
# 检查端口占用
|
||||
lsof -i :11434
|
||||
|
||||
# 重启服务
|
||||
killall ollama
|
||||
ollama serve
|
||||
```
|
||||
|
||||
### Q2: 模型响应速度慢
|
||||
- 使用量化版本
|
||||
- 启用GPU加速
|
||||
- 减少 num_predict 参数
|
||||
- 实施缓存策略
|
||||
|
||||
### Q3: 内存不足
|
||||
```bash
|
||||
# 使用更小的模型
|
||||
ollama pull qwen2.5:7b
|
||||
|
||||
# 或使用量化版本
|
||||
ollama pull qwen2.5:32b-q4_0
|
||||
```
|
||||
|
||||
### Q4: 如何更新知识库
|
||||
1. 修改 `scripts/prepare-knowledge-base.js`
|
||||
2. 重新生成数据:`node scripts/prepare-knowledge-base.js`
|
||||
3. 重新创建向量数据库
|
||||
4. 或更新Modelfile中的系统提示词
|
||||
|
||||
## 相关资源
|
||||
|
||||
- [Qwen官方仓库](https://github.com/QwenLM/Qwen2.5)
|
||||
- [Ollama文档](https://ollama.ai/docs)
|
||||
- [LangChain文档](https://python.langchain.com/)
|
||||
- [OmniVerse API文档](./docs/api.md)
|
||||
@@ -0,0 +1,2 @@
|
||||
{"messages":[{"role":"user","content":"我想了解你们的智能手表产品"},{"role":"assistant","content":"我们有OmniWatch Pro智能手表,这是一款医疗级的健康监测设备。它具有心率监测(精度±2bpm)、连续血氧监测、睡眠分期分析、跌倒检测等功能,7天续航,售价1999元。特别适合老年人和慢病患者使用。您是为自己还是为家人咨询呢?"}]}
|
||||
{"messages":[{"role":"user","content":"养老院如何使用你们的产品?"},{"role":"assistant","content":"我们为养老院提供完整的智慧养老解决方案。包括:1)为每位老人配备智能穿戴设备,实现24小时健康监护;2)部署护理机器人协助日常照护;3)健康数据管理平台供护理人员使用;4)家属远程关怀APP。上海阳光养老院使用我们的方案后,事故率降低60%,老人满意度达98%。"}]}
|
||||
@@ -0,0 +1,251 @@
|
||||
{
|
||||
"company": {
|
||||
"name": "OmniVerse (灵境万象)",
|
||||
"founded": "2020",
|
||||
"headquarters": "上海,中国",
|
||||
"mission": "通过AI和健康科技的融合,让每个人都能享受智慧健康生活",
|
||||
"vision": "成为全球领先的智慧健康科技公司",
|
||||
"values": [
|
||||
"创新",
|
||||
"专业",
|
||||
"关怀",
|
||||
"可靠"
|
||||
],
|
||||
"website": "https://omniverse.ai",
|
||||
"contact": {
|
||||
"phone": "400-888-9999",
|
||||
"email": "[email protected]",
|
||||
"address": "上海市浦东新区张江高科技园区"
|
||||
}
|
||||
},
|
||||
"products": [
|
||||
{
|
||||
"name": "智能穿戴设备系列",
|
||||
"category": "硬件产品",
|
||||
"models": [
|
||||
{
|
||||
"name": "OmniWatch Pro",
|
||||
"features": [
|
||||
"医疗级心率监测(精度±2bpm)",
|
||||
"连续血氧饱和度监测",
|
||||
"睡眠分期分析(深睡、浅睡、REM)",
|
||||
"跌倒检测与自动报警",
|
||||
"7天续航,无线充电",
|
||||
"IP68防水防尘"
|
||||
],
|
||||
"price": "¥1,999",
|
||||
"target": "老年人、慢病患者"
|
||||
},
|
||||
{
|
||||
"name": "OmniBand Health",
|
||||
"features": [
|
||||
"基础生命体征监测",
|
||||
"运动数据记录",
|
||||
"健康提醒功能",
|
||||
"30天超长续航",
|
||||
"轻量化设计(仅15g)"
|
||||
],
|
||||
"price": "¥599",
|
||||
"target": "普通消费者、运动爱好者"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "护理机器人系列",
|
||||
"category": "智能硬件",
|
||||
"models": [
|
||||
{
|
||||
"name": "CareBot-X1",
|
||||
"features": [
|
||||
"自然语言交互(支持方言)",
|
||||
"情感识别与陪伴",
|
||||
"用药提醒与管理",
|
||||
"远程视频诊疗",
|
||||
"自主导航与避障",
|
||||
"紧急情况处理"
|
||||
],
|
||||
"price": "¥29,999",
|
||||
"target": "养老院、医院"
|
||||
},
|
||||
{
|
||||
"name": "CompanionBot Mini",
|
||||
"features": [
|
||||
"智能对话陪伴",
|
||||
"健康数据监测",
|
||||
"娱乐互动功能",
|
||||
"家庭安防监控"
|
||||
],
|
||||
"price": "¥9,999",
|
||||
"target": "家庭用户"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "健康数据平台",
|
||||
"category": "软件服务",
|
||||
"modules": [
|
||||
{
|
||||
"name": "数据采集模块",
|
||||
"features": [
|
||||
"多源数据接入(穿戴设备、医疗设备、手动输入)",
|
||||
"实时数据同步",
|
||||
"数据清洗与标准化"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "AI分析引擎",
|
||||
"features": [
|
||||
"健康风险评估模型",
|
||||
"疾病预测算法",
|
||||
"个性化健康建议",
|
||||
"趋势分析与报告"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "医疗协作系统",
|
||||
"features": [
|
||||
"电子健康档案",
|
||||
"医生端管理界面",
|
||||
"远程会诊支持",
|
||||
"处方管理系统"
|
||||
]
|
||||
}
|
||||
],
|
||||
"pricing": {
|
||||
"basic": "¥99/月/用户",
|
||||
"professional": "¥299/月/用户",
|
||||
"enterprise": "定制价格"
|
||||
}
|
||||
}
|
||||
],
|
||||
"solutions": [
|
||||
{
|
||||
"name": "智慧养老解决方案",
|
||||
"targetCustomer": "养老院、康养中心",
|
||||
"components": [
|
||||
"智能穿戴设备全员配备",
|
||||
"护理机器人辅助照护",
|
||||
"健康数据管理平台",
|
||||
"家属远程关怀APP"
|
||||
],
|
||||
"benefits": [
|
||||
"降低护理人员工作强度30%",
|
||||
"提高老人满意度至95%以上",
|
||||
"减少意外事故发生率50%",
|
||||
"实现24小时健康监护"
|
||||
],
|
||||
"cases": [
|
||||
{
|
||||
"customer": "上海阳光养老院",
|
||||
"scale": "200+老人",
|
||||
"results": "事故率降低60%,满意度提升至98%"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "医院数字化健康管理",
|
||||
"targetCustomer": "三甲医院、专科医院",
|
||||
"components": [
|
||||
"患者健康监测系统",
|
||||
"AI辅助诊断平台",
|
||||
"医疗数据中台",
|
||||
"移动医护工作站"
|
||||
],
|
||||
"benefits": [
|
||||
"诊疗效率提升40%",
|
||||
"减少医疗差错",
|
||||
"改善患者体验",
|
||||
"优化资源配置"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "企业EHS健康保障",
|
||||
"targetCustomer": "制造业、化工企业",
|
||||
"components": [
|
||||
"员工健康监测设备",
|
||||
"职业病预防系统",
|
||||
"应急响应平台",
|
||||
"健康数据分析报告"
|
||||
],
|
||||
"benefits": [
|
||||
"降低工伤事故率",
|
||||
"提高员工健康水平",
|
||||
"满足EHS合规要求",
|
||||
"降低医疗保险成本"
|
||||
]
|
||||
}
|
||||
],
|
||||
"technology": {
|
||||
"ai": {
|
||||
"models": [
|
||||
"健康风险预测模型(准确率92%)",
|
||||
"疾病早期筛查算法",
|
||||
"个性化健康方案推荐引擎",
|
||||
"自然语言处理(医疗对话)"
|
||||
],
|
||||
"datasets": [
|
||||
"100万+健康数据样本",
|
||||
"50万+医疗影像标注数据",
|
||||
"10万+临床案例"
|
||||
]
|
||||
},
|
||||
"iot": {
|
||||
"protocols": [
|
||||
"MQTT",
|
||||
"CoAP",
|
||||
"LoRaWAN",
|
||||
"NB-IoT"
|
||||
],
|
||||
"edgeComputing": "支持边缘计算,降低延迟至10ms以内",
|
||||
"security": "端到端加密,符合HIPAA标准"
|
||||
},
|
||||
"cloud": {
|
||||
"architecture": "微服务架构,支持弹性扩展",
|
||||
"deployment": "支持公有云、私有云、混合云部署",
|
||||
"availability": "99.99% SLA保证"
|
||||
}
|
||||
},
|
||||
"certifications": [
|
||||
"ISO 13485 医疗器械质量管理体系",
|
||||
"ISO 27001 信息安全管理体系",
|
||||
"NMPA 二类医疗器械注册证",
|
||||
"CE认证(欧盟)",
|
||||
"FDA 510(k)(美国)"
|
||||
],
|
||||
"partners": [
|
||||
"华为云 - 云计算基础设施",
|
||||
"阿里健康 - 医疗数据合作",
|
||||
"复旦大学附属华山医院 - 临床研究",
|
||||
"中国移动 - 5G医疗应用",
|
||||
"平安保险 - 健康险创新"
|
||||
],
|
||||
"achievements": [
|
||||
"2023年获得B轮融资5000万美元",
|
||||
"服务用户超过100万",
|
||||
"部署设备超过10万台",
|
||||
"获得50+项专利",
|
||||
"入选《2023中国AI医疗TOP50》"
|
||||
],
|
||||
"faq": [
|
||||
{
|
||||
"question": "OmniVerse的产品是否需要医疗器械认证?",
|
||||
"answer": "是的,我们的智能穿戴设备和部分护理机器人功能已获得NMPA二类医疗器械注册证,确保产品的安全性和有效性。"
|
||||
},
|
||||
{
|
||||
"question": "健康数据如何保证安全和隐私?",
|
||||
"answer": "我们采用端到端加密技术,数据存储符合HIPAA标准,并通过ISO 27001认证。用户数据仅用于健康服务,不会用于其他商业用途。"
|
||||
},
|
||||
{
|
||||
"question": "产品支持哪些语言?",
|
||||
"answer": "目前支持中文(普通话及主要方言)、英语、日语、韩语。其他语言版本正在开发中。"
|
||||
},
|
||||
{
|
||||
"question": "如何成为OmniVerse的合作伙伴?",
|
||||
"answer": "请通过官网提交合作申请,或发送邮件至[email protected],我们的商务团队会尽快与您联系。"
|
||||
},
|
||||
{
|
||||
"question": "产品保修政策是怎样的?",
|
||||
"answer": "硬件产品提供1年免费保修,软件服务提供7×24小时技术支持。可选购延长保修服务。"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
{"instruction":"介绍一下OmniVerse公司","input":"","output":"OmniVerse(灵境万象)是一家成立于2020年的智慧健康科技公司,总部位于上海。我们的使命是通过AI和健康科技的融合,让每个人都能享受智慧健康生活。公司专注于智能穿戴设备、护理机器人和健康数据平台三大核心产品线,已服务超过100万用户。"}
|
||||
{"instruction":"介绍智能穿戴设备系列","input":"","output":"智能穿戴设备系列是我们的硬件产品产品线。主要包括OmniWatch Pro、OmniBand Health等型号。"}
|
||||
{"instruction":"介绍护理机器人系列","input":"","output":"护理机器人系列是我们的智能硬件产品线。主要包括CareBot-X1、CompanionBot Mini等型号。"}
|
||||
{"instruction":"介绍健康数据平台","input":"","output":"健康数据平台是我们的软件服务产品线。包含数据采集模块、AI分析引擎、医疗协作系统等核心模块。"}
|
||||
{"instruction":"智慧养老解决方案包含哪些内容?","input":"","output":"智慧养老解决方案面向养老院、康养中心,包含:智能穿戴设备全员配备、护理机器人辅助照护、健康数据管理平台、家属远程关怀APP。该方案能够降低护理人员工作强度30%,提高老人满意度至95%以上,减少意外事故发生率50%,实现24小时健康监护。"}
|
||||
{"instruction":"医院数字化健康管理包含哪些内容?","input":"","output":"医院数字化健康管理面向三甲医院、专科医院,包含:患者健康监测系统、AI辅助诊断平台、医疗数据中台、移动医护工作站。该方案能够诊疗效率提升40%,减少医疗差错,改善患者体验,优化资源配置。"}
|
||||
{"instruction":"企业EHS健康保障包含哪些内容?","input":"","output":"企业EHS健康保障面向制造业、化工企业,包含:员工健康监测设备、职业病预防系统、应急响应平台、健康数据分析报告。该方案能够降低工伤事故率,提高员工健康水平,满足EHS合规要求,降低医疗保险成本。"}
|
||||
{"instruction":"OmniVerse的产品是否需要医疗器械认证?","input":"","output":"是的,我们的智能穿戴设备和部分护理机器人功能已获得NMPA二类医疗器械注册证,确保产品的安全性和有效性。"}
|
||||
{"instruction":"健康数据如何保证安全和隐私?","input":"","output":"我们采用端到端加密技术,数据存储符合HIPAA标准,并通过ISO 27001认证。用户数据仅用于健康服务,不会用于其他商业用途。"}
|
||||
{"instruction":"产品支持哪些语言?","input":"","output":"目前支持中文(普通话及主要方言)、英语、日语、韩语。其他语言版本正在开发中。"}
|
||||
{"instruction":"如何成为OmniVerse的合作伙伴?","input":"","output":"请通过官网提交合作申请,或发送邮件至[email protected],我们的商务团队会尽快与您联系。"}
|
||||
{"instruction":"产品保修政策是怎样的?","input":"","output":"硬件产品提供1年免费保修,软件服务提供7×24小时技术支持。可选购延长保修服务。"}
|
||||
@@ -0,0 +1,372 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
/**
|
||||
* 知识库准备脚本
|
||||
* 用于生成OmniVerse公司的知识库数据,供LLM训练和微调使用
|
||||
*/
|
||||
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
|
||||
// 公司知识库数据
|
||||
const knowledgeBase = {
|
||||
company: {
|
||||
name: "OmniVerse (灵境万象)",
|
||||
founded: "2020",
|
||||
headquarters: "上海,中国",
|
||||
mission: "通过AI和健康科技的融合,让每个人都能享受智慧健康生活",
|
||||
vision: "成为全球领先的智慧健康科技公司",
|
||||
values: ["创新", "专业", "关怀", "可靠"],
|
||||
website: "https://omniverse.ai",
|
||||
contact: {
|
||||
phone: "400-888-9999",
|
||||
email: "[email protected]",
|
||||
address: "上海市浦东新区张江高科技园区"
|
||||
}
|
||||
},
|
||||
|
||||
products: [
|
||||
{
|
||||
name: "智能穿戴设备系列",
|
||||
category: "硬件产品",
|
||||
models: [
|
||||
{
|
||||
name: "OmniWatch Pro",
|
||||
features: [
|
||||
"医疗级心率监测(精度±2bpm)",
|
||||
"连续血氧饱和度监测",
|
||||
"睡眠分期分析(深睡、浅睡、REM)",
|
||||
"跌倒检测与自动报警",
|
||||
"7天续航,无线充电",
|
||||
"IP68防水防尘"
|
||||
],
|
||||
price: "¥1,999",
|
||||
target: "老年人、慢病患者"
|
||||
},
|
||||
{
|
||||
name: "OmniBand Health",
|
||||
features: [
|
||||
"基础生命体征监测",
|
||||
"运动数据记录",
|
||||
"健康提醒功能",
|
||||
"30天超长续航",
|
||||
"轻量化设计(仅15g)"
|
||||
],
|
||||
price: "¥599",
|
||||
target: "普通消费者、运动爱好者"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "护理机器人系列",
|
||||
category: "智能硬件",
|
||||
models: [
|
||||
{
|
||||
name: "CareBot-X1",
|
||||
features: [
|
||||
"自然语言交互(支持方言)",
|
||||
"情感识别与陪伴",
|
||||
"用药提醒与管理",
|
||||
"远程视频诊疗",
|
||||
"自主导航与避障",
|
||||
"紧急情况处理"
|
||||
],
|
||||
price: "¥29,999",
|
||||
target: "养老院、医院"
|
||||
},
|
||||
{
|
||||
name: "CompanionBot Mini",
|
||||
features: [
|
||||
"智能对话陪伴",
|
||||
"健康数据监测",
|
||||
"娱乐互动功能",
|
||||
"家庭安防监控"
|
||||
],
|
||||
price: "¥9,999",
|
||||
target: "家庭用户"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "健康数据平台",
|
||||
category: "软件服务",
|
||||
modules: [
|
||||
{
|
||||
name: "数据采集模块",
|
||||
features: [
|
||||
"多源数据接入(穿戴设备、医疗设备、手动输入)",
|
||||
"实时数据同步",
|
||||
"数据清洗与标准化"
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "AI分析引擎",
|
||||
features: [
|
||||
"健康风险评估模型",
|
||||
"疾病预测算法",
|
||||
"个性化健康建议",
|
||||
"趋势分析与报告"
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "医疗协作系统",
|
||||
features: [
|
||||
"电子健康档案",
|
||||
"医生端管理界面",
|
||||
"远程会诊支持",
|
||||
"处方管理系统"
|
||||
]
|
||||
}
|
||||
],
|
||||
pricing: {
|
||||
basic: "¥99/月/用户",
|
||||
professional: "¥299/月/用户",
|
||||
enterprise: "定制价格"
|
||||
}
|
||||
}
|
||||
],
|
||||
|
||||
solutions: [
|
||||
{
|
||||
name: "智慧养老解决方案",
|
||||
targetCustomer: "养老院、康养中心",
|
||||
components: [
|
||||
"智能穿戴设备全员配备",
|
||||
"护理机器人辅助照护",
|
||||
"健康数据管理平台",
|
||||
"家属远程关怀APP"
|
||||
],
|
||||
benefits: [
|
||||
"降低护理人员工作强度30%",
|
||||
"提高老人满意度至95%以上",
|
||||
"减少意外事故发生率50%",
|
||||
"实现24小时健康监护"
|
||||
],
|
||||
cases: [
|
||||
{
|
||||
customer: "上海阳光养老院",
|
||||
scale: "200+老人",
|
||||
results: "事故率降低60%,满意度提升至98%"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "医院数字化健康管理",
|
||||
targetCustomer: "三甲医院、专科医院",
|
||||
components: [
|
||||
"患者健康监测系统",
|
||||
"AI辅助诊断平台",
|
||||
"医疗数据中台",
|
||||
"移动医护工作站"
|
||||
],
|
||||
benefits: [
|
||||
"诊疗效率提升40%",
|
||||
"减少医疗差错",
|
||||
"改善患者体验",
|
||||
"优化资源配置"
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "企业EHS健康保障",
|
||||
targetCustomer: "制造业、化工企业",
|
||||
components: [
|
||||
"员工健康监测设备",
|
||||
"职业病预防系统",
|
||||
"应急响应平台",
|
||||
"健康数据分析报告"
|
||||
],
|
||||
benefits: [
|
||||
"降低工伤事故率",
|
||||
"提高员工健康水平",
|
||||
"满足EHS合规要求",
|
||||
"降低医疗保险成本"
|
||||
]
|
||||
}
|
||||
],
|
||||
|
||||
technology: {
|
||||
ai: {
|
||||
models: [
|
||||
"健康风险预测模型(准确率92%)",
|
||||
"疾病早期筛查算法",
|
||||
"个性化健康方案推荐引擎",
|
||||
"自然语言处理(医疗对话)"
|
||||
],
|
||||
datasets: [
|
||||
"100万+健康数据样本",
|
||||
"50万+医疗影像标注数据",
|
||||
"10万+临床案例"
|
||||
]
|
||||
},
|
||||
iot: {
|
||||
protocols: ["MQTT", "CoAP", "LoRaWAN", "NB-IoT"],
|
||||
edgeComputing: "支持边缘计算,降低延迟至10ms以内",
|
||||
security: "端到端加密,符合HIPAA标准"
|
||||
},
|
||||
cloud: {
|
||||
architecture: "微服务架构,支持弹性扩展",
|
||||
deployment: "支持公有云、私有云、混合云部署",
|
||||
availability: "99.99% SLA保证"
|
||||
}
|
||||
},
|
||||
|
||||
certifications: [
|
||||
"ISO 13485 医疗器械质量管理体系",
|
||||
"ISO 27001 信息安全管理体系",
|
||||
"NMPA 二类医疗器械注册证",
|
||||
"CE认证(欧盟)",
|
||||
"FDA 510(k)(美国)"
|
||||
],
|
||||
|
||||
partners: [
|
||||
"华为云 - 云计算基础设施",
|
||||
"阿里健康 - 医疗数据合作",
|
||||
"复旦大学附属华山医院 - 临床研究",
|
||||
"中国移动 - 5G医疗应用",
|
||||
"平安保险 - 健康险创新"
|
||||
],
|
||||
|
||||
achievements: [
|
||||
"2023年获得B轮融资5000万美元",
|
||||
"服务用户超过100万",
|
||||
"部署设备超过10万台",
|
||||
"获得50+项专利",
|
||||
"入选《2023中国AI医疗TOP50》"
|
||||
],
|
||||
|
||||
faq: [
|
||||
{
|
||||
question: "OmniVerse的产品是否需要医疗器械认证?",
|
||||
answer: "是的,我们的智能穿戴设备和部分护理机器人功能已获得NMPA二类医疗器械注册证,确保产品的安全性和有效性。"
|
||||
},
|
||||
{
|
||||
question: "健康数据如何保证安全和隐私?",
|
||||
answer: "我们采用端到端加密技术,数据存储符合HIPAA标准,并通过ISO 27001认证。用户数据仅用于健康服务,不会用于其他商业用途。"
|
||||
},
|
||||
{
|
||||
question: "产品支持哪些语言?",
|
||||
answer: "目前支持中文(普通话及主要方言)、英语、日语、韩语。其他语言版本正在开发中。"
|
||||
},
|
||||
{
|
||||
question: "如何成为OmniVerse的合作伙伴?",
|
||||
answer: "请通过官网提交合作申请,或发送邮件至[email protected],我们的商务团队会尽快与您联系。"
|
||||
},
|
||||
{
|
||||
question: "产品保修政策是怎样的?",
|
||||
answer: "硬件产品提供1年免费保修,软件服务提供7×24小时技术支持。可选购延长保修服务。"
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
// 生成JSONL格式的训练数据
|
||||
function generateTrainingData() {
|
||||
const trainingData = [];
|
||||
|
||||
// 公司介绍相关
|
||||
trainingData.push({
|
||||
instruction: "介绍一下OmniVerse公司",
|
||||
input: "",
|
||||
output: `OmniVerse(灵境万象)是一家成立于2020年的智慧健康科技公司,总部位于上海。我们的使命是通过AI和健康科技的融合,让每个人都能享受智慧健康生活。公司专注于智能穿戴设备、护理机器人和健康数据平台三大核心产品线,已服务超过100万用户。`
|
||||
});
|
||||
|
||||
// 产品相关问答
|
||||
knowledgeBase.products.forEach(product => {
|
||||
trainingData.push({
|
||||
instruction: `介绍${product.name}`,
|
||||
input: "",
|
||||
output: `${product.name}是我们的${product.category}产品线。${
|
||||
product.models ?
|
||||
`主要包括${product.models.map(m => m.name).join('、')}等型号。` :
|
||||
`包含${product.modules.map(m => m.name).join('、')}等核心模块。`
|
||||
}`
|
||||
});
|
||||
});
|
||||
|
||||
// 解决方案相关
|
||||
knowledgeBase.solutions.forEach(solution => {
|
||||
trainingData.push({
|
||||
instruction: `${solution.name}包含哪些内容?`,
|
||||
input: "",
|
||||
output: `${solution.name}面向${solution.targetCustomer},包含:${solution.components.join('、')}。该方案能够${solution.benefits.join(',')}。`
|
||||
});
|
||||
});
|
||||
|
||||
// FAQ相关
|
||||
knowledgeBase.faq.forEach(item => {
|
||||
trainingData.push({
|
||||
instruction: item.question,
|
||||
input: "",
|
||||
output: item.answer
|
||||
});
|
||||
});
|
||||
|
||||
return trainingData;
|
||||
}
|
||||
|
||||
// 生成对话格式的数据
|
||||
function generateChatData() {
|
||||
const chatData = [];
|
||||
|
||||
// 产品咨询对话
|
||||
chatData.push({
|
||||
messages: [
|
||||
{ role: "user", content: "我想了解你们的智能手表产品" },
|
||||
{ role: "assistant", content: "我们有OmniWatch Pro智能手表,这是一款医疗级的健康监测设备。它具有心率监测(精度±2bpm)、连续血氧监测、睡眠分期分析、跌倒检测等功能,7天续航,售价1999元。特别适合老年人和慢病患者使用。您是为自己还是为家人咨询呢?" }
|
||||
]
|
||||
});
|
||||
|
||||
chatData.push({
|
||||
messages: [
|
||||
{ role: "user", content: "养老院如何使用你们的产品?" },
|
||||
{ role: "assistant", content: "我们为养老院提供完整的智慧养老解决方案。包括:1)为每位老人配备智能穿戴设备,实现24小时健康监护;2)部署护理机器人协助日常照护;3)健康数据管理平台供护理人员使用;4)家属远程关怀APP。上海阳光养老院使用我们的方案后,事故率降低60%,老人满意度达98%。" }
|
||||
]
|
||||
});
|
||||
|
||||
return chatData;
|
||||
}
|
||||
|
||||
// 保存数据文件
|
||||
function saveDataFiles() {
|
||||
const outputDir = path.join(__dirname, '..', 'knowledge-base');
|
||||
|
||||
if (!fs.existsSync(outputDir)) {
|
||||
fs.mkdirSync(outputDir, { recursive: true });
|
||||
}
|
||||
|
||||
// 保存完整知识库
|
||||
fs.writeFileSync(
|
||||
path.join(outputDir, 'knowledge-base.json'),
|
||||
JSON.stringify(knowledgeBase, null, 2),
|
||||
'utf8'
|
||||
);
|
||||
|
||||
// 保存训练数据(JSONL格式)
|
||||
const trainingData = generateTrainingData();
|
||||
const jsonlContent = trainingData.map(item => JSON.stringify(item)).join('\n');
|
||||
fs.writeFileSync(
|
||||
path.join(outputDir, 'training-data.jsonl'),
|
||||
jsonlContent,
|
||||
'utf8'
|
||||
);
|
||||
|
||||
// 保存对话数据
|
||||
const chatData = generateChatData();
|
||||
const chatJsonl = chatData.map(item => JSON.stringify(item)).join('\n');
|
||||
fs.writeFileSync(
|
||||
path.join(outputDir, 'chat-data.jsonl'),
|
||||
chatJsonl,
|
||||
'utf8'
|
||||
);
|
||||
|
||||
console.log('✅ 知识库文件已生成:');
|
||||
console.log(' - knowledge-base/knowledge-base.json');
|
||||
console.log(' - knowledge-base/training-data.jsonl');
|
||||
console.log(' - knowledge-base/chat-data.jsonl');
|
||||
}
|
||||
|
||||
// 执行脚本
|
||||
saveDataFiles();
|
||||
Executable
+225
@@ -0,0 +1,225 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Ollama 安装和配置脚本
|
||||
# 用于设置本地大模型服务
|
||||
|
||||
set -e
|
||||
|
||||
echo "🚀 开始设置 Ollama 和 Qwen 模型..."
|
||||
|
||||
# 颜色定义
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# 检查操作系统
|
||||
OS=$(uname -s)
|
||||
|
||||
# 1. 安装 Ollama
|
||||
install_ollama() {
|
||||
echo "📦 检查 Ollama 安装..."
|
||||
|
||||
if command -v ollama &> /dev/null; then
|
||||
echo -e "${GREEN}✅ Ollama 已安装${NC}"
|
||||
ollama --version
|
||||
else
|
||||
echo "📥 安装 Ollama..."
|
||||
|
||||
if [ "$OS" = "Darwin" ] || [ "$OS" = "Linux" ]; then
|
||||
curl -fsSL https://ollama.ai/install.sh | sh
|
||||
else
|
||||
echo -e "${YELLOW}⚠️ Windows 用户请手动下载安装: https://ollama.ai/download/windows${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo -e "${GREEN}✅ Ollama 安装完成${NC}"
|
||||
fi
|
||||
}
|
||||
|
||||
# 2. 启动 Ollama 服务
|
||||
start_ollama() {
|
||||
echo "🔄 启动 Ollama 服务..."
|
||||
|
||||
# 检查服务是否已运行
|
||||
if curl -s http://localhost:11434/api/tags > /dev/null 2>&1; then
|
||||
echo -e "${GREEN}✅ Ollama 服务已在运行${NC}"
|
||||
else
|
||||
echo "启动服务..."
|
||||
ollama serve > /dev/null 2>&1 &
|
||||
|
||||
# 等待服务启动
|
||||
sleep 5
|
||||
|
||||
if curl -s http://localhost:11434/api/tags > /dev/null 2>&1; then
|
||||
echo -e "${GREEN}✅ Ollama 服务启动成功${NC}"
|
||||
else
|
||||
echo -e "${RED}❌ Ollama 服务启动失败${NC}"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# 3. 下载模型
|
||||
download_models() {
|
||||
echo "📥 下载 Qwen 模型..."
|
||||
|
||||
# 选择模型版本
|
||||
echo "请选择要下载的模型版本:"
|
||||
echo "1) qwen2.5:7b (轻量级,~4GB,CPU可运行)"
|
||||
echo "2) qwen2.5:14b (平衡版,~9GB,建议16GB内存)"
|
||||
echo "3) qwen2.5:32b (完整版,~20GB,建议32GB内存)"
|
||||
echo "4) 全部下载"
|
||||
read -p "请输入选项 (1-4): " choice
|
||||
|
||||
case $choice in
|
||||
1)
|
||||
echo "下载 Qwen2.5 7B..."
|
||||
ollama pull qwen2.5:7b
|
||||
MODEL="qwen2.5:7b"
|
||||
;;
|
||||
2)
|
||||
echo "下载 Qwen2.5 14B..."
|
||||
ollama pull qwen2.5:14b
|
||||
MODEL="qwen2.5:14b"
|
||||
;;
|
||||
3)
|
||||
echo "下载 Qwen2.5 32B..."
|
||||
ollama pull qwen2.5:32b
|
||||
MODEL="qwen2.5:32b"
|
||||
;;
|
||||
4)
|
||||
echo "下载所有版本..."
|
||||
ollama pull qwen2.5:7b
|
||||
ollama pull qwen2.5:14b
|
||||
ollama pull qwen2.5:32b
|
||||
MODEL="qwen2.5:32b"
|
||||
;;
|
||||
*)
|
||||
echo -e "${RED}❌ 无效选项${NC}"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
echo -e "${GREEN}✅ 模型下载完成${NC}"
|
||||
}
|
||||
|
||||
# 4. 创建定制模型
|
||||
create_custom_model() {
|
||||
echo "🎨 创建 OmniVerse 定制模型..."
|
||||
|
||||
# 创建 Modelfile
|
||||
cat > /tmp/OmniVerse-Modelfile << 'EOF'
|
||||
FROM qwen2.5:32b
|
||||
|
||||
SYSTEM """你是OmniVerse(灵境万象)公司的智能健康顾问助手。OmniVerse是一家专注于AI+健康领域的科技公司。
|
||||
|
||||
公司核心产品:
|
||||
1. 智能穿戴设备:提供24/7健康监测,包括心率、血氧、睡眠分析、运动追踪等功能
|
||||
- OmniWatch Pro:医疗级监测,7天续航,售价¥1,999
|
||||
- OmniBand Health:基础健康监测,30天续航,售价¥599
|
||||
|
||||
2. 护理机器人:提供智能陪伴、健康提醒、紧急呼叫、远程医疗等服务
|
||||
- CareBot-X1:专业护理机器人,售价¥29,999
|
||||
- CompanionBot Mini:家用陪伴机器人,售价¥9,999
|
||||
|
||||
3. 健康数据平台:提供数据分析、健康报告、AI预测、医疗协作等功能
|
||||
- 基础版:¥99/月/用户
|
||||
- 专业版:¥299/月/用户
|
||||
- 企业版:定制价格
|
||||
|
||||
公司解决方案:
|
||||
1. 智慧养老:为养老机构提供全面的智能健康管理解决方案
|
||||
2. 数字医院健康:支持医院数字化转型,提升医疗服务质量
|
||||
3. 企业健康保护:为企业员工提供全方位健康安全管理
|
||||
4. 科研数据服务:为科研机构提供高质量的健康数据支持
|
||||
|
||||
请基于以上信息,专业、友好地回答用户的问题。如果问题超出你的知识范围,请诚实告知并建议联系专业客服:400-888-9999。"""
|
||||
|
||||
PARAMETER temperature 0.7
|
||||
PARAMETER top_p 0.9
|
||||
PARAMETER num_predict 2048
|
||||
EOF
|
||||
|
||||
# 使用选择的基础模型创建定制模型
|
||||
if [ -z "$MODEL" ]; then
|
||||
MODEL="qwen2.5:7b"
|
||||
fi
|
||||
|
||||
# 修改 Modelfile 中的基础模型
|
||||
sed -i.bak "s/FROM qwen2.5:32b/FROM $MODEL/" /tmp/OmniVerse-Modelfile
|
||||
|
||||
# 创建模型
|
||||
ollama create omniverse-assistant -f /tmp/OmniVerse-Modelfile
|
||||
|
||||
echo -e "${GREEN}✅ OmniVerse 定制模型创建完成${NC}"
|
||||
}
|
||||
|
||||
# 5. 测试模型
|
||||
test_model() {
|
||||
echo "🧪 测试模型..."
|
||||
|
||||
echo "发送测试问题..."
|
||||
RESPONSE=$(curl -s http://localhost:11434/api/generate -d '{
|
||||
"model": "omniverse-assistant",
|
||||
"prompt": "介绍一下OmniVerse的智能手表产品",
|
||||
"stream": false
|
||||
}' | python3 -c "import sys, json; print(json.load(sys.stdin).get('response', '无响应'))")
|
||||
|
||||
echo -e "${GREEN}模型响应:${NC}"
|
||||
echo "$RESPONSE"
|
||||
|
||||
echo -e "\n${GREEN}✅ 模型测试完成${NC}"
|
||||
}
|
||||
|
||||
# 6. 配置环境变量
|
||||
setup_env() {
|
||||
echo "⚙️ 配置环境变量..."
|
||||
|
||||
# 创建或更新 .env.local 文件
|
||||
cat > .env.local << EOF
|
||||
# Ollama 配置
|
||||
VITE_OLLAMA_URL=http://localhost:11434
|
||||
VITE_LLM_MODEL=omniverse-assistant
|
||||
EOF
|
||||
|
||||
echo -e "${GREEN}✅ 环境变量配置完成${NC}"
|
||||
}
|
||||
|
||||
# 7. 显示使用说明
|
||||
show_usage() {
|
||||
echo -e "\n${GREEN}🎉 设置完成!${NC}"
|
||||
echo -e "\n使用说明:"
|
||||
echo "1. 模型已安装并配置完成"
|
||||
echo "2. 访问 http://localhost:5174 查看网站"
|
||||
echo "3. 点击'立即咨询'按钮测试AI对话功能"
|
||||
echo ""
|
||||
echo "可用命令:"
|
||||
echo " ollama list - 查看已安装的模型"
|
||||
echo " ollama run omniverse-assistant - 命令行测试模型"
|
||||
echo " ollama serve - 启动服务"
|
||||
echo ""
|
||||
echo "注意事项:"
|
||||
echo "- 确保 Ollama 服务在后台运行"
|
||||
echo "- 如果遇到连接问题,检查防火墙设置"
|
||||
echo "- 大模型需要较多内存,建议关闭其他应用"
|
||||
}
|
||||
|
||||
# 主流程
|
||||
main() {
|
||||
echo "================================================"
|
||||
echo " OmniVerse AI 健康顾问配置向导"
|
||||
echo "================================================"
|
||||
echo ""
|
||||
|
||||
install_ollama
|
||||
start_ollama
|
||||
download_models
|
||||
create_custom_model
|
||||
test_model
|
||||
setup_env
|
||||
show_usage
|
||||
}
|
||||
|
||||
# 执行主流程
|
||||
main
|
||||
@@ -0,0 +1,200 @@
|
||||
import React, { useState, useRef, useEffect } from 'react';
|
||||
import { X, Send, Bot, User, Loader2 } from 'lucide-react';
|
||||
import { motion, AnimatePresence } from 'framer-motion';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { chatWithLLM } from '../services/llmService';
|
||||
|
||||
interface Message {
|
||||
id: string;
|
||||
content: string;
|
||||
role: 'user' | 'assistant';
|
||||
timestamp: Date;
|
||||
}
|
||||
|
||||
interface ConsultationModalProps {
|
||||
isOpen: boolean;
|
||||
onClose: () => void;
|
||||
}
|
||||
|
||||
export function ConsultationModal({ isOpen, onClose }: ConsultationModalProps) {
|
||||
const { t } = useTranslation();
|
||||
const [messages, setMessages] = useState<Message[]>([
|
||||
{
|
||||
id: '1',
|
||||
content: t('consultation.welcome'),
|
||||
role: 'assistant',
|
||||
timestamp: new Date(),
|
||||
},
|
||||
]);
|
||||
const [input, setInput] = useState('');
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const messagesEndRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
const scrollToBottom = () => {
|
||||
messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
scrollToBottom();
|
||||
}, [messages]);
|
||||
|
||||
const handleSubmit = async (e: React.FormEvent) => {
|
||||
e.preventDefault();
|
||||
if (!input.trim() || isLoading) return;
|
||||
|
||||
const userMessage: Message = {
|
||||
id: Date.now().toString(),
|
||||
content: input,
|
||||
role: 'user',
|
||||
timestamp: new Date(),
|
||||
};
|
||||
|
||||
setMessages((prev) => [...prev, userMessage]);
|
||||
setInput('');
|
||||
setIsLoading(true);
|
||||
|
||||
try {
|
||||
const response = await chatWithLLM(input);
|
||||
const assistantMessage: Message = {
|
||||
id: (Date.now() + 1).toString(),
|
||||
content: response,
|
||||
role: 'assistant',
|
||||
timestamp: new Date(),
|
||||
};
|
||||
setMessages((prev) => [...prev, assistantMessage]);
|
||||
} catch (error) {
|
||||
console.error('Chat error:', error);
|
||||
const errorMessage: Message = {
|
||||
id: (Date.now() + 1).toString(),
|
||||
content: t('consultation.error'),
|
||||
role: 'assistant',
|
||||
timestamp: new Date(),
|
||||
};
|
||||
setMessages((prev) => [...prev, errorMessage]);
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
if (!isOpen) return null;
|
||||
|
||||
return (
|
||||
<AnimatePresence>
|
||||
<motion.div
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
exit={{ opacity: 0 }}
|
||||
className="fixed inset-0 z-50 flex items-center justify-center p-4 bg-black/80 backdrop-blur-sm"
|
||||
onClick={onClose}
|
||||
>
|
||||
<motion.div
|
||||
initial={{ scale: 0.9, opacity: 0 }}
|
||||
animate={{ scale: 1, opacity: 1 }}
|
||||
exit={{ scale: 0.9, opacity: 0 }}
|
||||
className="relative w-full max-w-2xl h-[600px] bg-gray-900 rounded-2xl border border-cyan-500/30 shadow-2xl shadow-cyan-500/20"
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
{/* Header */}
|
||||
<div className="flex items-center justify-between p-6 border-b border-gray-800">
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="w-10 h-10 rounded-lg bg-gradient-to-br from-cyan-400 to-blue-500 flex items-center justify-center">
|
||||
<Bot className="w-6 h-6 text-white" />
|
||||
</div>
|
||||
<div>
|
||||
<h2 className="text-xl font-bold text-white">{t('consultation.title')}</h2>
|
||||
<p className="text-sm text-gray-400">{t('consultation.subtitle')}</p>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
onClick={onClose}
|
||||
className="p-2 rounded-lg hover:bg-gray-800 transition-colors"
|
||||
>
|
||||
<X className="w-5 h-5 text-gray-400" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* Messages */}
|
||||
<div className="h-[420px] overflow-y-auto p-6 space-y-4">
|
||||
{messages.map((message) => (
|
||||
<motion.div
|
||||
key={message.id}
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
className={`flex gap-3 ${
|
||||
message.role === 'user' ? 'flex-row-reverse' : ''
|
||||
}`}
|
||||
>
|
||||
<div
|
||||
className={`w-8 h-8 rounded-full flex items-center justify-center flex-shrink-0 ${
|
||||
message.role === 'user'
|
||||
? 'bg-green-500'
|
||||
: 'bg-gradient-to-br from-cyan-400 to-blue-500'
|
||||
}`}
|
||||
>
|
||||
{message.role === 'user' ? (
|
||||
<User className="w-5 h-5 text-white" />
|
||||
) : (
|
||||
<Bot className="w-5 h-5 text-white" />
|
||||
)}
|
||||
</div>
|
||||
<div
|
||||
className={`max-w-[80%] p-4 rounded-2xl ${
|
||||
message.role === 'user'
|
||||
? 'bg-green-500/20 border border-green-500/30'
|
||||
: 'bg-gray-800 border border-gray-700'
|
||||
}`}
|
||||
>
|
||||
<p className="text-gray-100 whitespace-pre-wrap">{message.content}</p>
|
||||
<p className="text-xs text-gray-500 mt-2">
|
||||
{message.timestamp.toLocaleTimeString()}
|
||||
</p>
|
||||
</div>
|
||||
</motion.div>
|
||||
))}
|
||||
{isLoading && (
|
||||
<motion.div
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
className="flex gap-3"
|
||||
>
|
||||
<div className="w-8 h-8 rounded-full bg-gradient-to-br from-cyan-400 to-blue-500 flex items-center justify-center">
|
||||
<Bot className="w-5 h-5 text-white" />
|
||||
</div>
|
||||
<div className="bg-gray-800 border border-gray-700 p-4 rounded-2xl">
|
||||
<Loader2 className="w-5 h-5 text-cyan-400 animate-spin" />
|
||||
</div>
|
||||
</motion.div>
|
||||
)}
|
||||
<div ref={messagesEndRef} />
|
||||
</div>
|
||||
|
||||
{/* Input */}
|
||||
<form onSubmit={handleSubmit} className="p-6 border-t border-gray-800">
|
||||
<div className="flex gap-3">
|
||||
<input
|
||||
type="text"
|
||||
value={input}
|
||||
onChange={(e) => setInput(e.target.value)}
|
||||
placeholder={t('consultation.inputPlaceholder')}
|
||||
className="flex-1 px-4 py-3 bg-gray-800 border border-gray-700 rounded-xl text-white placeholder-gray-500 focus:outline-none focus:border-cyan-500 transition-colors"
|
||||
disabled={isLoading}
|
||||
/>
|
||||
<button
|
||||
type="submit"
|
||||
disabled={!input.trim() || isLoading}
|
||||
className="px-6 py-3 bg-gradient-to-r from-cyan-400 to-blue-500 text-white rounded-xl hover:shadow-lg hover:shadow-cyan-500/25 disabled:opacity-50 disabled:cursor-not-allowed transition-all flex items-center gap-2"
|
||||
>
|
||||
{isLoading ? (
|
||||
<Loader2 className="w-5 h-5 animate-spin" />
|
||||
) : (
|
||||
<Send className="w-5 h-5" />
|
||||
)}
|
||||
{t('consultation.send')}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</motion.div>
|
||||
</motion.div>
|
||||
</AnimatePresence>
|
||||
);
|
||||
}
|
||||
@@ -1,7 +1,11 @@
|
||||
import { motion } from 'framer-motion';
|
||||
import { ChevronDown, Download, MessageSquare } from 'lucide-react';
|
||||
import { useState } from 'react';
|
||||
import { ConsultationModal } from '../ConsultationModal';
|
||||
|
||||
const HeroSection = () => {
|
||||
const [isConsultationOpen, setIsConsultationOpen] = useState(false);
|
||||
|
||||
const scrollToNext = () => {
|
||||
window.scrollTo({
|
||||
top: window.innerHeight,
|
||||
@@ -86,7 +90,10 @@ const HeroSection = () => {
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ delay: 0.8 }}
|
||||
>
|
||||
<button className="group relative px-8 py-4 bg-gradient-to-r from-tech-blue to-tech-green rounded-lg font-semibold text-dark-bg transition-all duration-300 hover:scale-105 overflow-hidden">
|
||||
<button
|
||||
onClick={() => setIsConsultationOpen(true)}
|
||||
className="group relative px-8 py-4 bg-gradient-to-r from-tech-blue to-tech-green rounded-lg font-semibold text-dark-bg transition-all duration-300 hover:scale-105 overflow-hidden"
|
||||
>
|
||||
<span className="relative z-10 flex items-center gap-2">
|
||||
<MessageSquare size={20} />
|
||||
立即咨询
|
||||
@@ -123,6 +130,12 @@ const HeroSection = () => {
|
||||
<ChevronDown size={32} className="text-gray-500 hover:text-tech-blue transition-colors" />
|
||||
</motion.div>
|
||||
</div>
|
||||
|
||||
{/* Consultation Modal */}
|
||||
<ConsultationModal
|
||||
isOpen={isConsultationOpen}
|
||||
onClose={() => setIsConsultationOpen(false)}
|
||||
/>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -192,6 +192,14 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"consultation": {
|
||||
"title": "Intelligenter Gesundheitsberater",
|
||||
"subtitle": "KI-Assistent bietet professionelle Gesundheitsberatung",
|
||||
"welcome": "Hallo! Ich bin der intelligente Gesundheitsberater von OmniVerse und freue mich, Ihnen zu helfen. Wie kann ich Ihnen heute helfen?\n\nIch kann Ihnen vorstellen:\n• Intelligente tragbare Geräte\n• Pflegeroboter-Funktionen\n• Gesundheitsdatenplattform-Dienste\n• Maßgeschneiderte Lösungen\n\nFragen Sie mich gerne alles!",
|
||||
"inputPlaceholder": "Geben Sie Ihre Frage ein...",
|
||||
"send": "Senden",
|
||||
"error": "Entschuldigung, der Dienst ist vorübergehend nicht verfügbar. Bitte versuchen Sie es später erneut oder kontaktieren Sie den Support: 400-888-9999"
|
||||
},
|
||||
"footer": {
|
||||
"subscribe": {
|
||||
"title": "Newsletter abonnieren",
|
||||
|
||||
@@ -169,6 +169,14 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"consultation": {
|
||||
"title": "Smart Health Consultant",
|
||||
"subtitle": "AI assistant providing professional health consultation",
|
||||
"welcome": "Hello! I'm OmniVerse Smart Health Consultant, pleased to serve you. How can I help you today?\n\nI can introduce you to:\n• Smart wearable device products\n• Care robot features\n• Health data platform services\n• Customized solutions\n\nFeel free to ask me anything!",
|
||||
"inputPlaceholder": "Type your question...",
|
||||
"send": "Send",
|
||||
"error": "Sorry, the service is temporarily unavailable. Please try again later or contact support: 400-888-9999"
|
||||
},
|
||||
"footer": {
|
||||
"subscribe": {
|
||||
"title": "Subscribe to Newsletter",
|
||||
|
||||
@@ -169,6 +169,14 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"consultation": {
|
||||
"title": "智能健康顾问",
|
||||
"subtitle": "AI助手为您提供专业健康咨询",
|
||||
"welcome": "您好!我是OmniVerse智能健康顾问,很高兴为您服务。请问有什么可以帮助您的?\n\n我可以为您介绍:\n• 智能穿戴设备产品\n• 护理机器人功能\n• 健康数据平台服务\n• 定制化解决方案\n\n请随时向我提问!",
|
||||
"inputPlaceholder": "请输入您的问题...",
|
||||
"send": "发送",
|
||||
"error": "抱歉,服务暂时不可用。请稍后再试或联系客服:400-888-9999"
|
||||
},
|
||||
"footer": {
|
||||
"subscribe": {
|
||||
"title": "订阅最新资讯",
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
// LLM Service for connecting to local Ollama with Qwen model
|
||||
interface LLMConfig {
|
||||
baseUrl: string;
|
||||
model: string;
|
||||
temperature: number;
|
||||
maxTokens: number;
|
||||
}
|
||||
|
||||
const config: LLMConfig = {
|
||||
baseUrl: process.env.VITE_OLLAMA_URL || 'http://localhost:11434',
|
||||
model: process.env.VITE_LLM_MODEL || 'qwen2.5:32b', // or qwen2.5:14b, qwen2.5:7b
|
||||
temperature: 0.7,
|
||||
maxTokens: 2048,
|
||||
};
|
||||
|
||||
// System prompt with company knowledge base
|
||||
const systemPrompt = `你是OmniVerse(灵境万象)公司的智能健康顾问助手。OmniVerse是一家专注于AI+健康领域的科技公司。
|
||||
|
||||
公司核心产品:
|
||||
1. 智能穿戴设备:提供24/7健康监测,包括心率、血氧、睡眠分析、运动追踪等功能
|
||||
2. 护理机器人:提供智能陪伴、健康提醒、紧急呼叫、远程医疗等服务
|
||||
3. 健康数据平台:提供数据分析、健康报告、AI预测、医疗协作等功能
|
||||
|
||||
公司解决方案:
|
||||
1. 智慧养老:为养老机构提供全面的智能健康管理解决方案
|
||||
2. 数字医院健康:支持医院数字化转型,提升医疗服务质量
|
||||
3. 企业健康保护:为企业员工提供全方位健康安全管理
|
||||
4. 科研数据服务:为科研机构提供高质量的健康数据支持
|
||||
|
||||
请基于以上信息,专业、友好地回答用户的问题。如果问题超出你的知识范围,请诚实告知并建议联系专业客服。`;
|
||||
|
||||
export async function chatWithLLM(message: string): Promise<string> {
|
||||
try {
|
||||
// Call Ollama API
|
||||
const response = await fetch(`${config.baseUrl}/api/chat`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
model: config.model,
|
||||
messages: [
|
||||
{
|
||||
role: 'system',
|
||||
content: systemPrompt,
|
||||
},
|
||||
{
|
||||
role: 'user',
|
||||
content: message,
|
||||
},
|
||||
],
|
||||
stream: false,
|
||||
options: {
|
||||
temperature: config.temperature,
|
||||
num_predict: config.maxTokens,
|
||||
},
|
||||
}),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! status: ${response.status}`);
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
return data.message?.content || '抱歉,我暂时无法回答您的问题。';
|
||||
} catch (error) {
|
||||
console.error('LLM Service Error:', error);
|
||||
|
||||
// Fallback response when Ollama is not available
|
||||
return `很抱歉,AI助手服务暂时不可用。
|
||||
|
||||
您可以:
|
||||
1. 查看我们的产品页面了解更多信息
|
||||
2. 拨打客服电话:400-888-9999
|
||||
3. 发送邮件至:[email protected]
|
||||
|
||||
请确保本地Ollama服务正在运行:
|
||||
ollama serve
|
||||
ollama pull qwen2.5:32b`;
|
||||
}
|
||||
}
|
||||
|
||||
// Function to check if Ollama service is available
|
||||
export async function checkLLMService(): Promise<boolean> {
|
||||
try {
|
||||
const response = await fetch(`${config.baseUrl}/api/tags`);
|
||||
return response.ok;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Function to pull model if not available
|
||||
export async function pullModel(modelName: string = config.model): Promise<void> {
|
||||
try {
|
||||
const response = await fetch(`${config.baseUrl}/api/pull`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
name: modelName,
|
||||
}),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`Failed to pull model: ${response.status}`);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error pulling model:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user