vllm/server.py

87 lines
3.2 KiB
Python
Raw Normal View History

2023-02-24 01:33:37 +00:00
import argparse
from typing import List
2023-02-24 11:56:21 +00:00
from cacheflow.master.frontend import Frontend
2023-02-24 01:33:37 +00:00
from cacheflow.master.scheduler import Scheduler
from cacheflow.models import get_memory_analyzer
2023-02-24 01:33:37 +00:00
from cacheflow.worker.controller import Controller
parser = argparse.ArgumentParser(description='CacheFlow server')
parser.add_argument('--model', type=str, default='facebook/opt-125m', help='model name')
parser.add_argument('--num-nodes', type=int, default=1, help='number of nodes')
parser.add_argument('--num-workers', type=int, default=1, help='number of workers per node')
parser.add_argument('--block-size', type=int, default=8, choices=[8, 16], help='token block size')
# NOTE(woosuk): If FlashAttention is used, the float data type is not supported.
parser.add_argument('--dtype', type=str, default='half', choices=['half', 'float'], help='data type')
# TODO(woosuk): Support fine-grained seeds (e.g., seed per request).
parser.add_argument('--seed', type=int, default=0, help='random seed')
2023-03-13 13:48:38 -07:00
parser.add_argument('--swap-space', type=int, default=20, help='CPU swap space size (GiB) per GPU')
parser.add_argument('--max-batch-size', type=int, default=2560, help='maximum number of batched tokens')
2023-02-24 11:56:21 +00:00
args = parser.parse_args()
2023-02-24 01:33:37 +00:00
def main():
memory_analyzer = get_memory_analyzer(
model_name=args.model,
block_size=args.block_size,
dtype=args.dtype,
)
num_gpu_blocks = memory_analyzer.get_max_num_gpu_blocks(
max_num_batched_tokens=args.max_batch_size)
2023-03-13 13:48:38 -07:00
num_cpu_blocks = memory_analyzer.get_max_num_cpu_blocks(
swap_space=args.swap_space)
print(f'# GPU blocks: {num_gpu_blocks}, # CPU blocks: {num_cpu_blocks}')
2023-02-24 11:56:21 +00:00
# Create a controller for each node.
2023-02-24 01:33:37 +00:00
controllers: List[Controller] = []
for i in range(args.num_nodes):
controller = Controller(
node_id=i,
num_workers=args.num_workers,
model_name=args.model,
block_size=args.block_size,
num_gpu_blocks=num_gpu_blocks,
num_cpu_blocks=num_cpu_blocks,
dtype=args.dtype,
seed=args.seed,
2023-02-24 01:33:37 +00:00
)
controllers.append(controller)
2023-02-24 11:56:21 +00:00
# Create a frontend.
frontend = Frontend(
model_name=args.model,
block_size=args.block_size,
)
2023-02-24 01:33:37 +00:00
# Create a scheduler.
scheduler = Scheduler(
2023-02-24 11:56:21 +00:00
frontend=frontend,
2023-02-24 01:33:37 +00:00
controllers=controllers,
block_size=args.block_size,
num_gpu_blocks=num_gpu_blocks,
num_cpu_blocks=num_cpu_blocks,
max_num_batched_tokens=args.max_batch_size,
2023-02-24 01:33:37 +00:00
)
# Connect the controllers.
for i in range(len(controllers) - 1):
controllers[i].set_next(controllers[i + 1])
controllers[-1].set_next(scheduler)
# Test the following inputs.
2023-02-24 11:56:21 +00:00
test_inputs = [
('Ion Stoica is a', {'n': 4, 'use_beam_search': True, 'temperature': 0.0}),
('UC Berkeley is', {'n': 3, 'temperature': 0.8, 'top_p': 0.99}),
('The future of cloud computing is', {}), # Use default parameters.
2023-02-24 11:56:21 +00:00
]
while True:
2023-03-06 10:05:27 -08:00
if test_inputs:
text, sampling_params = test_inputs.pop(0)
frontend.query(text, **sampling_params)
2023-02-24 01:33:37 +00:00
scheduler.step()
if not (scheduler.pending or scheduler.running or test_inputs):
2023-02-24 11:56:21 +00:00
break
2023-02-24 01:33:37 +00:00
if __name__ == '__main__':
main()