Skill: sherajdev/pocket-tts (version 1.0.1)

# Pocket TTS Skill Fully local, offline text-to-speech using Kyutai's Pocket TTS model. Generate high-quality audio from text without any API calls or internet connection. Features 8 built-in voices, voice cloning support, and runs entirely on CPU. ## Features - 🎯 **Fully local** - No API calls, runs completely offline - 🚀 **CPU-only** - No GPU required, works on any computer - ⚡ **Fast generation** - ~2-6x real-time on CPU - 🎤 **8 built-in voices** - alba, marius, javert, jean, fantine, cosette, eponine, azelma - 🎭 **Voice cloning** - Clone any voice from a WAV sample - 🔊 **Low latency** - ~200ms first audio chunk - 📚 **Simple Python API** - Easy integration into any project ## Installation ```bash # 1. Accept the model license on Hugging Face # https://huggingface.co/kyutai/pocket-tts # 2. Install the package pip install pocket-tts # Or use uv for automatic dependency management uvx pocket-tts generate "Hello world" ``` ## Usage ### CLI ```bash # Basic usage pocket-tts "Hello, I am your AI assistant" # With specific voice pocket-tts "Hello" --voice alba --output hello.wav # With custom voice file (voice cloning) pocket-tts "Hello" --voice-file myvoice.wav --output output.wav # Adjust speed pocket-tts "Hello" --speed 1.2 # Start local server pocket-tts --serve # List available voices pocket-tts --list-voices ``` ### Python API ```python from pocket_tts import TTSModel import scipy.io.wavfile # Load model tts_model = TTSModel.load_model() # Get voice state voice_state = tts_model.get_state_for_audio_prompt( "hf://kyutai/tts-voices/alba-mackenna/casual.wav" ) # Generate audio audio = tts_model.generate_audio(voice_state, "Hello world!") # Save to WAV scipy.io.wavfile.write("output.wav", tts_model.sample_rate, audio.numpy()) # Check sample rate print(f"Sample rate: {tts_model.sample_rate} Hz") ``` ## Available Voices | Voice | Description | |-------|-------------| | alba | Casual female voice | | marius | Male voice | | javert | Clear male voice | | jean | Natural male voice | | fantine | Female voice | | cosette | Female voice | | eponine | Female voice | | azelma | Female voice | Or use `--voice-file /path/to/wav.wav` for custom voice cloning. ## Options | Option | Description | Default | |--------|-------------|---------| | `text` | Text to convert | Required | | `-o, --output` | Output WAV file | `output.wav` | | `-v, --voice` | Voice preset | `alba` | | `-s, --speed` | Speech speed (0.5-2.0) | `1.0` | | `--voice-file` | Custom WAV for cloning | None | | `--serve` | Start HTTP server | False | | `--list-voices` | List all voices | False | ## Requirements - Python 3.10-3.14 - PyTorch 2.5+ (CPU version works) - Works on 2 CPU cores ## Notes - ⚠️ Model is gated - accept license on Hugging Face first - 🌍 English language only (v1) - 💾 First run downloads model (~100M parameters) - 🔊 Audio is returned as 1D torch tensor (PCM data) ## Links - [Demo](https://kyutai.org/tts) - [GitHub](https://github.com/kyutai-labs/pocket-tts) - [Hugging Face](https://huggingface.co/kyutai/pocket-tts) - [Paper](https://arxiv.org/abs/2509.06926)

path: cli.py
content: #!/usr/bin/env python3
"""
Pocket TTS - Local text-to-speech using Kyutai's Pocket TTS model

Usage:
    pocket-tts "Your text here" [--output FILE] [--voice VOICE] [--speed FLOAT]

Installation:
    pip install pocket-tts

Note: You must accept the model license at:
    https://huggingface.co/kyutai/pocket-tts
"""

import argparse
import os
import sys
from pathlib import Path

try:
    from pocket_tts import TTSModel
    import scipy.io.wavfile
except ImportError:
    print("❌ Pocket TTS not installed.")
    print("Install with: pip install pocket-tts")
    print("")
    print("⚠️  Accept the model license first:")
    print("   https://huggingface.co/kyutai/pocket-tts")
    sys.exit(1)

# Available voices
VOICES = [
    "alba", "marius", "javert", "jean", 
    "fantine", "cosette", "eponine", "azelma"
]

def main():
    parser = argparse.ArgumentParser(
        description="Pocket TTS - Local text-to-speech",
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog="""
Available voices:
  alba, marius, javert, jean, fantine, cosette, eponine, azelma

Examples:
  pocket-tts "Hello world"
  pocket-tts "Hello" --voice alba --output hello.wav
  pocket-tts "Text-to-speech is awesome" --speed 1.2
        """
    )
    parser.add_argument(
        "text",
        nargs="?",
        help="Text to convert to speech"
    )
    parser.add_argument(
        "-o", "--output",
        default="output.wav",
        help="Output WAV file (default: output.wav)"
    )
    parser.add_argument(
        "-v", "--voice",
        default="alba",
        choices=VOICES,
        help=f"Voice preset (default: alba)"
    )
    parser.add_argument(
        "-s", "--speed",
        type=float,
        default=1.0,
        help="Speech speed 0.5-2.0 (default: 1.0)"
    )
    parser.add_argument(
        "--voice-file",
        help="Use custom WAV file for voice cloning"
    )
    parser.add_argument(
        "--serve",
        action="store_true",
        help="Start local TTS server"
    )
    parser.add_argument(
        "--list-voices",
        action="store_true",
        help="List available voices"
    )
    
    args = parser.parse_args()
    
    if args.list_voices:
        print("🎤 Available voices:")
        for voice in VOICES:
            print(f"   - {voice}")
        print("")
        print("Or use --voice-file /path/to/voice.wav for custom voice cloning")
        sys.exit(0)
    
    if args.serve:
        print("🚀 Starting Pocket TTS server on http://localhost:8000")
        os.system("pocket-tts serve")
        sys.exit(0)
    
    if not args.text:
        parser.print_help()
        print("\n💡 Tip: pocket-tts \"Hello, world!\"")
        sys.exit(1)
    
    print(f"🔊 Generating speech...")
    print(f"📝 Text: {args.text[:60]}{'...' if len(args.text) > 60 else ''}")
    print(f"🎤 Voice: {args.voice}")
    
    try:
        # Load model
        tts_model = TTSModel.load_model()
        
        # Get voice state
        if args.voice_file:
            voice_state = tts_model.get_state_for_audio_prompt(args.voice_file)
            print(f"🎭 Using custom voice from: {args.voice_file}")
        else:
            voice_state = tts_model.get_state_for_audio_prompt(
                f"hf://kyutai/tts-voices/{args.voice}-mackenna/casual.wav"
            )
        
        # Generate audio
        audio = tts_model.generate_audio(voice_state, args.text)
        
        # Save audio
        wavfile.write(args.output, tts_model.sample_rate, audio.numpy())
        
        print(f"✅ Saved to: {args.output}")
        print(f"📊 Sample rate: {tts_model.sample_rate} Hz")
        print(f"📏 Audio length: {len(audio) / tts_model.sample_rate:.2f}s")
        
    except Exception as e:
        print(f"❌ Error: {e}")
        print("")
        print("Make sure you've accepted the model license at:")
        print("   https://huggingface.co/kyutai/pocket-tts")
        sys.exit(1)

if __name__ == "__main__":
    main()


path: install.sh
content: #!/bin/bash
# Install script for Pocket TTS skill

echo "📦 Installing Pocket TTS dependencies..."

pip install torch scipy huggingface_hub

echo ""
echo "✅ Dependencies installed!"
echo ""
echo "⚠️  IMPORTANT: Accept the model license at:"
echo "   https://huggingface.co/kyutai/pocket-tts"
echo ""
echo "Then test with:"
echo "   pocket-tts --model"


path: test.sh
content: #!/bin/bash
# Quick test script for Pocket TTS skill

echo "🧪 Testing Pocket TTS installation..."

# Check if package is installed
if ! python -c "import pocket_tts" 2>/dev/null; then
    echo "❌ pocket-tts not installed"
    echo "Run: pip install pocket-tts"
    exit 1
fi

echo "✅ pocket-tts package installed"

# Test basic import
python -c "
from pocket_tts import TTSModel
print('✅ TTSModel imported successfully')
"

echo ""
echo "📋 Skill files created:"
ls -la /home/clawdbot/clawd/skills/pocket-tts/

echo ""
echo "💡 Usage:"
echo "   pocket-tts \"Hello world\" --output test.wav"
echo "   python /home/clawdbot/clawd/skills/pocket-tts/cli.py \"Test\""


Security scan verdicts — ClawScan: clean | static analysis: clean | VirusTotal: clean | SkillSpector: suspicious (MEDIUM)