Views
No views yet





transformers from the main branch. Below is a simple example of how to use the granite-speech-3.3-8b revision 3.3.2 model.transformerspip install transformers>=4.52.4 torchaudio peft soundfile1import torch
2import torchaudio
3from transformers import AutoProcessor, AutoModelForSpeechSeq2Seq
4from huggingface_hub import hf_hub_download
5
6device = "cuda" if torch.cuda.is_available() else "cpu"
7
8model_name = "ibm-granite/granite-speech-3.3-8b"
9processor = AutoProcessor.from_pretrained(model_name)
10tokenizer = processor.tokenizer
11model = AutoModelForSpeechSeq2Seq.from_pretrained(
12 model_name, device_map=device, torch_dtype=torch.bfloat16
13)
14# load audio
15audio_path = hf_hub_download(repo_id=model_name, filename="10226_10111_000000.wav")
16wav, sr = torchaudio.load(audio_path, normalize=True)
17assert wav.shape[0] == 1 and sr == 16000 # mono, 16khz
18
19# create text prompt
20system_prompt = "Knowledge Cutoff Date: April 2024.\nToday's Date: April 9, 2025.\nYou are Granite, developed by IBM. You are a helpful AI assistant"
21user_prompt = "<|audio|>can you transcribe the speech into a written format?"
22chat = [
23 dict(role="system", content=system_prompt),
24 dict(role="user", content=user_prompt),
25]
26prompt = tokenizer.apply_chat_template(chat, tokenize=False, add_generation_prompt=True)
27
28# run the processor+model
29model_inputs = processor(prompt, wav, device=device, return_tensors="pt").to(device)
30model_outputs = model.generate(**model_inputs, max_new_tokens=200, do_sample=False, num_beams=1)
31
32# Transformers includes the input IDs in the response.
33num_input_tokens = model_inputs["input_ids"].shape[-1]
34new_tokens = torch.unsqueeze(model_outputs[0, num_input_tokens:], dim=0)
35output_text = tokenizer.batch_decode(
36 new_tokens, add_special_tokens=False, skip_special_tokens=True
37)
38print(f"STT output = {output_text[0].upper()}")vLLMpip install vllm --upgrade1from transformers import AutoTokenizer
2from vllm import LLM, SamplingParams
3from vllm.assets.audio import AudioAsset
4from vllm.lora.request import LoRARequest
5
6model_id = "ibm-granite/granite-speech-3.3-8b"
7tokenizer = AutoTokenizer.from_pretrained(model_id)
8
9def get_prompt(question: str, has_audio: bool):
10 """Build the input prompt to send to vLLM."""
11 if has_audio:
12 question = f"<|audio|>{question}"
13 chat = [
14 {
15 "role": "user",
16 "content": question
17 }
18 ]
19 return tokenizer.apply_chat_template(chat, tokenize=False)
20
21# NOTE - you may see warnings about multimodal lora layers being ignored;
22# this is okay as the lora in this model is only applied to the LLM.
23model = LLM(
24 model=model_id,
25 enable_lora=True,
26 max_lora_rank=64,
27 max_model_len=2048, # This may be needed for lower resource devices.
28 limit_mm_per_prompt={"audio": 1},
29)
30
31### 1. Example with Audio [make sure to use the lora]
32question = "can you transcribe the speech into a written format?"
33prompt_with_audio = get_prompt(
34 question=question,
35 has_audio=True,
36)
37audio = AudioAsset("mary_had_lamb").audio_and_sample_rate
38
39inputs = {
40 "prompt": prompt_with_audio,
41 "multi_modal_data": {
42 "audio": audio,
43 }
44}
45
46outputs = model.generate(
47 inputs,
48 sampling_params=SamplingParams(
49 temperature=0.2,
50 max_tokens=64,
51 ),
52 lora_request=[LoRARequest("speech", 1, model_id)]
53)
54print(f"Audio Example - Question: {question}")
55print(f"Generated text: {outputs[0].outputs[0].text}")
56
57
58### 2. Example without Audio [do NOT use the lora]
59question = "What is the capital of Brazil?"
60prompt = get_prompt(
61 question=question,
62 has_audio=False,
63)
64
65outputs = model.generate(
66 {"prompt": prompt},
67 sampling_params=SamplingParams(
68 temperature=0.2,
69 max_tokens=12,
70 ),
71)
72print(f"Text Only Example - Question: {question}")
73print(f"Generated text: {outputs[0].outputs[0].text}")1"""
2Launch the vLLM server with the following command:
3
4vllm serve ibm-granite/granite-speech-3.3-8b \
5 --api-key token-abc123 \
6 --max-model-len 2048 \
7 --enable-lora \
8 --lora-modules speech=ibm-granite/granite-speech-3.3-8b \
9 --max-lora-rank 64
10"""
11
12import base64
13
14import requests
15from openai import OpenAI
16
17from vllm.assets.audio import AudioAsset
18
19# Modify OpenAI's API key and API base to use vLLM's API server.
20openai_api_key = "token-abc123"
21openai_api_base = "http://localhost:8000/v1"
22
23client = OpenAI(
24 # defaults to os.environ.get("OPENAI_API_KEY")
25 api_key=openai_api_key,
26 base_url=openai_api_base,
27)
28
29base_model_name = "ibm-granite/granite-speech-3.3-8b"
30lora_model_name = "speech"
31# Any format supported by librosa is supported
32audio_url = AudioAsset("mary_had_lamb").url
33
34# Use base64 encoded audio in the payload
35def encode_audio_base64_from_url(audio_url: str) -> str:
36 """Encode an audio retrieved from a remote url to base64 format."""
37 with requests.get(audio_url) as response:
38 response.raise_for_status()
39 result = base64.b64encode(response.content).decode('utf-8')
40 return result
41
42audio_base64 = encode_audio_base64_from_url(audio_url=audio_url)
43
44### 1. Example with Audio
45# NOTE: we pass the name of the lora model (`speech`) here because we have audio.
46question = "can you transcribe the speech into a written format?"
47chat_completion_with_audio = client.chat.completions.create(
48 messages=[{
49 "role": "user",
50 "content": [
51 {
52 "type": "text",
53 "text": question
54 },
55 {
56 "type": "audio_url",
57 "audio_url": {
58 # Any format supported by librosa is supported
59 "url": f"data:audio/ogg;base64,{audio_base64}"
60 },
61 },
62 ],
63 }],
64 temperature=0.2,
65 max_tokens=64,
66 model=lora_model_name,
67)
68
69
70print(f"Audio Example - Question: {question}")
71print(f"Generated text: {chat_completion_with_audio.choices[0].message.content}")
72
73
74### 2. Example without Audio
75# NOTE: we pass the name of the base model here because we do not have audio.
76question = "What is the capital of Brazil?"
77chat_completion_with_audio = client.chat.completions.create(
78 messages=[{
79 "role": "user",
80 "content": [
81 {
82 "type": "text",
83 "text": question
84 },
85 ],
86 }],
87 temperature=0.2,
88 max_tokens=12,
89 model=base_model_name,
90)
91
92print(f"Text Only Example - Question: {question}")
93print(f"Generated text: {chat_completion_with_audio.choices[0].message.content}")| Configuration parameter | Value |
|---|---|
| Input dimension | 160 (80 logmels x 2) |
| Nb. of layers | 16 |
| Hidden dimension | 1024 |
| Nb. of attention heads | 8 |
| Attention head size | 128 |
| Convolution kernel size | 15 |
| Output dimension | 256 |