Tassos

System Diagnostic for Podcast Transcription

Jun 1st, 2026 (edited)
57
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 14.64 KB | None | 0 0
  1. #!/usr/bin/env bash
  2. # =============================================================================
  3. # Complete System Diagnostic for Podcast Transcription
  4. #
  5. # ⚠️ Run with sudo or root user !
  6. #
  7. # Usage:
  8. #   chmod +x 12-system-evaluation.sh
  9. #   sudo ./12-system-evaluation.sh
  10. #
  11. # What it does:
  12. #   Examines the machine's hardware, software, and network connectivity
  13. #   and recommends the best transcription approach for this system.
  14. #
  15. # Compatible with: Fedora, RHEL, Debian, Ubuntu (any Linux with bash)
  16. #
  17. # See also:
  18. #   docs/en/12-system-evaluation.md
  19. #   docs/en/13-transcription-runbook.md
  20. #
  21. # Tip commands:
  22. # dmidecode -t system | grep -E "Manufacturer|Product Name|Version|Family"
  23. # lspci | grep -i "3d\|vga\|nvidia\|quadro"
  24. # =============================================================================
  25.  
  26. # Fix Windows-style line endings (CRLF → LF) if present
  27. if grep -qP '\r$' "$0" 2>/dev/null; then
  28.     sed -i 's/\r$//' "$0"
  29.     exec bash "$0" "$@"
  30. fi
  31.  
  32. set -euo pipefail
  33.  
  34. # --- Colors ---
  35. RED='\033[0;31m'
  36. GREEN='\033[0;32m'
  37. YELLOW='\033[1;33m'
  38. CYAN='\033[0;36m'
  39. BOLD='\033[1m'
  40. NC='\033[0m'
  41.  
  42. header() {
  43.     echo ""
  44.     echo -e "${CYAN}═══════════════════════════════════════════════════════════════${NC}"
  45.     echo -e "${BOLD}  $1${NC}"
  46.     echo -e "${CYAN}═══════════════════════════════════════════════════════════════${NC}"
  47. }
  48.  
  49. section() {
  50.     echo -e "\n${YELLOW}--- $1 ---${NC}"
  51. }
  52.  
  53. ok()   { echo -e "  ${GREEN}${NC} $1"; }
  54. warn() { echo -e "  ${YELLOW}!${NC} $1"; }
  55. fail() { echo -e "  ${RED}${NC} $1"; }
  56.  
  57. # =============================================================================
  58. header "MACHINE IDENTITY"
  59. # =============================================================================
  60.  
  61. section "Manufacturer & Model"
  62. if [ -r /sys/devices/virtual/dmi/id/sys_vendor ]; then
  63.     VENDOR=$(cat /sys/devices/virtual/dmi/id/sys_vendor 2>/dev/null || echo "Unknown")
  64.     PRODUCT=$(cat /sys/devices/virtual/dmi/id/product_name 2>/dev/null || echo "Unknown")
  65.     VERSION=$(cat /sys/devices/virtual/dmi/id/product_version 2>/dev/null || echo "")
  66.     echo "  Vendor:  $VENDOR"
  67.     echo "  Product: $PRODUCT"
  68.     [ -n "$VERSION" ] && echo "  Version: $VERSION"
  69. else
  70.     warn "Cannot read DMI (need sudo?)"
  71. fi
  72.  
  73. if command -v dmidecode &>/dev/null && [ "$(id -u)" = "0" ]; then
  74.     section "Detailed System Info (dmidecode)"
  75.     dmidecode -t system 2>/dev/null | grep -E "Manufacturer|Product Name|Version|Serial|Family" | sed 's/^/  /'
  76.     echo ""
  77.     dmidecode -t baseboard 2>/dev/null | grep -E "Manufacturer|Product Name|Version" | sed 's/^/  /'
  78.     echo ""
  79.     dmidecode -t bios 2>/dev/null | grep -E "Vendor|Version|Release Date" | sed 's/^/  /'
  80. elif [ "$(id -u)" != "0" ]; then
  81.     warn "Run with sudo for full dmidecode information"
  82. fi
  83.  
  84. # =============================================================================
  85. header "CPU (PROCESSOR)"
  86. # =============================================================================
  87.  
  88. section "Model & Cores"
  89. lscpu | grep -E "Model name|^CPU\(s\)|Thread|Core|Socket|^CPU max MHz|^CPU min MHz|Architecture" | sed 's/^/  /'
  90.  
  91. section "AVX Support"
  92. if grep -qo 'avx512' /proc/cpuinfo 2>/dev/null; then
  93.     ok "AVX-512: Supported (excellent for inference)"
  94. elif grep -qo 'avx2' /proc/cpuinfo 2>/dev/null; then
  95.     ok "AVX2: Supported (good for inference)"
  96. else
  97.     fail "No AVX2 — CPU inference will be very slow"
  98. fi
  99.  
  100. # =============================================================================
  101. header "MEMORY (RAM)"
  102. # =============================================================================
  103.  
  104. section "Total & Available"
  105. free -h | head -2 | sed 's/^/  /'
  106.  
  107. AVAILABLE_MB=$(free -m | awk '/Mem:/ {print $7}')
  108. echo ""
  109. if [ "$AVAILABLE_MB" -ge 14000 ]; then
  110.     ok "Available RAM: ${AVAILABLE_MB} MB — enough for WhisperX large-v3 + diarization on CPU"
  111. elif [ "$AVAILABLE_MB" -ge 11000 ]; then
  112.     ok "Available RAM: ${AVAILABLE_MB} MB — enough for Whisper large-v3 on CPU"
  113. elif [ "$AVAILABLE_MB" -ge 6000 ]; then
  114.     warn "Available RAM: ${AVAILABLE_MB} MB — enough only for Whisper medium on CPU"
  115. else
  116.     fail "Available RAM: ${AVAILABLE_MB} MB — insufficient for local inference, use cloud"
  117. fi
  118.  
  119. if command -v dmidecode &>/dev/null && [ "$(id -u)" = "0" ]; then
  120.     section "RAM Details (slots, type, speed)"
  121.     dmidecode -t memory 2>/dev/null | grep -E "Size|Type:|Speed|Manufacturer|Locator" | grep -v "No Module\|Unknown\|Not Specified" | sed 's/^/  /'
  122. fi
  123.  
  124. # =============================================================================
  125. header "GRAPHICS CARD (GPU)"
  126. # =============================================================================
  127.  
  128. section "GPU Detection"
  129. GPU_FOUND=false
  130.  
  131. if lspci 2>/dev/null | grep -iE "nvidia" | grep -iv "audio" > /dev/null 2>&1; then
  132.     lspci | grep -iE "nvidia" | grep -iv "audio" | sed 's/^/  /'
  133.     GPU_FOUND=true
  134.     echo ""
  135.  
  136.     if command -v nvidia-smi &>/dev/null; then
  137.         section "NVIDIA GPU Details"
  138.         nvidia-smi --query-gpu=name,memory.total,memory.free,memory.used,driver_version,compute_cap,temperature.gpu,power.draw --format=csv,noheader 2>/dev/null | while IFS=',' read -r name total free used driver compute temp power; do
  139.             echo "  Name:        $name"
  140.             echo "  VRAM Total:  $total"
  141.             echo "  VRAM Free:   $free"
  142.             echo "  VRAM Used:   $used"
  143.             echo "  Driver:      $driver"
  144.             echo "  Compute Cap: $compute"
  145.             echo "  Temperature: $temp"
  146.             echo "  Power Draw:  $power"
  147.         done
  148.  
  149.         VRAM_MB=$(nvidia-smi --query-gpu=memory.total --format=csv,noheader,nounits 2>/dev/null | head -1 | tr -d ' ')
  150.         echo ""
  151.         if [ -n "$VRAM_MB" ] && [ "$VRAM_MB" -ge 10000 ] 2>/dev/null; then
  152.             ok "VRAM: ${VRAM_MB} MB — enough for Whisper large-v3 on GPU (best accuracy)"
  153.         elif [ -n "$VRAM_MB" ] && [ "$VRAM_MB" -ge 5000 ] 2>/dev/null; then
  154.             warn "VRAM: ${VRAM_MB} MB — enough for Whisper medium on GPU"
  155.         elif [ -n "$VRAM_MB" ] && [ "$VRAM_MB" -ge 2000 ] 2>/dev/null; then
  156.             warn "VRAM: ${VRAM_MB} MB — enough only for Whisper small on GPU"
  157.         fi
  158.     else
  159.         fail "nvidia-smi not found — install NVIDIA drivers"
  160.     fi
  161. else
  162.     # Check for AMD or Intel integrated
  163.     if lspci 2>/dev/null | grep -iE "amd.*radeon|amd.*vga" > /dev/null 2>&1; then
  164.         lspci | grep -iE "amd.*radeon|amd.*vga" | sed 's/^/  /'
  165.         warn "AMD GPU — not supported for Whisper/WhisperX (requires NVIDIA CUDA)"
  166.     fi
  167.     if lspci 2>/dev/null | grep -iE "intel.*(vga|graphics)" > /dev/null 2>&1; then
  168.         lspci | grep -iE "intel.*(vga|graphics)" | sed 's/^/  /'
  169.         warn "Intel integrated graphics — not supported for AI inference"
  170.     fi
  171.     if ! $GPU_FOUND; then
  172.         fail "No NVIDIA GPU found — use cloud (Groq/Google) or CPU mode (slow)"
  173.     fi
  174. fi
  175.  
  176. # =============================================================================
  177. header "CUDA"
  178. # =============================================================================
  179.  
  180. section "CUDA Toolkit"
  181. if command -v nvcc &>/dev/null; then
  182.     nvcc --version 2>/dev/null | grep "release" | sed 's/^/  /'
  183.     ok "CUDA toolkit installed"
  184. else
  185.     warn "CUDA toolkit not found (nvcc) — needed for WhisperX on GPU"
  186. fi
  187.  
  188. section "CUDA via nvidia-smi"
  189. if command -v nvidia-smi &>/dev/null; then
  190.     CUDA_VER=$(nvidia-smi 2>/dev/null | grep "CUDA Version" | awk '{print $9}')
  191.     if [ -n "$CUDA_VER" ]; then
  192.         ok "CUDA Version: $CUDA_VER (via driver)"
  193.     fi
  194. fi
  195.  
  196. # =============================================================================
  197. header "STORAGE"
  198. # =============================================================================
  199.  
  200. section "Disk Space"
  201. df -h / | tail -1 | awk '{print "  Total: " $2 "  Used: " $3 "  Free: " $4 "  Use%: " $5}'
  202.  
  203. section "Disk Model & Type"
  204. lsblk -d -o NAME,MODEL,ROTA,SIZE,TRAN 2>/dev/null | sed 's/^/  /'
  205. echo ""
  206. echo "  (ROTA=0: SSD, ROTA=1: HDD, TRAN: nvme/sata/usb)"
  207.  
  208. if ls /dev/nvme* &>/dev/null 2>&1; then
  209.     ok "NVMe drive detected — fast model loading"
  210. fi
  211.  
  212. # =============================================================================
  213. header "PYTHON & AI PACKAGES"
  214. # =============================================================================
  215.  
  216. section "Python"
  217. if command -v python3 &>/dev/null; then
  218.     ok "Python3: $(python3 --version 2>&1 | awk '{print $2}')"
  219. else
  220.     fail "Python3 not found — required for all approaches"
  221. fi
  222.  
  223. if command -v pip3 &>/dev/null; then
  224.     ok "pip3: $(pip3 --version 2>&1 | awk '{print $2}')"
  225. else
  226.     warn "pip3 not found"
  227. fi
  228.  
  229. section "Installed AI Packages"
  230. if command -v pip3 &>/dev/null; then
  231.     PACKAGES=$(pip3 list 2>/dev/null | grep -iE "^(openai-whisper|whisperx|faster-whisper|torch |torchaudio|google-cloud-speech|groq |pyannote|transformers) " || true)
  232.     if [ -n "$PACKAGES" ]; then
  233.         echo "$PACKAGES" | while read -r pkg ver; do
  234.             ok "$pkg ($ver)"
  235.         done
  236.     else
  237.         warn "No relevant AI packages found — installation will be needed"
  238.     fi
  239. fi
  240.  
  241. # =============================================================================
  242. header "FFMPEG"
  243. # =============================================================================
  244.  
  245. if command -v ffmpeg &>/dev/null; then
  246.     ok "FFmpeg: $(ffmpeg -version 2>/dev/null | head -1 | awk '{print $3}')"
  247. else
  248.     fail "FFmpeg not found — required for audio conversion and chunking"
  249.     echo "  Install: sudo apt install ffmpeg (Debian/Ubuntu)"
  250.     echo "           sudo dnf install ffmpeg-free (Fedora/RHEL)"
  251. fi
  252.  
  253. # =============================================================================
  254. header "NETWORK"
  255. # =============================================================================
  256.  
  257. section "Cloud API Connectivity"
  258. if command -v curl &>/dev/null; then
  259.     GROQ_STATUS=$(curl -s -o /dev/null -w "%{http_code}" --max-time 5 https://api.groq.com/openai/v1/models 2>/dev/null || echo "000")
  260.     if [ "$GROQ_STATUS" != "000" ]; then
  261.         ok "Groq API: HTTP $GROQ_STATUS — reachable"
  262.     else
  263.         fail "Groq API: unreachable — Approach A will not work"
  264.     fi
  265.  
  266.     GOOGLE_STATUS=$(curl -s -o /dev/null -w "%{http_code}" --max-time 5 https://speech.googleapis.com 2>/dev/null || echo "000")
  267.     if [ "$GOOGLE_STATUS" != "000" ]; then
  268.         ok "Google Cloud STT API: HTTP $GOOGLE_STATUS — reachable"
  269.     else
  270.         fail "Google Cloud STT API: unreachable — Approach C will not work"
  271.     fi
  272. else
  273.     warn "curl not found — cannot check connectivity"
  274. fi
  275.  
  276. # =============================================================================
  277. header "OPERATING SYSTEM"
  278. # =============================================================================
  279.  
  280. echo "  Kernel: $(uname -r)"
  281. echo "  Arch:   $(uname -m)"
  282. if [ -f /etc/os-release ]; then
  283.     echo "  Distro: $(grep PRETTY_NAME /etc/os-release | cut -d= -f2 | tr -d '"')"
  284. fi
  285. echo "  Uptime: $(uptime -p 2>/dev/null || uptime | awk '{print $3, $4}')"
  286.  
  287. section "Power"
  288. if command -v upower &>/dev/null; then
  289.     AC=$(upower -i /org/freedesktop/UPower/devices/line_power_AC 2>/dev/null | grep "online" | awk '{print $2}')
  290.     if [ "$AC" = "yes" ]; then
  291.         ok "On AC power — good for inference"
  292.     elif [ "$AC" = "no" ]; then
  293.         warn "On battery — PLUG IN before running inference (2x slower on battery)"
  294.     fi
  295. fi
  296.  
  297. section "CPU Temperature"
  298. if command -v sensors &>/dev/null; then
  299.     sensors 2>/dev/null | grep -iE "core|temp|package" | head -5 | sed 's/^/  /'
  300. elif [ -d /sys/class/thermal ]; then
  301.     for tz in /sys/class/thermal/thermal_zone*/temp; do
  302.         TEMP=$(cat "$tz" 2>/dev/null)
  303.         if [ -n "$TEMP" ]; then
  304.             TEMP_C=$((TEMP / 1000))
  305.             ZONE=$(basename "$(dirname "$tz")")
  306.             if [ "$TEMP_C" -gt 80 ]; then
  307.                 warn "$ZONE: ${TEMP_C}°C — HIGH temperature, throttling risk"
  308.             else
  309.                 ok "$ZONE: ${TEMP_C}°C"
  310.             fi
  311.         fi
  312.     done
  313. else
  314.     warn "Cannot read temperature — install lm-sensors"
  315. fi
  316.  
  317. # =============================================================================
  318. header "APPROACH RECOMMENDATION"
  319. # =============================================================================
  320.  
  321. echo ""
  322. echo -e "${BOLD}Based on this machine's hardware:${NC}"
  323. echo ""
  324.  
  325. # Decision logic
  326. HAS_NVIDIA_GPU=false
  327. VRAM_SUFFICIENT_LARGE=false
  328. VRAM_SUFFICIENT_MEDIUM=false
  329.  
  330. if command -v nvidia-smi &>/dev/null; then
  331.     VRAM_MB=$(nvidia-smi --query-gpu=memory.total --format=csv,noheader,nounits 2>/dev/null | head -1 | tr -d ' ')
  332.     if [ -n "$VRAM_MB" ] 2>/dev/null; then
  333.         HAS_NVIDIA_GPU=true
  334.         [ "$VRAM_MB" -ge 10000 ] 2>/dev/null && VRAM_SUFFICIENT_LARGE=true
  335.         [ "$VRAM_MB" -ge 5000 ] 2>/dev/null && VRAM_SUFFICIENT_MEDIUM=true
  336.     fi
  337. fi
  338.  
  339. if $VRAM_SUFFICIENT_LARGE; then
  340.     echo -e "  ${GREEN}★ RECOMMENDATION: Approach B — WhisperX (large-v3 on GPU)${NC}"
  341.     echo "    Best accuracy (~3-4% WER), speaker diarization, free"
  342.     echo "    Estimated time: ~5 hours for 4 episodes"
  343. elif $VRAM_SUFFICIENT_MEDIUM; then
  344.     echo -e "  ${GREEN}★ RECOMMENDATION: Approach B — WhisperX (medium on GPU)${NC}"
  345.     echo "    Good accuracy (~4% WER), speaker diarization, free"
  346.     echo "    Estimated time: ~5 hours for 4 episodes"
  347. elif [ "$AVAILABLE_MB" -ge 14000 ] 2>/dev/null; then
  348.     echo -e "  ${YELLOW}★ RECOMMENDATION: Approach A — Groq API (free, fast)${NC}"
  349.     echo "    Alternative: WhisperX on CPU (large-v3) but ~50 hours!"
  350.     echo "    Estimated time with Groq: ~5 minutes"
  351. else
  352.     echo -e "  ${YELLOW}★ RECOMMENDATION: Approach A — Groq API (free, fast)${NC}"
  353.     echo "    Insufficient hardware for local inference"
  354.     echo "    Estimated time: ~5 minutes"
  355. fi
  356.  
  357. echo ""
  358. echo "  For proper noun accuracy (Dallaire, Habyarimana, Interahamwe):"
  359. echo -e "  ${CYAN}→ Add Approach C (Google Cloud STT, ~\$5) with custom vocabulary${NC}"
  360.  
  361. echo ""
  362. echo -e "${CYAN}═══════════════════════════════════════════════════════════════${NC}"
  363. echo -e "${BOLD}  See docs/en/13-transcription-runbook.md for full instructions${NC}"
  364. echo -e "${CYAN}═══════════════════════════════════════════════════════════════${NC}"
  365. echo ""
Add Comment
Please, Sign In to add comment