fix missing output_token_logprobs when using ngram speculative decoding (#10702)
Co-authored-by: a4zhangfei <a4zhangfei@qq.com>
This commit is contained in:
co-authored by
a4zhangfei
parent
611a4fd08b
commit
6f08488042
@@ -1,9 +1,16 @@
|
|||||||
#include "ngram.h"
|
#include "ngram.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <chrono>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
#include <list>
|
||||||
|
#include <mutex>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <thread>
|
||||||
|
#include <tuple>
|
||||||
|
#include <unordered_map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace ngram {
|
namespace ngram {
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#include <functional>
|
#include <functional>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
#include <new>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
#include <cstdlib>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <regex>
|
#include <regex>
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <condition_variable>
|
#include <condition_variable>
|
||||||
|
#include <mutex>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
namespace utils {
|
namespace utils {
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ import numpy as np
|
|||||||
import torch
|
import torch
|
||||||
from sgl_kernel.speculative import reconstruct_indices_from_tree_mask
|
from sgl_kernel.speculative import reconstruct_indices_from_tree_mask
|
||||||
|
|
||||||
|
from sglang.srt.layers.logits_processor import LogitsProcessorOutput
|
||||||
|
from sglang.srt.layers.sampler import get_token_ids_logprobs, get_top_logprobs
|
||||||
from sglang.srt.managers.schedule_batch import ScheduleBatch
|
from sglang.srt.managers.schedule_batch import ScheduleBatch
|
||||||
from sglang.srt.managers.scheduler import GenerationBatchResult
|
from sglang.srt.managers.scheduler import GenerationBatchResult
|
||||||
from sglang.srt.managers.tp_worker import TpModelWorker
|
from sglang.srt.managers.tp_worker import TpModelWorker
|
||||||
@@ -13,9 +15,12 @@ from sglang.srt.server_args import ServerArgs
|
|||||||
from sglang.srt.speculative.cpp_ngram.ngram_cache import NgramCache
|
from sglang.srt.speculative.cpp_ngram.ngram_cache import NgramCache
|
||||||
from sglang.srt.speculative.ngram_info import NgramVerifyInput
|
from sglang.srt.speculative.ngram_info import NgramVerifyInput
|
||||||
from sglang.srt.speculative.spec_info import SpeculativeAlgorithm
|
from sglang.srt.speculative.spec_info import SpeculativeAlgorithm
|
||||||
|
from sglang.srt.utils import get_bool_env_var
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
RETURN_ORIGINAL_LOGPROB = get_bool_env_var("RETURN_ORIGINAL_LOGPROB")
|
||||||
|
|
||||||
USE_FULL_MASK = True
|
USE_FULL_MASK = True
|
||||||
|
|
||||||
|
|
||||||
@@ -194,6 +199,85 @@ class NGRAMWorker:
|
|||||||
)
|
)
|
||||||
batch.spec_info.prepare_for_verify(batch, self.page_size)
|
batch.spec_info.prepare_for_verify(batch, self.page_size)
|
||||||
|
|
||||||
|
def add_logprob_values(
|
||||||
|
self,
|
||||||
|
batch: ScheduleBatch,
|
||||||
|
res: NgramVerifyInput,
|
||||||
|
logits_output: LogitsProcessorOutput,
|
||||||
|
):
|
||||||
|
# Extract args
|
||||||
|
top_logprobs_nums = batch.top_logprobs_nums
|
||||||
|
token_ids_logprobs = batch.token_ids_logprobs
|
||||||
|
accepted_indices = res.accept_index
|
||||||
|
assert len(accepted_indices) == len(logits_output.next_token_logits)
|
||||||
|
|
||||||
|
temperatures = batch.sampling_info.temperatures
|
||||||
|
num_draft_tokens = batch.spec_info.draft_token_num
|
||||||
|
# acceptance indices are the indices in a "flattened" batch.
|
||||||
|
# dividing it to num_draft_tokens will yield the actual batch index.
|
||||||
|
temperatures = temperatures[accepted_indices // num_draft_tokens]
|
||||||
|
if RETURN_ORIGINAL_LOGPROB:
|
||||||
|
logprobs = torch.nn.functional.log_softmax(
|
||||||
|
logits_output.next_token_logits, dim=-1
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
logprobs = torch.nn.functional.log_softmax(
|
||||||
|
logits_output.next_token_logits / temperatures, dim=-1
|
||||||
|
)
|
||||||
|
batch_next_token_ids = res.verified_id
|
||||||
|
accept_length_per_req_cpu = res.accept_length.tolist()
|
||||||
|
num_tokens_per_req = [accept + 1 for accept in accept_length_per_req_cpu]
|
||||||
|
|
||||||
|
# We should repeat top_logprobs_nums to match num_tokens_per_req.
|
||||||
|
top_logprobs_nums_repeat_interleaved = []
|
||||||
|
token_ids_logprobs_repeat_interleaved = []
|
||||||
|
for num, num_tokens in zip(top_logprobs_nums, num_tokens_per_req):
|
||||||
|
top_logprobs_nums_repeat_interleaved.extend([num] * num_tokens)
|
||||||
|
for token_ids, num_tokens in zip(token_ids_logprobs, num_tokens_per_req):
|
||||||
|
token_ids_logprobs_repeat_interleaved.extend([token_ids] * num_tokens)
|
||||||
|
|
||||||
|
# Extract logprobs
|
||||||
|
if any(x > 0 for x in top_logprobs_nums):
|
||||||
|
(
|
||||||
|
logits_output.next_token_top_logprobs_val,
|
||||||
|
logits_output.next_token_top_logprobs_idx,
|
||||||
|
) = get_top_logprobs(
|
||||||
|
logprobs,
|
||||||
|
top_logprobs_nums_repeat_interleaved,
|
||||||
|
)
|
||||||
|
|
||||||
|
if any(x is not None for x in token_ids_logprobs):
|
||||||
|
(
|
||||||
|
logits_output.next_token_token_ids_logprobs_val,
|
||||||
|
logits_output.next_token_token_ids_logprobs_idx,
|
||||||
|
) = get_token_ids_logprobs(
|
||||||
|
logprobs,
|
||||||
|
token_ids_logprobs_repeat_interleaved,
|
||||||
|
)
|
||||||
|
|
||||||
|
logits_output.next_token_logprobs = logprobs[
|
||||||
|
torch.arange(len(batch_next_token_ids), device=batch.sampling_info.device),
|
||||||
|
batch_next_token_ids,
|
||||||
|
]
|
||||||
|
|
||||||
|
# Add output logprobs to the request
|
||||||
|
pt = 0
|
||||||
|
next_token_logprobs = logits_output.next_token_logprobs.tolist()
|
||||||
|
verified_ids = batch_next_token_ids.tolist()
|
||||||
|
for req, num_tokens in zip(batch.reqs, num_tokens_per_req, strict=True):
|
||||||
|
for _ in range(num_tokens):
|
||||||
|
if req.return_logprob:
|
||||||
|
req.output_token_logprobs_val.append(next_token_logprobs[pt])
|
||||||
|
req.output_token_logprobs_idx.append(verified_ids[pt])
|
||||||
|
if req.top_logprobs_num > 0:
|
||||||
|
req.output_top_logprobs_val.append(
|
||||||
|
logits_output.next_token_top_logprobs_val[pt]
|
||||||
|
)
|
||||||
|
req.output_top_logprobs_idx.append(
|
||||||
|
logits_output.next_token_top_logprobs_idx[pt]
|
||||||
|
)
|
||||||
|
pt += 1
|
||||||
|
|
||||||
def _update_ngram_cache(self, batch: ScheduleBatch):
|
def _update_ngram_cache(self, batch: ScheduleBatch):
|
||||||
batch_tokens = []
|
batch_tokens = []
|
||||||
for req in batch.reqs:
|
for req in batch.reqs:
|
||||||
@@ -225,6 +309,8 @@ class NGRAMWorker:
|
|||||||
logits_output, next_token_ids, num_accepted_tokens = verify_input.verify(
|
logits_output, next_token_ids, num_accepted_tokens = verify_input.verify(
|
||||||
batch, logits_output, self.page_size
|
batch, logits_output, self.page_size
|
||||||
)
|
)
|
||||||
|
if batch.return_logprob:
|
||||||
|
self.add_logprob_values(batch, verify_input, logits_output)
|
||||||
self._update_ngram_cache(batch)
|
self._update_ngram_cache(batch)
|
||||||
batch.forward_mode = ForwardMode.DECODE
|
batch.forward_mode = ForwardMode.DECODE
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user