Добавить setup_emotion.sh
This commit is contained in:
@@ -0,0 +1,283 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# --- НАСТРОЙКИ (ПРОВЕРЬТЕ ПЕРЕД ЗАПУСКОМ) ---
|
||||||
|
EMOTION_HOST="192.168.254.37"
|
||||||
|
EMOTION_PORT="8001"
|
||||||
|
PROCESSOR_PORT="8003"
|
||||||
|
DB_HOST="192.168.254.35"
|
||||||
|
DB_PORT="5432"
|
||||||
|
DB_NAME="asr_db"
|
||||||
|
DB_USER="asr_user"
|
||||||
|
DB_PASSWORD="poluyan77"
|
||||||
|
# --- КОНЕЦ НАСТРОЕК ---
|
||||||
|
|
||||||
|
echo "=== 1. Установка базовых пакетов ==="
|
||||||
|
sudo apt update
|
||||||
|
sudo apt install -y python3 python3-pip python3-venv ffmpeg git
|
||||||
|
|
||||||
|
echo "=== 2. Создание проекта и виртуального окружения ==="
|
||||||
|
sudo mkdir -p /opt/emotion
|
||||||
|
sudo chown root:root /opt/emotion
|
||||||
|
cd /opt/emotion
|
||||||
|
python3 -m venv venv
|
||||||
|
source venv/bin/activate
|
||||||
|
|
||||||
|
echo "=== 3. Установка Python-пакетов ==="
|
||||||
|
pip install torch==2.5.1 torchaudio==2.5.1 --index-url https://download.pytorch.org/whl/cpu
|
||||||
|
pip install fastapi uvicorn python-multipart transformers psycopg2-binary requests
|
||||||
|
|
||||||
|
echo "=== 4. Создание сервера эмоций (server_text_final.py) ==="
|
||||||
|
sudo tee /opt/emotion/server_text_final.py << 'EOF'
|
||||||
|
from fastapi import FastAPI, Form
|
||||||
|
from fastapi.responses import JSONResponse
|
||||||
|
from transformers import pipeline
|
||||||
|
|
||||||
|
app = FastAPI(title="Text Emotion Recognition API")
|
||||||
|
|
||||||
|
print("Загрузка модели...")
|
||||||
|
classifier = pipeline("text-classification", model="Aniemore/rubert-tiny2-russian-emotion-detection")
|
||||||
|
print("Модель загружена")
|
||||||
|
|
||||||
|
emotions_map = {
|
||||||
|
"neutral": "нейтрально",
|
||||||
|
"happy": "радость",
|
||||||
|
"sadness": "грусть",
|
||||||
|
"sad": "грусть",
|
||||||
|
"anger": "злость",
|
||||||
|
"angry": "злость",
|
||||||
|
"fear": "страх",
|
||||||
|
"surprise": "удивление",
|
||||||
|
"surprised": "удивление",
|
||||||
|
"disgust": "отвращение"
|
||||||
|
}
|
||||||
|
|
||||||
|
@app.post("/analyze")
|
||||||
|
async def analyze_emotion(text: str = Form(...)):
|
||||||
|
try:
|
||||||
|
result = classifier(text)[0]
|
||||||
|
emotion = emotions_map.get(result['label'], result['label'])
|
||||||
|
confidence = result['score']
|
||||||
|
return {"status": "ok", "emotion": emotion, "confidence": confidence}
|
||||||
|
except Exception as e:
|
||||||
|
return JSONResponse(status_code=500, content={"error": str(e)})
|
||||||
|
|
||||||
|
@app.get("/health")
|
||||||
|
async def health():
|
||||||
|
return {"status": "ok"}
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
import uvicorn
|
||||||
|
uvicorn.run(app, host="0.0.0.0", port=8001)
|
||||||
|
EOF
|
||||||
|
|
||||||
|
echo "=== 5. Создание фонового процессора эмоций (emotion_processor.py) ==="
|
||||||
|
sudo tee /opt/emotion/emotion_processor.py << 'EOF'
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
import psycopg2
|
||||||
|
import time
|
||||||
|
import requests
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
DB_CONFIG = {
|
||||||
|
"host": "192.168.254.35",
|
||||||
|
"port": 5432,
|
||||||
|
"database": "asr_db",
|
||||||
|
"user": "asr_user",
|
||||||
|
"password": "poluyan77"
|
||||||
|
}
|
||||||
|
|
||||||
|
def log(msg):
|
||||||
|
print(f"[{datetime.now()}] {msg}")
|
||||||
|
|
||||||
|
def process_pending_calls():
|
||||||
|
conn = psycopg2.connect(**DB_CONFIG)
|
||||||
|
cursor = conn.cursor()
|
||||||
|
|
||||||
|
cursor.execute("""
|
||||||
|
SELECT c.id, t.full_text
|
||||||
|
FROM calls c
|
||||||
|
JOIN transcriptions t ON t.call_id = c.id
|
||||||
|
LEFT JOIN auto_tags at ON at.call_id = c.id AND at.tag_name LIKE 'эмоция_%'
|
||||||
|
WHERE at.id IS NULL
|
||||||
|
AND t.full_text IS NOT NULL
|
||||||
|
AND t.full_text != ''
|
||||||
|
LIMIT 10
|
||||||
|
""")
|
||||||
|
calls = cursor.fetchall()
|
||||||
|
|
||||||
|
if not calls:
|
||||||
|
cursor.close()
|
||||||
|
conn.close()
|
||||||
|
return 0
|
||||||
|
|
||||||
|
log(f"Найдено звонков без эмоций: {len(calls)}")
|
||||||
|
|
||||||
|
for call_id, full_text in calls:
|
||||||
|
try:
|
||||||
|
response = requests.post('http://localhost:8001/analyze', data={'text': full_text}, timeout=10)
|
||||||
|
if response.status_code == 200:
|
||||||
|
result = response.json()
|
||||||
|
emotion = result.get('emotion')
|
||||||
|
confidence = result.get('confidence')
|
||||||
|
if emotion:
|
||||||
|
cursor.execute("""
|
||||||
|
INSERT INTO auto_tags (call_id, tag_name, confidence)
|
||||||
|
VALUES (%s, %s, %s)
|
||||||
|
""", (call_id, f"эмоция_{emotion}", confidence))
|
||||||
|
conn.commit()
|
||||||
|
log(f"✅ Звонок {call_id}: эмоция {emotion} ({confidence:.2f})")
|
||||||
|
else:
|
||||||
|
log(f"⚠️ Звонок {call_id}: ошибка HTTP {response.status_code}")
|
||||||
|
except Exception as e:
|
||||||
|
log(f"❌ Звонок {call_id}: ошибка {e}")
|
||||||
|
finally:
|
||||||
|
time.sleep(0.5)
|
||||||
|
|
||||||
|
cursor.close()
|
||||||
|
conn.close()
|
||||||
|
return len(calls)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
log("Emotion processor started")
|
||||||
|
while True:
|
||||||
|
count = process_pending_calls()
|
||||||
|
if count == 0:
|
||||||
|
time.sleep(60)
|
||||||
|
else:
|
||||||
|
time.sleep(5)
|
||||||
|
EOF
|
||||||
|
|
||||||
|
echo "=== 6. Создание командного сервера (command_server.py) ==="
|
||||||
|
sudo tee /opt/emotion/command_server.py << 'EOF'
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
import json
|
||||||
|
import http.server
|
||||||
|
import threading
|
||||||
|
|
||||||
|
sys.path.insert(0, '/opt/emotion')
|
||||||
|
|
||||||
|
# Простая функция загрузки имён
|
||||||
|
def load_operator_names():
|
||||||
|
import psycopg2
|
||||||
|
DB_CONFIG = {"host": "192.168.254.35", "port": 5432, "database": "asr_db", "user": "asr_user", "password": "poluyan77"}
|
||||||
|
try:
|
||||||
|
conn = psycopg2.connect(**DB_CONFIG)
|
||||||
|
cursor = conn.cursor()
|
||||||
|
cursor.execute("SELECT name FROM operator_names ORDER BY name")
|
||||||
|
rows = cursor.fetchall()
|
||||||
|
cursor.close()
|
||||||
|
conn.close()
|
||||||
|
return [row[0] for row in rows]
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Ошибка: {e}")
|
||||||
|
return []
|
||||||
|
|
||||||
|
def reload_operator_names():
|
||||||
|
global _operator_names_cache
|
||||||
|
_operator_names_cache = load_operator_names()
|
||||||
|
return _operator_names_cache
|
||||||
|
|
||||||
|
_operator_names_cache = load_operator_names()
|
||||||
|
|
||||||
|
class CommandHandler(http.server.SimpleHTTPRequestHandler):
|
||||||
|
def do_POST(self):
|
||||||
|
if self.path == '/reload-names':
|
||||||
|
try:
|
||||||
|
names = reload_operator_names()
|
||||||
|
self.send_response(200)
|
||||||
|
self.send_header('Content-type', 'application/json')
|
||||||
|
self.end_headers()
|
||||||
|
self.wfile.write(json.dumps({"status": "ok", "count": len(names)}).encode())
|
||||||
|
print(f"🔄 Кэш имён операторов обновлён, загружено {len(names)} имён")
|
||||||
|
except Exception as e:
|
||||||
|
self.send_response(500)
|
||||||
|
self.end_headers()
|
||||||
|
self.wfile.write(json.dumps({"status": "error", "error": str(e)}).encode())
|
||||||
|
else:
|
||||||
|
self.send_response(404)
|
||||||
|
self.end_headers()
|
||||||
|
|
||||||
|
def log_message(self, format, *args):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def start_command_server(port=8003):
|
||||||
|
server = http.server.HTTPServer(('0.0.0.0', port), CommandHandler)
|
||||||
|
print(f"🚀 Командный сервер запущен на порту {port}")
|
||||||
|
server.serve_forever()
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
start_command_server()
|
||||||
|
EOF
|
||||||
|
|
||||||
|
echo "=== 7. Создание systemd сервисов ==="
|
||||||
|
sudo tee /etc/systemd/system/emotion-api.service << 'EOF'
|
||||||
|
[Unit]
|
||||||
|
Description=Text Emotion Recognition API
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
User=root
|
||||||
|
WorkingDirectory=/opt/emotion
|
||||||
|
Environment="PATH=/opt/emotion/venv/bin"
|
||||||
|
ExecStart=/opt/emotion/venv/bin/python /opt/emotion/server_text_final.py
|
||||||
|
Restart=always
|
||||||
|
RestartSec=10
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
EOF
|
||||||
|
|
||||||
|
sudo tee /etc/systemd/system/emotion-processor.service << 'EOF'
|
||||||
|
[Unit]
|
||||||
|
Description=Emotion Processor (background)
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
User=root
|
||||||
|
WorkingDirectory=/opt/emotion
|
||||||
|
Environment="PATH=/opt/emotion/venv/bin"
|
||||||
|
ExecStart=/opt/emotion/venv/bin/python /opt/emotion/emotion_processor.py
|
||||||
|
Restart=always
|
||||||
|
RestartSec=10
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
EOF
|
||||||
|
|
||||||
|
sudo tee /etc/systemd/system/emotion-command.service << 'EOF'
|
||||||
|
[Unit]
|
||||||
|
Description=Emotion Command Server
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
User=root
|
||||||
|
WorkingDirectory=/opt/emotion
|
||||||
|
Environment="PATH=/opt/emotion/venv/bin"
|
||||||
|
ExecStart=/opt/emotion/venv/bin/python /opt/emotion/command_server.py
|
||||||
|
Restart=always
|
||||||
|
RestartSec=10
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
EOF
|
||||||
|
|
||||||
|
echo "=== 8. Запуск сервисов ==="
|
||||||
|
sudo systemctl daemon-reload
|
||||||
|
sudo systemctl enable emotion-api emotion-processor emotion-command
|
||||||
|
sudo systemctl start emotion-api emotion-processor emotion-command
|
||||||
|
|
||||||
|
echo "=== 9. Проверка статуса ==="
|
||||||
|
sleep 3
|
||||||
|
sudo systemctl status emotion-api --no-pager
|
||||||
|
sudo systemctl status emotion-processor --no-pager
|
||||||
|
sudo systemctl status emotion-command --no-pager
|
||||||
|
|
||||||
|
echo "=== Emotion ВМ готова ==="
|
||||||
|
echo "API эмоций: http://$EMOTION_HOST:$EMOTION_PORT"
|
||||||
|
echo "Командный сервер: порт $PROCESSOR_PORT"
|
||||||
Reference in New Issue
Block a user