KEY INSIGHT
Onboarding for local AI products must build trust before asking for compute resources. Users need to understand what they're installing, why local processing matters, and how their hardware will be used—before any model downloads begin.
Cloud product onboarding optimises for activation speed. Local product onboarding must optimising for informed consent. You're asking users to allocate gigabytes of disk space and potentially all their RAM. They need to understand the commitment.
```python
# onboarding_flow.py
from dataclasses import dataclass
from typing import List, Optional
import platform
import torch
@dataclass
class SystemRequirements:
min_ram_gb: float
recommended_ram_gb: float
disk_space_gb: float
gpu_required: bool
gpu_vram_gb: float = 0
cuda_version: Optional[str] = None
@dataclass
class OnboardingStep:
step_id: str
title: str
description: str
action_required: bool
estimated_time: str
completed: bool = False
class LocalModelOnboarding:
def __init__(self, product_name: str, model_configs: dict):
self.product_name = product_name
self.model_configs = model_configs
def run_system_audit(self) -> dict:
"""Gather system compatibility information."""
import psutil
system_info = {
"os": platform.system(),
"os_version": platform.version(),
"architecture": platform.machine(),
"cpu_count": psutil.cpu_count(),
"total_ram_gb": psutil.virtual_memory().total / (1024**3),
"available_ram_gb": psutil.virtual_memory().available / (1024**3),
"gpu_available": torch.cuda.is_available(),
"gpu_count": torch.cuda.device_count() if torch.cuda.is_available() else 0,
"gpu_name": torch.cuda.get_device_name() if torch.cuda.is_available() else None,
"gpu_vram_gb": torch.cuda.get_device_properties(0).total_memory / (1024**3) if torch.cuda.is_available() else 0,
"disk_free_gb": psutil.disk_usage('/').free / (1024**3)
}
return system_info
def generate_requirements_checklist(self, model_name: str) -> List[OnboardingStep]:
"""Generate onboarding steps based on selected model."""
config = self.model_configs.get(model_name, {})
requirements = config.get('requirements', SystemRequirements(
min_ram_gb=8, recommended_ram_gb=16,
disk_space_gb=20, gpu_required=True
))
steps = [
OnboardingStep(
step_id="privacy_explained",
title="Your Data Stays Local",
description=f"{self.product_name} processes all requests on YOUR hardware. Nothing is sent to external servers.",
action_required=False,
estimated_time="1 minute"
),
OnboardingStep(
step_id="hardware_check",
title="Checking Your System",
description=f"RAM: {requirements.recommended_ram_gb}+GB recommended, {requirements.disk_space_gb}+GB disk space needed",
action_required=True,
estimated_time="30 seconds"
),
OnboardingStep(
step_id="model_download",
title="Download Model Files",
description=f"Downloading {config.get('size_gb', '~15')}GB model. This happens once.",
action_required=True,
estimated_time=f"{config.get('download_minutes', '5-15')} minutes"
)
]
return steps
def calculate_model_recommendation(self, system_info: dict) -> List[dict]:
"""Recommend appropriate models based on system capabilities."""
ram = system_info['total_ram_gb']
vram = system_info.get('gpu_vram_gb', 0)
has_gpu = system_info['gpu_available']
recommendations = []
for name, config in self.model_configs.items():
req = config['requirements']
score = 0
if ram >= req.min_ram_gb:
score += 1
if ram >= req.recommended_ram_gb:
score += 2
if has_gpu and vram >= req.gpu_vram_gb:
score += 2
if not has_gpu and not req.gpu_required:
score += 2
if score >= 2:
recommendations.append({
'model': name,
'fit': 'recommended' if score >= 4 else 'adequate',
'notes': config.get('notes', '')
})
return sorted(recommendations, key=lambda x: 0 if x['fit'] == 'recommended' else 1)
```
Display hardware stats prominently during onboarding. Show actual numbers from their system next to requirements. This transparency builds trust and reduces support tickets where users claim they weren't warned.