Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
94 commits
Select commit Hold shift + click to select a range
cbd57c1
feat: add router replay
Nov 3, 2025
2b92df8
Merge branch 'main' into feat/router_replay
ISEEKYAN Nov 20, 2025
bd32db8
refactor(router): rename RouterMode to RouterReplayAction
Nov 24, 2025
054942d
Merge branch 'main' into feat/router_replay
ISEEKYAN Dec 8, 2025
0cc1b08
Merge branch 'main' into feat/router_replay
ISEEKYAN Dec 9, 2025
fc668b6
Merge branch 'main' into feat/router_replay
ISEEKYAN Dec 10, 2025
e9d1a52
Merge branch 'main' into feat/router_replay
ISEEKYAN Dec 12, 2025
31bdce4
Merge branch 'main' into feat/router_replay
ISEEKYAN Dec 15, 2025
1aec041
simplify compute topk function
Dec 16, 2025
39fd47a
update router replay
Dec 17, 2025
49da256
add unit test and doc
Dec 23, 2025
590ce52
format code
Dec 23, 2025
15395b8
first attempt
sidsingh-nvidia Jan 20, 2026
39d36cc
merge conflict resolution
sidsingh-nvidia Jan 20, 2026
14f1347
non cudagraphable implementation tested
sidsingh-nvidia Jan 21, 2026
4b80457
make this work with sequence parallel + multiple prompts
sidsingh-nvidia Jan 21, 2026
36e850a
extract number of moe layers
sidsingh-nvidia Jan 21, 2026
c3e7854
cuda graphability
sidsingh-nvidia Jan 21, 2026
0a72c80
make this work with cuda graphs
sidsingh-nvidia Jan 21, 2026
d62038d
save router routing in functional tests and correctly handle inferenc…
sidsingh-nvidia Jan 23, 2026
351c00e
Move to using the Inference OpenAI API server; Remove all conversatio…
Jan 27, 2026
c195e24
Remove base model prompting special cases
Jan 27, 2026
6489600
Add tool and reasoning parsers
Feb 3, 2026
09b83eb
Fix reasoning parser. Add some logging.
Feb 3, 2026
f32d215
Fix RL code to match new OpenAI server
Feb 3, 2026
055964d
Force exit
Feb 4, 2026
076fac5
Update configs, remove more arguments
Feb 4, 2026
3f0bb15
Fix review comments. Remove 'n' from RL code altogether
Feb 4, 2026
ebf542c
remove extra logging
Feb 4, 2026
9a5207b
Remove unused code, Fix typo
Feb 4, 2026
fc0307d
formatter
Feb 4, 2026
d321cc5
Fix lint
Feb 4, 2026
d69730f
Fix test args
Feb 4, 2026
d5edaaa
Fix test args
Feb 4, 2026
2412044
Add copyright
Feb 4, 2026
dc4fcbc
Really important newline.
Feb 4, 2026
441e49a
More copyright
Feb 4, 2026
81c78f9
Update regex library
Feb 4, 2026
fc27fa3
More linting
ArEsKay3 Feb 4, 2026
2216694
Merge branch 'main' into rkirby/rl_inference_server_integration
ArEsKay3 Feb 4, 2026
652431c
Merge branch 'main' into rkirby/rl_inference_server_integration
ArEsKay3 Feb 5, 2026
338f36d
Merge branch 'main' into rkirby/rl_inference_server_integration
ArEsKay3 Feb 6, 2026
ad40331
Merge branch 'main' into inference-router-record
sidsingh-nvidia Feb 9, 2026
ee45dd6
Merge branch 'main' into inference-router-record
sidsingh-nvidia Feb 9, 2026
0666c2e
make it work with merge
sidsingh-nvidia Feb 9, 2026
9109ca1
hook upto openAI API
sidsingh-nvidia Feb 10, 2026
7a36e5e
Merge branch 'main' into inference-router-record
sidsingh-nvidia Feb 10, 2026
7feee53
format
sidsingh-nvidia Feb 10, 2026
473a652
minor
sidsingh-nvidia Feb 10, 2026
23ceea5
Merge branch 'main' into rkirby/rl_inference_server_integration
ArEsKay3 Feb 10, 2026
0bd3202
Merge branch 'main' into rkirby/rl_inference_server_integration
ArEsKay3 Feb 10, 2026
3912fd7
Merge branch 'main' into rkirby/rl_inference_server_integration
ko3n1g Feb 10, 2026
120c22f
Merge branch 'main' into inference-router-record
sidsingh-nvidia Feb 10, 2026
452acb2
remove unnecessary methods
sidsingh-nvidia Feb 10, 2026
20760a5
Merge remote-tracking branch 'gh/main' into rkirby/rl_inference_serve…
tdene Feb 10, 2026
9b8843a
Add dependencies
tdene Feb 10, 2026
1ca3a82
Merge remote-tracking branch 'gh/main' into rkirby/rl_inference_serve…
tdene Feb 10, 2026
96dc390
Update uv.lock
tdene Feb 10, 2026
bf27426
miinor bugfix
sidsingh-nvidia Feb 10, 2026
26002fc
attempt to reactivate functional test
sidsingh-nvidia Feb 10, 2026
75d31e1
Merge branch 'main' into inference-router-record
sidsingh-nvidia Feb 10, 2026
db37b3b
update functional test to run router recording
sidsingh-nvidia Feb 10, 2026
e0d3dd5
add routing indices to metrics
sidsingh-nvidia Feb 10, 2026
601b77d
Merge branch 'main' into inference-router-record
sidsingh-nvidia Feb 10, 2026
a13eafb
Merge branch 'main' into rkirby/rl_inference_server_integration
tdene Feb 11, 2026
dda0b6a
move test to github
sidsingh-nvidia Feb 11, 2026
045b07b
Merge branch 'main' into inference-router-record
sidsingh-nvidia Feb 11, 2026
48bb9b9
Merge branch 'main' into inference-router-record
sidsingh-nvidia Feb 11, 2026
b632151
Update test_inference_regular_pipeline.py
sidsingh-nvidia Feb 11, 2026
5072d5d
Merge branch 'main' into rkirby/rl_inference_server_integration
tdene Feb 11, 2026
e3c6cab
Merge branch 'main' into inference-router-record
sidsingh-nvidia Feb 11, 2026
061228c
Merge branch 'main' into inference-router-record
sidsingh-nvidia Feb 11, 2026
aeb73d1
Merge branch 'main' into rkirby/rl_inference_server_integration
tdene Feb 11, 2026
e084310
Merge branch 'main' into inference-router-record
sidsingh-nvidia Feb 11, 2026
c05da3b
Merge branch 'main' into inference-router-record
sidsingh-nvidia Feb 11, 2026
a99ddee
Merge branch 'main' into inference-router-record
sidsingh-nvidia Feb 11, 2026
8657146
Merge branch 'main' into rkirby/rl_inference_server_integration
tdene Feb 11, 2026
2594c39
Fix new GRPO functional test
tdene Feb 11, 2026
11a0b46
Merge remote-tracking branch 'autoformatter-remote/pull-request/3034'…
tdene Feb 12, 2026
8fd7f70
Merge remote-tracking branch 'gh/main' into rkirby/rl_inference_serve…
tdene Feb 12, 2026
6baad1e
Merge remote-tracking branch 'gh/main' into rkirby/rl_inference_serve…
tdene Feb 12, 2026
593f2f1
Merge remote-tracking branch 'gh/main' into rkirby/rl_inference_serve…
tdene Feb 12, 2026
14be3e1
Update uv.lock
tdene Feb 12, 2026
f2f0b6c
Fix test
tdene Feb 13, 2026
be42aa6
Fix BOS issue
tdene Feb 13, 2026
0aa4aa6
Fix typo
tdene Feb 13, 2026
53d8f74
Fix extra body
tdene Feb 13, 2026
f61e5b5
Merge remote-tracking branch 'gh/main' into rkirby/rl_inference_serve…
tdene Feb 13, 2026
cf2d71b
Account for engine modifying prompts
tdene Feb 13, 2026
d6df874
Fix README
tdene Feb 13, 2026
c0dba97
Fix typo
tdene Feb 13, 2026
ca51104
Serialize correctly
tdene Feb 13, 2026
58fb099
Fix add_BOS
tdene Feb 13, 2026
82e98be
Merge branch 'main' into rkirby/rl_inference_server_integration
tdene Feb 13, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion examples/rl/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,6 @@ torchrun \
--save $CHECKPOINT_DIR \
--load $CHECKPOINT_DIR \
--tensorboard-dir $TB_DIR \
--langrl-inference-server-type inplace_megatron \
--seed $SEED \
--sequence-parallel \
--finetune \
Expand Down
2 changes: 0 additions & 2 deletions examples/rl/environment_configs/gsm8k_nanov3.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
agent_args:
answer_format: "boxed"
format_reward: 0.5
assistant_suffix: "Assistant: "
chat_mode: true
negative_reward: 0.0
partial_end_reward: 0.75
weight: 1.0
Expand Down
9 changes: 1 addition & 8 deletions examples/rl/environments/countdown/countdown_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,8 @@
class CountdownAgent(RewardOnlyAgent, HFDatasetAgent):

def make_prefix(self, target, nums) -> str:
if self.chat_mode:
prefix = f"""Using the numbers {nums}, create an equation that equals {target}. You can use basic arithmetic operations (+, -, *, /) and each number can only be used once.
prefix = f"""Using the numbers {nums}, create an equation that equals {target}. You can use basic arithmetic operations (+, -, *, /) and each number can only be used once.
Return the final answer in <answer> </answer> tags, for example <answer> (1 + 2) / 3 </answer>. Do not include an = sign."""
else:
prefix = f"""A conversation between User and Assistant. The user asks a question, and the Assistant solves it. The assistant first thinks about the reasoning process in the mind and then provides the user with the answer.
User: Using the numbers {nums}, create an equation that equals {target}. You can use basic arithmetic operations (+, -, *, /) and each number can only be used once. Show your work in <think> </think> tags.
And return the final answer in <answer> </answer> tags, for example <answer> (1 + 2) / 3 </answer>. Do not include an = sign.
Assistant: Let me solve this step by step.
<think>"""
return prefix

def get_dataset(self, validation: bool = False):
Expand Down
4 changes: 0 additions & 4 deletions examples/rl/environments/math/gsm8k_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,12 @@
class GSM8KAgent(MathAgent):
def __init__(self,
answer_format: str = "boxed",
chat_mode: bool = False,
assistant_suffix: str = "Assistant: Let me solve this step by step.\n<think>",
format_reward: float = 0.0,
negative_reward: float = 0.0,
partial_end_reward: float = 0.0,
**kwargs):
super().__init__(
answer_format=answer_format,
chat_mode=chat_mode,
assistant_suffix=assistant_suffix,
format_reward=format_reward,
negative_reward=negative_reward,
partial_end_reward=partial_end_reward,
Expand Down
18 changes: 2 additions & 16 deletions examples/rl/environments/math/math_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import re
import traceback

from megatron.rl.agent.pass_at_evaluation_agent import PassAtEvaluationAgent
from megatron.rl.agent.reward_only_agent import RewardOnlyAgent

try:
Expand All @@ -25,8 +24,6 @@ class MathAgent(RewardOnlyAgent):
def __init__(self,
format_reward: float = 0.0,
answer_format: str = "tagged",
assistant_suffix: str = "Assistant: Let me solve this step by step.\n<think>",
chat_mode: bool = False,
negative_reward: float = 0.0,
partial_end_reward: float = 0.0,
**kwargs):
Expand All @@ -36,9 +33,6 @@ def __init__(self,
even if the answer is incorrect or is missing the end-of-text token.
answer_format (str): Which answer format is expected: "tagged" for <answer> tags,
or "boxed" for \boxed{} LaTeX formatting.
assistant_suffix (str): The suffix string included in the assistant's response, typically to
guide the assistant's output format and "persona". For example, "Let me solve this step by step."
chat_mode (bool): If True, agent operates in a chat (conversational) context.
negative_reward (float): Reward assigned for a clearly incorrect or unparseable answer.
partial_end_reward (float): Reward when the answer is correct but an expected end token is not matched exactly.
**kwargs: Additional arguments for the base RewardOnlyAgent.
Expand All @@ -49,8 +43,6 @@ def __init__(self,

self.format_reward = format_reward
self.answer_format = answer_format
self.assistant_suffix = assistant_suffix
self.chat_mode = chat_mode
self.negative_reward = negative_reward
self.partial_end_reward = partial_end_reward

Expand Down Expand Up @@ -134,12 +126,6 @@ def make_prefix(self, problem_key: str = "problem", **kwargs) -> str:
else:
raise ValueError(f"Invalid answer format: {self.answer_format}")

if self.chat_mode:
prefix = f"""{kwargs[problem_key]}\n{answer_format}"""
else:
prefix = f"""A conversation between User and Assistant. The user asks a question, and the Assistant solves it. The assistant first thinks about the reasoning process in the mind and then provides the user with the answer.
The question will be a word math problem. Show your work in <think> </think> tags.
{answer_format}
User: {kwargs[problem_key]}
{self.assistant_suffix}"""
prefix = f"""{kwargs[problem_key]}\n{answer_format}"""

return prefix
2 changes: 1 addition & 1 deletion examples/rl/model_configs/common.sh
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ COMMON_OPTIONS="\
--attention-backend flash \
--timing-log-level 1 \
--log-timers-to-tensorboard \
--save-retain-interval 120 \
--save-retain-interval 160 \
--inference-dynamic-batching-num-cuda-graphs 1 \
--inference-dynamic-batching-unified-memory-level 1 \
--adam-beta1 0.9 \
Expand Down
3 changes: 0 additions & 3 deletions examples/rl/model_configs/llama3p1_8b_instruct.sh
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,6 @@ MODEL_OPTIONS="\
--max-position-embeddings 131072 \
--tokenizer-type HuggingFaceTokenizer \
--tokenizer-model unsloth/Meta-Llama-3.1-8B-Instruct \
--legacy-tokenizer \
--langrl-inference-server-type "inplace_megatron_chat" \
--langrl-inference-server-conversation-template "unsloth/Meta-Llama-3.1-8B-Instruct" \
--lr 3e-7 \
--make-vocab-size-divisible-by 128 \
--clip-grad 1.0 \
Expand Down
2 changes: 0 additions & 2 deletions examples/rl/model_configs/qwen3_4b.sh
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,6 @@ MODEL_OPTIONS="\
--attention-softmax-in-fp32 \
--tokenizer-type HuggingFaceTokenizer \
--tokenizer-model Qwen/Qwen3-4B \
--langrl-inference-server-type "inplace_megatron_chat" \
--langrl-inference-server-conversation-template "Qwen/Qwen3-4B" \
--vocab-size 151936 \
--make-vocab-size-divisible-by 128 \
--optimizer adam \
Expand Down
2 changes: 0 additions & 2 deletions examples/rl/model_configs/qwen3_8b.sh
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,6 @@ MODEL_OPTIONS="\
--attention-softmax-in-fp32 \
--tokenizer-type HuggingFaceTokenizer \
--tokenizer-model Qwen/Qwen3-8B \
--langrl-inference-server-type "inplace_megatron_chat" \
--langrl-inference-server-conversation-template "Qwen/Qwen3-8B" \
--vocab-size 151936 \
--make-vocab-size-divisible-by 128 \
--optimizer adam \
Expand Down
4 changes: 2 additions & 2 deletions examples/rl/model_configs/qwen_2p5_3b.sh
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ if [ "$(basename "$ENV_CONFIG")" = "dapo.yaml" ]; then
GRPO_KL_BETA=${GRPO_KL_BETA:-"0.0"}
ENTROPY_WEIGHT=${ENTROPY_WEIGHT:-"0.0"}
TRAINING_BATCH_SIZE=${TRAINING_BATCH_SIZE:-1024}
MICRO_BATCH_SIZE=${MICRO_BATCH_SIZE:-2}
MICRO_BATCH_SIZE=${MICRO_BATCH_SIZE:-1}
MAX_SEQ_LENGTH=${MAX_SEQ_LENGTH:-8192}
EXIT_INTERVAL=${EXIT_INTERVAL:-16}
CHKPT_SAVE_INTERVAL=${CHKPT_SAVE_INTERVAL:-16}
Expand All @@ -38,7 +38,7 @@ else
GRPO_KL_BETA=${GRPO_KL_BETA:-"0.0"}
ENTROPY_WEIGHT=${ENTROPY_WEIGHT:-"0.0"}
TRAINING_BATCH_SIZE=${TRAINING_BATCH_SIZE:-512}
MICRO_BATCH_SIZE=${MICRO_BATCH_SIZE:-2}
MICRO_BATCH_SIZE=${MICRO_BATCH_SIZE:-1}
MAX_SEQ_LENGTH=${MAX_SEQ_LENGTH:-8192}
EXIT_INTERVAL=${EXIT_INTERVAL:-16}
CHKPT_SAVE_INTERVAL=${CHKPT_SAVE_INTERVAL:-16}
Expand Down
2 changes: 0 additions & 2 deletions examples/rl/model_configs/qwen_2p5_distill_7b.sh
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,6 @@ MODEL_OPTIONS="\
--max-position-embeddings 131072 \
--tokenizer-type HuggingFaceTokenizer \
--tokenizer-model "unsloth/DeepSeek-R1-Distill-Qwen-7B" \
--langrl-inference-server-type "inplace_megatron_chat" \
--langrl-inference-server-conversation-template "deepseek-ai/DeepSeek-R1-Distill-Qwen-7B" \
--lr 0.000001 \
--lr-warmup-samples 0 \
--make-vocab-size-divisible-by 128 \
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
import asyncio
import logging
import time
import traceback

from megatron.core.inference.sampling_params import SamplingParams
from megatron.core.tokenizers.text.parsers import PARSER_MAPPING

logger = logging.getLogger(__name__)

Expand All @@ -19,6 +21,7 @@ async def chat_completions():
"""Handles async POST requests for chat completions."""
client = current_app.config['client']
tokenizer = current_app.config['tokenizer']
parsers = current_app.config['parsers']

req = request.get_json()

Expand All @@ -31,14 +34,17 @@ async def chat_completions():

try:
prompt_tokens = tokenizer.apply_chat_template(
messages, tokenize=True, add_generation_prompt=True
messages, tokenize=True, add_generation_prompt=True, tools=req.get("tools", None)
)
except (AttributeError, AssertionError):
logger.warning(
"Tokenizer does not support 'apply_chat_template'. Using tokenize instead."
)
prompt_tokens = tokenizer.tokenize(
"\n".join([message["content"] for message in messages])
)
except AttributeError:
return (
"Tokenizer does not support 'apply_chat_template'. "
"Chat completions requires a tokenizer with a configured chat template."
), 500
except Exception as e:
logger.error(f"{traceback.format_exc()}")
return f"Error processing 'messages': {e}", 500

# --- 2. Parse Sampling Params ---
Expand All @@ -55,14 +61,31 @@ async def chat_completions():
# Check for 'logprobs' (bool) and 'top_logprobs' (int)
return_log_probs = bool(req.get("logprobs", False))
top_n_logprobs = int(req.get("top_logprobs", 0)) if return_log_probs else 0
skip_prompt_log_probs = bool(req.get("skip_prompt_log_probs", False))
add_BOS = bool(req.get("add_BOS", False))

# The engine only handles add_BOS for string prompts, not pre-tokenized
# input. Since we pre-tokenize via apply_chat_template, we must handle
# BOS ourselves, matching the logic in tokenize_prompt().
if hasattr(tokenizer, 'bos') and tokenizer.bos is not None:
while prompt_tokens and prompt_tokens[0] == tokenizer.bos:
prompt_tokens.pop(0)
if add_BOS:
prompt_tokens = [tokenizer.bos] + prompt_tokens

sampling_params = SamplingParams(
temperature=temperature,
top_k=top_k,
top_p=top_p,
return_log_probs=return_log_probs,
top_n_logprobs=top_n_logprobs,
num_tokens_to_generate=int(req.get("max_tokens", 16)),
num_tokens_to_generate=(
int(max_tokens)
if ((max_tokens := req.get("max_tokens", None)) is not None)
else None
),
skip_prompt_log_probs=skip_prompt_log_probs,
add_BOS=add_BOS,
)
except ValueError as e:
return f"Invalid sampling parameter: {e}", 400
Expand All @@ -71,20 +94,13 @@ async def chat_completions():
# For chat, we run the *same* prompt 'n' times.
tasks = []
for _ in range(n):
per_req_params = SamplingParams(
temperature=sampling_params.temperature,
top_k=sampling_params.top_k,
top_p=sampling_params.top_p,
return_log_probs=sampling_params.return_log_probs,
top_n_logprobs=sampling_params.top_n_logprobs,
num_tokens_to_generate=sampling_params.num_tokens_to_generate,
)
tasks.append(client.add_request(prompt_tokens, per_req_params))
tasks.append(client.add_request(prompt_tokens, sampling_params))

start_time = time.perf_counter()
try:
batch_results = await asyncio.gather(*tasks)
except Exception as e:
logger.error(f"Error during inference: {e}")
return f"Error during inference: {e}", 500

logger.info(
Expand All @@ -95,21 +111,29 @@ async def chat_completions():
# --- 4. Format OpenAI Response ---
choices = []
total_completion_tokens = 0
prompt_token_count = len(prompt_tokens) # Calculated once
prompt_tokens_counts = []

request_idx = 0
for record in batch_results:
assert len(record.requests) == 1, "Each record should contain one request result."
result = record.merge()
text_output = result.generated_text
result = record.merge().serialize()
# Unwrap ("tensor", [...]) tuples from serialize() into plain lists.
result = {
k: v[1] if isinstance(v, (list, tuple)) and len(v) == 2 and v[0] == "tensor" else v
for k, v in result.items()
}
prompt_tokens = result["prompt_tokens"] # The engine can modify prompt_tokens.
text_output = result["generated_text"]
prompt_tokens_count = len(prompt_tokens) if prompt_tokens is not None else 0
prompt_tokens_counts.append(prompt_tokens_count)

logprobs_content = None
if sampling_params.return_log_probs:
token_logprobs = getattr(result, 'log_probs', [])
tokens = [tokenizer.detokenize([tok]) for tok in result.generated_tokens]
token_logprobs = result.get('log_probs', [])
tokens = [tokenizer.detokenize([tok]) for tok in result["generated_tokens"]]

# Get top_n_logprobs if available
generated_top_n_logprobs = getattr(result, 'generated_top_n_logprobs', None)
generated_top_n_logprobs = result.get('generated_top_n_logprobs')

logprobs_content = []
for i, (tok, lp) in enumerate(zip(tokens, token_logprobs)):
Expand All @@ -134,25 +158,50 @@ async def chat_completions():
}
logprobs_content.append(entry)

metadata = {}
message_text = text_output
if parsers:
for parser in parsers:
if parser not in PARSER_MAPPING:
raise ValueError(f"Parser {parser} not found in PARSER_MAPPING")
message_text, new_info = PARSER_MAPPING[parser].parse(
message_text, tools=req.get("tools", None)
)
assert not (
metadata.keys() & new_info.keys()
), "Multiple parsers found the same information."
metadata.update(new_info)
message = {"role": "assistant", "content": message_text}
if "tool_calls" in metadata:
message["tool_calls"] = metadata["tool_calls"]
if "reasoning" in metadata:
message["reasoning"] = metadata["reasoning"]

choice_data = {
"index": 0,
"message": {"role": "assistant", "content": text_output},
"index": request_idx,
"message": message,
"prompt_token_ids": result["prompt_tokens"],
"generation_token_ids": result["generated_tokens"],
"generation_log_probs": result["generated_log_probs"],
"raw_text": result["prompt"] + result["generated_text"],
# 'logprobs' in chat API is an object containing 'content'
"logprobs": {"content": logprobs_content} if logprobs_content else None,
"finish_reason": "length", # Original code hardcoded this.
"finish_reason": (
"tool_calls" if metadata.get("tool_calls", []) else "stop"
), # Original code hardcoded this.
}
logging.info(result)
if result.routing_indices is not None:
choice_data["moe_topk_indices"] = result.routing_indices.tolist()
prompt_length = len(result.prompt_tokens) if result.prompt_tokens is not None else 0
if prompt_length:
choices[-1]["prompt_moe_topk_indices"] = result.routing_indices[
:prompt_length
].tolist()
if result["routing_indices"] is not None:
choice_data["moe_topk_indices"] = result["routing_indices"]
if prompt_tokens_count:
choices[-1]["prompt_moe_topk_indices"] = result["routing_indices"][
:prompt_tokens_count
]
choices.append(choice_data)
total_completion_tokens += len(result.generated_tokens)
request_idx += 0
total_completion_tokens += len(result["generated_tokens"])
request_idx += 1

prompt_token_count = max(prompt_tokens_counts)
response = {
"choices": choices,
"usage": {
Expand Down
Loading
Loading