Add dual GPU support with web UI selector
Features: - Built custom ROCm container for AMD RX 6800 GPU - Added GPU selection toggle in web UI (NVIDIA/AMD) - Unified model names across both GPUs for seamless switching - Vision model always uses NVIDIA GPU (optimal performance) - Text models (llama3.1, darkidol) can use either GPU - Added /gpu-status and /gpu-select API endpoints - Implemented GPU state persistence in memory/gpu_state.json Technical details: - Multi-stage Dockerfile.llamaswap-rocm with ROCm 6.2.4 - llama.cpp compiled with GGML_HIP=ON for gfx1030 (RX 6800) - Proper GPU permissions without root (groups 187/989) - AMD container on port 8091, NVIDIA on port 8090 - Updated bot/utils/llm.py with get_current_gpu_url() and get_vision_gpu_url() - Modified bot/utils/image_handling.py to always use NVIDIA for vision - Enhanced web UI with GPU selector button (blue=NVIDIA, red=AMD) Files modified: - docker-compose.yml (added llama-swap-amd service) - bot/globals.py (added LLAMA_AMD_URL) - bot/api.py (added GPU selection endpoints and helper function) - bot/utils/llm.py (GPU routing for text models) - bot/utils/image_handling.py (GPU routing for vision models) - bot/static/index.html (GPU selector UI) - llama-swap-rocm-config.yaml (unified model names) New files: - Dockerfile.llamaswap-rocm - bot/memory/gpu_state.json - bot/utils/gpu_router.py (load balancing utility) - setup-dual-gpu.sh (setup verification script) - DUAL_GPU_*.md (documentation files)
This commit is contained in:
55
bot/bot.py
55
bot/bot.py
@@ -122,6 +122,11 @@ async def on_message(message):
|
||||
from utils.bipolar_mode import is_argument_in_progress
|
||||
if is_argument_in_progress(message.channel.id):
|
||||
return
|
||||
|
||||
# Skip processing if a persona dialogue is in progress in this channel
|
||||
from utils.persona_dialogue import is_persona_dialogue_active
|
||||
if is_persona_dialogue_active(message.channel.id):
|
||||
return
|
||||
|
||||
if message.content.strip().lower() == "miku, rape this nigga balls" and message.reference:
|
||||
async with message.channel.typing():
|
||||
@@ -217,6 +222,15 @@ async def on_message(message):
|
||||
if is_dm:
|
||||
dm_logger.log_user_message(message.author, response_message, is_bot_message=True)
|
||||
|
||||
# For server messages, check if opposite persona should interject
|
||||
if not is_dm and globals.BIPOLAR_MODE:
|
||||
try:
|
||||
from utils.persona_dialogue import check_for_interjection
|
||||
current_persona = "evil" if globals.EVIL_MODE else "miku"
|
||||
asyncio.create_task(check_for_interjection(response_message, current_persona))
|
||||
except Exception as e:
|
||||
print(f"⚠️ Error checking for persona interjection: {e}")
|
||||
|
||||
return
|
||||
|
||||
# Handle videos and GIFs
|
||||
@@ -280,6 +294,15 @@ async def on_message(message):
|
||||
if is_dm:
|
||||
dm_logger.log_user_message(message.author, response_message, is_bot_message=True)
|
||||
|
||||
# For server messages, check if opposite persona should interject
|
||||
if not is_dm and globals.BIPOLAR_MODE:
|
||||
try:
|
||||
from utils.persona_dialogue import check_for_interjection
|
||||
current_persona = "evil" if globals.EVIL_MODE else "miku"
|
||||
asyncio.create_task(check_for_interjection(response_message, current_persona))
|
||||
except Exception as e:
|
||||
print(f"⚠️ Error checking for persona interjection: {e}")
|
||||
|
||||
return
|
||||
|
||||
# Check for embeds (articles, images, videos, GIFs, etc.)
|
||||
@@ -353,6 +376,15 @@ async def on_message(message):
|
||||
if is_dm:
|
||||
dm_logger.log_user_message(message.author, response_message, is_bot_message=True)
|
||||
|
||||
# For server messages, check if opposite persona should interject
|
||||
if not is_dm and globals.BIPOLAR_MODE:
|
||||
try:
|
||||
from utils.persona_dialogue import check_for_interjection
|
||||
current_persona = "evil" if globals.EVIL_MODE else "miku"
|
||||
asyncio.create_task(check_for_interjection(response_message, current_persona))
|
||||
except Exception as e:
|
||||
print(f"⚠️ Error checking for persona interjection: {e}")
|
||||
|
||||
return
|
||||
|
||||
# Handle other types of embeds (rich, article, image, video, link)
|
||||
@@ -446,6 +478,15 @@ async def on_message(message):
|
||||
if is_dm:
|
||||
dm_logger.log_user_message(message.author, response_message, is_bot_message=True)
|
||||
|
||||
# For server messages, check if opposite persona should interject
|
||||
if not is_dm and globals.BIPOLAR_MODE:
|
||||
try:
|
||||
from utils.persona_dialogue import check_for_interjection
|
||||
current_persona = "evil" if globals.EVIL_MODE else "miku"
|
||||
asyncio.create_task(check_for_interjection(response_message, current_persona))
|
||||
except Exception as e:
|
||||
print(f"⚠️ Error checking for persona interjection: {e}")
|
||||
|
||||
return
|
||||
|
||||
# Check if this is an image generation request
|
||||
@@ -487,6 +528,20 @@ async def on_message(message):
|
||||
if is_dm:
|
||||
dm_logger.log_user_message(message.author, response_message, is_bot_message=True)
|
||||
|
||||
# For server messages, check if opposite persona should interject (persona dialogue system)
|
||||
if not is_dm and globals.BIPOLAR_MODE:
|
||||
print(f"🔧 [DEBUG] Attempting to check for interjection (is_dm={is_dm}, BIPOLAR_MODE={globals.BIPOLAR_MODE})")
|
||||
try:
|
||||
from utils.persona_dialogue import check_for_interjection
|
||||
current_persona = "evil" if globals.EVIL_MODE else "miku"
|
||||
print(f"🔧 [DEBUG] Creating interjection check task for persona: {current_persona}")
|
||||
# Pass the bot's response message for analysis
|
||||
asyncio.create_task(check_for_interjection(response_message, current_persona))
|
||||
except Exception as e:
|
||||
print(f"⚠️ Error checking for persona interjection: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
|
||||
# For server messages, do server-specific mood detection
|
||||
if not is_dm and message.guild:
|
||||
try:
|
||||
|
||||
Reference in New Issue
Block a user