Views
No views yet
1from vllm.assets.audio import AudioAsset
2from vllm import LLM, SamplingParams
3
4# prepare model
5llm = LLM(
6 model="neuralmagic/whisper-large-v3.w4a16",
7 max_model_len=448,
8 max_num_seqs=400,
9 limit_mm_per_prompt={"audio": 1},
10)
11
12# prepare inputs
13inputs = { # Test explicit encoder/decoder prompt
14 "encoder_prompt": {
15 "prompt": "",
16 "multi_modal_data": {
17 "audio": AudioAsset("winning_call").audio_and_sample_rate,
18 },
19 },
20 "decoder_prompt": "<|startoftranscript|>",
21}
22
23# generate response
24print("========== SAMPLE GENERATION ==============")
25outputs = llm.generate(inputs, SamplingParams(temperature=0.0, max_tokens=64))
26print(f"PROMPT : {outputs[0].prompt}")
27print(f"RESPONSE: {outputs[0].outputs[0].text}")
28print("==========================================")1import torch
2from datasets import load_dataset
3from transformers import WhisperProcessor
4
5from llmcompressor.modifiers.quantization import GPTQModifier
6from llmcompressor.transformers import oneshot
7from llmcompressor.transformers.tracing import TraceableWhisperForConditionalGeneration
8
9# Select model and load it.
10MODEL_ID = "openai/whisper-large-v3"
11
12model = TraceableWhisperForConditionalGeneration.from_pretrained(
13 MODEL_ID,
14 device_map="auto",
15 torch_dtype="auto",
16)
17model.config.forced_decoder_ids = None
18processor = WhisperProcessor.from_pretrained(MODEL_ID)
19
20# Configure processor the dataset task.
21processor.tokenizer.set_prefix_tokens(language="en", task="transcribe")
22
23# Select calibration dataset.
24DATASET_ID = "MLCommons/peoples_speech"
25DATASET_SUBSET = "test"
26DATASET_SPLIT = "test"
27
28# Select number of samples. 512 samples is a good place to start.
29# Increasing the number of samples can improve accuracy.
30NUM_CALIBRATION_SAMPLES = 512
31MAX_SEQUENCE_LENGTH = 2048
32
33# Load dataset and preprocess.
34ds = load_dataset(
35 DATASET_ID,
36 DATASET_SUBSET,
37 split=f"{DATASET_SPLIT}[:{NUM_CALIBRATION_SAMPLES}]",
38 trust_remote_code=True,
39)
40
41
42def preprocess(example):
43 return {
44 "array": example["audio"]["array"],
45 "sampling_rate": example["audio"]["sampling_rate"],
46 "text": " " + example["text"].capitalize(),
47 }
48
49
50ds = ds.map(preprocess, remove_columns=ds.column_names)
51
52
53# Process inputs.
54def process(sample):
55 inputs = processor(
56 audio=sample["array"],
57 sampling_rate=sample["sampling_rate"],
58 text=sample["text"],
59 add_special_tokens=True,
60 return_tensors="pt",
61 )
62
63 inputs["input_features"] = inputs["input_features"].to(dtype=model.dtype)
64 inputs["decoder_input_ids"] = inputs["labels"]
65 del inputs["labels"]
66
67 return inputs
68
69
70ds = ds.map(process, remove_columns=ds.column_names)
71
72
73# Define a oneshot data collator for multimodal inputs.
74def data_collator(batch):
75 assert len(batch) == 1
76 return {key: torch.tensor(value) for key, value in batch[0].items()}
77
78
79# Recipe
80recipe = GPTQModifier(targets="Linear", scheme="W4A16", ignore=["lm_head"])
81
82# Apply algorithms.
83oneshot(
84 model=model,
85 dataset=ds,
86 recipe=recipe,
87 max_seq_length=MAX_SEQUENCE_LENGTH,
88 num_calibration_samples=NUM_CALIBRATION_SAMPLES,
89 data_collator=data_collator,
90)
91
92# Confirm generations of the quantized model look sane.
93print("\n\n")
94print("========== SAMPLE GENERATION ==============")
95sample_features = next(iter(ds))["input_features"]
96sample_decoder_ids = [processor.tokenizer.prefix_tokens]
97sample_input = {
98 "input_features": torch.tensor(sample_features).to(model.device),
99 "decoder_input_ids": torch.tensor(sample_decoder_ids).to(model.device),
100}
101
102output = model.generate(**sample_input, language="en")
103print(processor.batch_decode(output, skip_special_tokens=True))
104print("==========================================\n\n")
105# that's where you have a lot of windows in the south no actually that's passive solar
106# and passive solar is something that was developed and designed in the 1960s and 70s
107# and it was a great thing for what it was at the time but it's not a passive house
108
109# Save to disk compressed.
110SAVE_DIR = MODEL_ID.split("/")[1] + "-W4A16-G128"
111model.save_pretrained(SAVE_DIR, save_compressed=True)
112processor.save_pretrained(SAVE_DIR)Total Test Time: 94.4606 seconds
Total Requests: 511
Successful Requests: 511
Average Latency: 53.3529 seconds
Median Latency: 52.7258 seconds
95th Percentile Latency: 86.5851 seconds
Estimated req_Throughput: 5.41 requests/s
Estimated Throughput: 100.79 tok/s
WER: 12.660815197787665Total Test Time: 106.2064 seconds
Total Requests: 511
Successful Requests: 511
Average Latency: 59.7467 seconds
Median Latency: 58.3930 seconds
95th Percentile Latency: 97.4831 seconds
Estimated req_Throughput: 4.81 requests/s
Estimated Throughput: 89.35 tok/s
WER: 12.9493807863412281@misc{radford2022whisper,
2 doi = {10.48550/ARXIV.2212.04356},
3 url = {https://arxiv.org/abs/2212.04356},
4 author = {Radford, Alec and Kim, Jong Wook and Xu, Tao and Brockman, Greg and McLeavey, Christine and Sutskever, Ilya},
5 title = {Robust Speech Recognition via Large-Scale Weak Supervision},
6 publisher = {arXiv},
7 year = {2022},
8 copyright = {arXiv.org perpetual, non-exclusive license}
9}