vllm-allocation
vllm/vllm/v1/core/sched/scheduler.py · ef9339e · L922–1028 · 固定 commit 上游
这是固定版本源码的只读摘录;可在线阅读,也可通过上游链接查看原文件。
922 request,
923 num_new_tokens,
924 num_lookahead_tokens=self.num_lookahead_tokens,
925 )
926
927 if new_blocks is not None:
928 # The request can be scheduled.
929 break
930
931 if (
932 self.connector is not None
933 and self.connector.has_pending_block_frees()
934 ):
935 break
936
937 # The request cannot be scheduled.
938 # Preempt the lowest-priority request.
939 if self.policy == SchedulingPolicy.PRIORITY:
940 preempted_req = max(
941 self.running,
942 key=lambda r: (r.priority, r.arrival_time),
943 )
944 else:
945 preempted_req = self.running[-1]
946
947 # A deferred free will not help with immediate allocation.
948 if not self._request_blocks_can_be_freed(preempted_req):
949 break
950
951 if self.policy == SchedulingPolicy.PRIORITY:
952 victim_index = self.running.index(preempted_req)
953 del self.running[victim_index]
954 if victim_index < req_index:
955 req_index -= 1
956
957 if preempted_req in scheduled_running_reqs:
958 preempted_req_id = preempted_req.request_id
959 scheduled_running_reqs.remove(preempted_req)
960 restored = num_scheduled_tokens.pop(preempted_req_id)
961 token_budget += restored
962 input_budget += restored + draft_slots
963 req_to_new_blocks.pop(preempted_req_id)
964 scheduled_spec_decode_tokens.pop(preempted_req_id, None)
965 preempted_encoder_inputs = scheduled_encoder_inputs.pop(
966 preempted_req_id, None
967 )
968 if preempted_encoder_inputs:
969 # Restore encoder compute budget if the preempted
970 # request had encoder inputs scheduled in this step.
971 num_embeds_to_restore = sum(
972 preempted_req.get_num_encoder_embeds(i)
973 for i in preempted_encoder_inputs
974 )
975 encoder_compute_budget += num_embeds_to_restore
976 else:
977 preempted_req = self.running.pop()
978
979 self._preempt_request(
980 preempted_req,
981 scheduled_timestamp,
982 drop_stale_output=self.requires_kv_delivery,
983 )
984 preempted_reqs.append(preempted_req)
985 if preempted_req == request:
986 # No more request to preempt. Cannot schedule this request.
987 break
988
989 if new_blocks is None:
990 if (
991 self.policy == SchedulingPolicy.PRIORITY
992 and request.status == RequestStatus.PREEMPTED
993 ):
994 # The request was the lowest-priority running request and
995 # preempted itself. The requests after it have higher
996 # priority and may still fit (it just freed its blocks);
997 # it was removed from `self.running`, so `req_index`
998 # already points at the next one.
999 continue
1000 # Cannot schedule this request.
1001 break
1002
1003 # Schedule the request.
1004 scheduled_running_reqs.append(request)
1005 prefill_scheduled |= request.is_prefill_chunk
1006 request_id = request.request_id
1007 req_to_new_blocks[request_id] = new_blocks
1008 num_scheduled_tokens[request_id] = num_new_tokens
1009 token_budget -= num_new_tokens
1010 input_budget -= num_new_tokens + draft_slots
1011 req_index += 1
1012 drafts_needed = drafts_needed or not self._drafts_unused(
1013 request, request.num_computed_tokens, num_new_tokens
1014 )
1015
1016 # Speculative decode related.
1017 if request.spec_token_ids:
1018 num_scheduled_spec_tokens = (
1019 num_new_tokens
1020 + request.num_computed_tokens
1021 - request.num_tokens
1022 - request.num_output_placeholders
1023 )
1024 if num_scheduled_spec_tokens > 0:
1025 spec_token_ids = request.spec_token_ids
1026 if len(spec_token_ids) > num_scheduled_spec_tokens:
1027 spec_token_ids = spec_token_ids[:num_scheduled_spec_tokens]
1028 scheduled_spec_decode_tokens[request.request_id] = spec_token_ids