From 6f6b66cef545785554871b33ef6bc35e7f1bf147 Mon Sep 17 00:00:00 2001 From: aitbc Date: Thu, 30 Apr 2026 11:19:10 +0200 Subject: [PATCH] Create GPU service foundation - Created gpu-service application structure - Added pyproject.toml with FastAPI, SQLModel, asyncpg, and aitbc-core dependencies - Implemented main.py with basic GPU service structure - Created systemd service file for gpu-service (port 8101) - Added README.md with installation and configuration instructions - Documented future work needed for full GPU extraction This starts Phase 4.3: Extract GPU Service (foundation created, full extraction requires additional work) --- apps/gpu-service/README.md | 53 ++++++++++++++ apps/gpu-service/gpu-service.service | 17 +++++ apps/gpu-service/pyproject.toml | 24 +++++++ apps/gpu-service/src/gpu_service/__init__.py | 6 ++ apps/gpu-service/src/gpu_service/main.py | 72 ++++++++++++++++++++ 5 files changed, 172 insertions(+) create mode 100644 apps/gpu-service/README.md create mode 100644 apps/gpu-service/gpu-service.service create mode 100644 apps/gpu-service/pyproject.toml create mode 100644 apps/gpu-service/src/gpu_service/__init__.py create mode 100644 apps/gpu-service/src/gpu_service/main.py diff --git a/apps/gpu-service/README.md b/apps/gpu-service/README.md new file mode 100644 index 00000000..5ed7aef0 --- /dev/null +++ b/apps/gpu-service/README.md @@ -0,0 +1,53 @@ +# AITBC GPU Service + +Manages GPU resource operations. + +## Installation + +```bash +cd /opt/aitbc +poetry install --with gpu-service +``` + +## Database Setup + +Create a separate database for the GPU service: + +```sql +CREATE DATABASE aitbc_gpu; +CREATE USER aitbc_gpu WITH PASSWORD 'password'; +GRANT ALL PRIVILEGES ON DATABASE aitbc_gpu TO aitbc_gpu; +``` + +## Running + +```bash +# Development +python -m gpu_service.main + +# Production (systemd) +sudo systemctl start gpu-service +sudo systemctl enable gpu-service +``` + +## Endpoints + +- `GET /health` - Health check +- `GET /gpu/status` - Get GPU status + +## Future Work + +To fully extract GPU functionality from coordinator-api, the following needs to be done: + +1. **Extract domain models**: Copy GPU-related domain models from coordinator-api +2. **Extract services**: Copy GPU-related services from coordinator-api +3. **Extract storage layer**: Set up separate database session management +4. **Extract routers**: Copy GPU routers (edge_gpu.py, gpu_multimodal_health.py, miner.py) +5. **Update coordinator-api**: Remove GPU-related code +6. **Update gateway**: GPU service is already configured in gateway + +## Service Configuration + +- Port: 8101 +- Database: aitbc_gpu +- Gateway route: /gpu/* diff --git a/apps/gpu-service/gpu-service.service b/apps/gpu-service/gpu-service.service new file mode 100644 index 00000000..026479e4 --- /dev/null +++ b/apps/gpu-service/gpu-service.service @@ -0,0 +1,17 @@ +[Unit] +Description=AITBC GPU Service +After=network.target postgresql.service + +[Service] +Type=simple +User=aitbc +WorkingDirectory=/opt/aitbc/apps/gpu-service +Environment="PATH=/opt/aitbc/venv/bin" +Environment="PYTHONPATH=/opt/aitbc/packages/py/aitbc-core/src:/opt/aitbc/apps/gpu-service/src:/opt/aitbc" +Environment="DATABASE_URL=postgresql+asyncpg://aitbc_gpu:password@localhost:5432/aitbc_gpu" +ExecStart=/opt/aitbc/venv/bin/python -m gpu_service.main +Restart=always +RestartSec=10 + +[Install] +WantedBy=multi-user.target diff --git a/apps/gpu-service/pyproject.toml b/apps/gpu-service/pyproject.toml new file mode 100644 index 00000000..78b68ddd --- /dev/null +++ b/apps/gpu-service/pyproject.toml @@ -0,0 +1,24 @@ +[project] +name = "gpu-service" +version = "0.1.0" +description = "AITBC GPU Service for GPU resource management" +authors = [ + {name = "AITBC Team", email = "team@aitbc.dev"} +] +requires-python = ">=3.13" +dependencies = [ + "fastapi>=0.104.0", + "uvicorn>=0.24.0", + "sqlmodel>=0.0.14", + "asyncpg>=0.30.0", + "aitbc-core", +] + +[build-system] +requires = ["poetry-core"] +build-backend = "poetry.core.masonry.api" + +[tool.poetry] +packages = [ + { include = "gpu_service", from = "src" } +] diff --git a/apps/gpu-service/src/gpu_service/__init__.py b/apps/gpu-service/src/gpu_service/__init__.py new file mode 100644 index 00000000..b5623d19 --- /dev/null +++ b/apps/gpu-service/src/gpu_service/__init__.py @@ -0,0 +1,6 @@ +""" +AITBC GPU Service +Manages GPU resource operations +""" + +__version__ = "0.1.0" diff --git a/apps/gpu-service/src/gpu_service/main.py b/apps/gpu-service/src/gpu_service/main.py new file mode 100644 index 00000000..1b8c0656 --- /dev/null +++ b/apps/gpu-service/src/gpu_service/main.py @@ -0,0 +1,72 @@ +""" +GPU Service main application +Manages GPU resource operations +""" + +from contextlib import asynccontextmanager +from typing import AsyncIterator + +from fastapi import FastAPI +from pydantic import BaseModel + +from aitbc import ( + configure_logging, + get_logger, + RequestIDMiddleware, + PerformanceLoggingMiddleware, + RequestValidationMiddleware, + ErrorHandlerMiddleware, +) + +# Configure structured logging +configure_logging(level="INFO") +logger = get_logger(__name__) + + +@asynccontextmanager +async def lifespan(app: FastAPI) -> AsyncIterator[None]: + """Lifecycle events for the GPU Service.""" + logger.info("Starting GPU Service") + yield + logger.info("Shutting down GPU Service") + + +app = FastAPI( + title="AITBC GPU Service", + description="Manages GPU resource operations", + version="0.1.0", + lifespan=lifespan, +) + +# Add middleware +app.add_middleware(RequestIDMiddleware) +app.add_middleware(PerformanceLoggingMiddleware) +app.add_middleware(RequestValidationMiddleware, max_request_size=10*1024*1024) +app.add_middleware(ErrorHandlerMiddleware) + + +class HealthResponse(BaseModel): + """Health check response""" + status: str + service: str + + +@app.get("/health") +async def health() -> HealthResponse: + """Health check endpoint""" + return HealthResponse(status="healthy", service="gpu-service") + + +@app.get("/gpu/status") +async def gpu_status() -> dict[str, str]: + """Get GPU status""" + return { + "status": "operational", + "service": "gpu-service", + "message": "GPU service is running", + } + + +if __name__ == "__main__": + import uvicorn + uvicorn.run(app, host="0.0.0.0", port=8101)