Files
aitbc/scripts/gpu/simple_gpu_miner.py
oib 9b9c5beb23 ```
chore: enhance .gitignore and remove obsolete documentation files

- Reorganize .gitignore with categorized sections for better maintainability
- Add comprehensive ignore patterns for Python, Node.js, databases, logs, and build artifacts
- Add project-specific ignore rules for coordinator, explorer, and deployment files
- Remove outdated documentation: BITCOIN-WALLET-SETUP.md, LOCAL_ASSETS_SUMMARY.md, README-CONTAINER-DEPLOYMENT.md, README-DOMAIN-DEPLOYMENT.md
```
2026-01-24 14:44:51 +01:00

183 lines
4.9 KiB
Python

#!/usr/bin/env python3
"""
Simple GPU Miner Client for AITBC
Registers GPU with coordinator and sends heartbeats
"""
import json
import time
import httpx
import logging
from datetime import datetime
# Configuration
COORDINATOR_URL = "http://localhost:8000"
MINER_ID = "localhost-gpu-miner"
AUTH_TOKEN = "REDACTED_MINER_KEY"
HEARTBEAT_INTERVAL = 15
# Setup logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
# GPU capabilities (RTX 4060 Ti)
GPU_CAPABILITIES = {
"gpu": {
"model": "NVIDIA GeForce RTX 4060 Ti",
"memory_gb": 16,
"cuda_version": "12.4",
"compute_capability": "8.9",
"driver_version": "550.163.01"
},
"compute": {
"type": "GPU",
"platform": "CUDA",
"supported_tasks": ["inference", "training", "stable-diffusion", "llama"],
"max_concurrent_jobs": 1
}
}
def register_miner():
"""Register the miner with the coordinator"""
register_data = {
"capabilities": GPU_CAPABILITIES,
"concurrency": 1,
"region": "localhost"
}
headers = {
"Authorization": f"Bearer {AUTH_TOKEN}",
"Content-Type": "application/json"
}
try:
response = httpx.post(
f"{COORDINATOR_URL}/miners/register",
json=register_data,
headers=headers,
timeout=10
)
if response.status_code == 200:
data = response.json()
logger.info(f"Successfully registered miner: {data}")
return data.get("session_token")
else:
logger.error(f"Registration failed: {response.status_code} - {response.text}")
return None
except Exception as e:
logger.error(f"Error registering miner: {e}")
return None
def send_heartbeat():
"""Send heartbeat to coordinator"""
heartbeat_data = {
"inflight": 0,
"status": "ONLINE",
"metadata": {
"last_seen": datetime.utcnow().isoformat(),
"gpu_utilization": 9, # Current GPU utilization from nvidia-smi
"gpu_memory_used": 2682, # MB
"gpu_temperature": 43
}
}
headers = {
"Authorization": f"Bearer {AUTH_TOKEN}",
"Content-Type": "application/json"
}
try:
response = httpx.post(
f"{COORDINATOR_URL}/miners/heartbeat",
json=heartbeat_data,
headers=headers,
timeout=5
)
if response.status_code == 200:
logger.info("Heartbeat sent successfully")
else:
logger.error(f"Heartbeat failed: {response.status_code} - {response.text}")
except Exception as e:
logger.error(f"Error sending heartbeat: {e}")
def poll_for_jobs():
"""Poll for available jobs"""
poll_data = {
"max_wait_seconds": 5
}
headers = {
"Authorization": f"Bearer {AUTH_TOKEN}",
"Content-Type": "application/json"
}
try:
response = httpx.post(
f"{COORDINATOR_URL}/miners/poll",
json=poll_data,
headers=headers,
timeout=10
)
if response.status_code == 200:
job = response.json()
logger.info(f"Received job: {job}")
return job
elif response.status_code == 204:
logger.info("No jobs available")
return None
else:
logger.error(f"Poll failed: {response.status_code} - {response.text}")
return None
except Exception as e:
logger.error(f"Error polling for jobs: {e}")
return None
def main():
"""Main miner loop"""
logger.info("Starting GPU Miner Client...")
# Register with coordinator
session_token = register_miner()
if not session_token:
logger.error("Failed to register, exiting")
return
logger.info("Miner registered successfully, starting main loop...")
# Main loop
last_heartbeat = 0
last_poll = 0
try:
while True:
current_time = time.time()
# Send heartbeat
if current_time - last_heartbeat >= HEARTBEAT_INTERVAL:
send_heartbeat()
last_heartbeat = current_time
# Poll for jobs
if current_time - last_poll >= 3: # Poll every 3 seconds
job = poll_for_jobs()
if job:
# TODO: Execute job
logger.info(f"Would execute job: {job}")
last_poll = current_time
time.sleep(1)
except KeyboardInterrupt:
logger.info("Shutting down miner...")
except Exception as e:
logger.error(f"Error in main loop: {e}")
if __name__ == "__main__":
main()