forked from novitalabs/pegaflow
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbasic_vllm.py
More file actions
162 lines (137 loc) · 5.24 KB
/
Copy pathbasic_vllm.py
File metadata and controls
162 lines (137 loc) · 5.24 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
"""
Basic vLLM example - Test KV cache save and load with PegaFlow connector
This example demonstrates:
1. First run: Generate text and save KV cache to CPU
2. Second run: Generate same prompt again and load KV cache from CPU
"""
import random
import time
from vllm import LLM, SamplingParams
from vllm.config import KVTransferConfig
def generate_long_prompt(length: int) -> str:
"""Randomly generate a prompt string with (at least) the given length."""
words = [
"apple",
"banana",
"orange",
"kiwi",
"mango",
"grape",
"quantum",
"tensor",
"network",
"compute",
"memory",
"rdma",
"cache",
"pega",
"flow",
"mooncake",
"nvlink",
"distributed",
"system",
"prefill",
"decode",
"chunk",
]
parts = []
total_len = 0
while total_len < length:
w = random.choice(words)
parts.append(w)
total_len += len(w) + 1
full = " ".join(parts)
return full[:length]
def real_long_prompt() -> str:
return (
"Hello, this is a longer piece of text written for testing purposes. "
"Imagine a quiet morning in a small coastal town, the kind of place "
"where the streets are still empty when the sun rises and the smell of "
"the sea drifts in through every open window. The houses stand close "
"together, their walls painted in soft colors that have faded slightly "
"over the years, giving the town a gentle and familiar feeling. "
"A bakery opens its doors early, letting warm air spill out along with "
"the scent of fresh bread. A few fishermen prepare their boats at the "
"harbor, moving slowly and without hurry, as if the rhythm of the town "
"is set by the tide itself. "
"This text continues in a calm and steady way, describing nothing more "
"than simple scenes and small moments. It does not introduce dramatic "
"events or complicated ideas, because its purpose is simply to provide "
"a long, predictable prompt. You can use it to observe whether the "
"system handles extended context normally, without sudden changes in "
"behavior. The tone stays even, the sentences unfold at a relaxed pace, "
"and the details remain grounded in everyday life. "
"If you need an even longer prompt, you can extend this one by adding "
"more scenes from the same quiet town, or simply repeat the structure "
"to create additional length for stress testing."
)
def main():
print("=" * 70)
print("PegaFlow KV Cache Test - Save and Load")
print("=" * 70)
# Configure vLLM to use our PegaKVConnector
kv_transfer_config = KVTransferConfig(
kv_connector="PegaKVConnector",
kv_role="kv_both",
kv_connector_module_path="pegaflow.connector",
)
# Initialize vLLM with GPT-2
print("\n[1/4] Loading model...")
llm = LLM(
model="Qwen/Qwen3-0.6B",
trust_remote_code=True,
enforce_eager=True,
tensor_parallel_size=1,
enable_prefix_caching=False, # Disable vLLM's internal prefix cache
kv_transfer_config=kv_transfer_config,
)
print("✓ Model loaded successfully!")
# Test prompt - use a long prompt (~2048 characters)
print("\n[Generating long prompt (~2048 chars)...]")
prompt = real_long_prompt()
print(f"✓ Generated prompt with {len(prompt)} characters")
print(f"Preview: {prompt[:100]}...")
# Sampling parameters - use temperature=0 for deterministic output
sampling_params = SamplingParams(
temperature=0.0, # Deterministic
max_tokens=50,
)
# First run: Generate and save KV cache
print("\n" + "=" * 70)
print("[2/4] First run - Generating text (will save KV cache to CPU)...")
print("=" * 70)
start_time = time.time()
outputs = llm.generate([prompt], sampling_params)
first_run_time = time.time() - start_time
first_output = outputs[0].outputs[0].text
print(f"\nPrompt length: {len(prompt)} chars")
print(f"Prompt preview: {prompt[:100]}...")
print(f"Generated: {first_output}")
print(f"Time: {first_run_time:.3f}s")
# Second run: Same prompt, should load from CPU cache
print("\n" + "=" * 70)
print("[3/4] Second run - Same prompt (should load KV cache from CPU)...")
print("=" * 70)
start_time = time.time()
outputs = llm.generate([prompt], sampling_params)
second_run_time = time.time() - start_time
second_output = outputs[0].outputs[0].text
print(f"\nPrompt length: {len(prompt)} chars")
print(f"Prompt preview: {prompt[:100]}...")
print(f"Generated: {second_output}")
print(f"Time: {second_run_time:.3f}s")
# Compare results
print("\n" + "=" * 70)
print("[4/4] Results Summary")
print("=" * 70)
print(f"First run time: {first_run_time:.3f}s")
print(f"Second run time: {second_run_time:.3f}s")
if first_output == second_output:
print("✓ Outputs match (deterministic generation working)")
else:
print("✗ Outputs differ (unexpected)")
print("\n" + "=" * 70)
print("Test completed!")
print("=" * 70)
if __name__ == "__main__":
main()