multimodalart's picture
multimodalart HF Staff
Upload folder using huggingface_hub
4d7f061 verified
Raw History Blame Contribute Delete
3.35 kB
"""Command-line inference for WhisperPro and TextPro-SLM."""
import argparse
import json
import numpy as np
import torch
from .audio import WhisperProEncoder
from .model import SYSTEM_PROMPTS, TextProSLM
def main():
# No --instruction: the question/instruction is spoken in the audio.
# With --instruction: append the supplied text after the ASR transcript.
parser = argparse.ArgumentParser(description="Speech understanding with TextPro-SLM")
parser.add_argument("--model", default="qqjz/TextPro-SLM-7B-Global")
parser.add_argument("--encoder", help="Optional paired local WhisperPro directory")
parser.add_argument("--revision", help="Optional model Hub revision; defaults to the verified release")
parser.add_argument("--cache-dir", help="Hugging Face model cache directory")
parser.add_argument("--audio", required=True)
parser.add_argument("--instruction", default="", help="Optional text instruction; omit for audio-only QA")
parser.add_argument("--task", choices=SYSTEM_PROMPTS, default="semantic",
help="System prompt: semantic for spoken QA, emotion for AIR-Bench emotion, audio for other audio QA")
parser.add_argument("--device", default="cuda")
parser.add_argument("--max-new-tokens", type=int, default=512, help="Maximum reply tokens (paper: 512)")
parser.add_argument("--temperature", type=float, default=.7, help="Sampling temperature (paper: 0.7)")
parser.add_argument("--top-p", type=float, default=.9, help="Nucleus sampling threshold (paper: 0.9)")
parser.add_argument("--greedy", action="store_true", help="Use greedy decoding instead of the paper's sampling policy")
parser.add_argument("--seed", type=int, default=42)
args = parser.parse_args()
torch.set_num_threads(1)
torch.manual_seed(args.seed)
model = TextProSLM(model=args.model, encoder=args.encoder, device=args.device,
revision=args.revision, cache_dir=args.cache_dir)
# The paper uses sampling. Greedy is an optional user-selected alternative.
result = model.respond(
audio=args.audio, instruction=args.instruction, task=args.task,
max_new_tokens=args.max_new_tokens, do_sample=not args.greedy,
temperature=args.temperature, top_p=args.top_p,
)
print(json.dumps(result, ensure_ascii=False, indent=2))
def encode_main():
parser = argparse.ArgumentParser(description="Extract a transcript and prosody with WhisperPro")
parser.add_argument("--model", default="qqjz/WhisperPro")
parser.add_argument("--audio", required=True)
parser.add_argument("--device", default="cuda")
parser.add_argument("--revision")
parser.add_argument("--cache-dir")
parser.add_argument("--token-level", action="store_true", help="Return token-aligned states for original WhisperPro")
parser.add_argument("--prosody-output", help="Optional output .npy file")
args = parser.parse_args()
torch.set_num_threads(1)
encoder = WhisperProEncoder(args.model, args.device, args.revision, cache_dir=args.cache_dir)
result = encoder.encode(args.audio, args.token_level)
prosody = result.pop("prosody")
if args.prosody_output:
np.save(args.prosody_output, prosody)
result["prosody_shape"] = list(prosody.shape)
print(json.dumps(result, ensure_ascii=False, indent=2))