Skip to content

Commit 96263b1

Browse files
authored
[Fix] Fix per-turn statistics in dump-res-length and repeat detection issues for multi-round conversations (#2569)
1 parent 96ec35d commit 96263b1

4 files changed

Lines changed: 42 additions & 11 deletions

File tree

opencompass/openicl/icl_inferencer/icl_base_inferencer.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -169,9 +169,9 @@ def save_results(self,
169169
}
170170
if gold:
171171
self.results_dict[str(idx)]['gold'] = gold
172-
if res_length:
172+
if res_length is not None:
173173
self.results_dict[str(idx)]['res_length'] = res_length
174-
if input_length:
174+
if input_length is not None:
175175
self.results_dict[str(idx)]['all_input_length'] = input_length
176176

177177

opencompass/openicl/icl_inferencer/icl_gen_inferencer.py

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -190,17 +190,20 @@ def inference(self,
190190
num_return_sequences = getattr(self.model, 'generation_kwargs',
191191
{}).get('num_return_sequences', 1)
192192
# 5-3. Save current output
193-
for prompt, prediction, gold in zip(
194-
parsed_entries, batched(generated, num_return_sequences),
195-
golds):
193+
for batch_idx, (prompt, prediction, gold) in enumerate(
194+
zip(parsed_entries, batched(generated,
195+
num_return_sequences), golds)):
196196
if num_return_sequences == 1:
197197
prediction = prediction[0]
198198

199199
if self.dump_res_length:
200-
input_length = 0
201-
if isinstance(prompt, str):
200+
if self.multiround and isinstance(prompt, list):
201+
input_length = self._compute_multiround_input_lengths(
202+
entry[batch_idx])
203+
elif isinstance(prompt, str):
202204
input_length = self.model.get_token_len(prompt)
203205
elif isinstance(prompt, list):
206+
input_length = 0
204207
for i in range(len(prompt)):
205208
if 'prompt' in prompt[i]:
206209
prompt[i][
@@ -275,6 +278,29 @@ def inference(self,
275278
for sample in output_handler.results_dict.values()
276279
]
277280

281+
def _compute_multiround_input_lengths(self, chat: List) -> List[int]:
282+
"""Compute cumulative input token length at each generation turn.
283+
284+
Expects ``chat`` to be the filled multi-round conversation where
285+
assistant slots already contain the generated responses. Returns a
286+
list of cumulative token counts, one per generation turn, i.e. the
287+
input length the model actually sees when generating each turn.
288+
"""
289+
input_lengths = []
290+
cumulative = 0
291+
for msg in chat:
292+
if isinstance(msg, dict):
293+
role = msg.get('role', '')
294+
content = msg.get('content', msg.get('prompt', ''))
295+
else:
296+
role, content = '', msg
297+
if not isinstance(content, str):
298+
content = str(content)
299+
if role == 'assistant':
300+
input_lengths.append(cumulative)
301+
cumulative += self.model.get_token_len(content)
302+
return input_lengths
303+
278304
def _generate_multiround(self, entry: List,
279305
extra_gen_kwargs: dict) -> List[List[str]]:
280306
"""Multi-turn generation with dynamic turn-level scheduling.

opencompass/openicl/icl_inferencer/icl_gen_inferencer_parallel.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -154,10 +154,13 @@ def _infer_one(entry, gold, idx):
154154
)
155155

156156
if self.dump_res_length:
157-
input_length = 0
158-
if isinstance(parsed_entry, str):
157+
if self.multiround and isinstance(parsed_entry, list):
158+
input_length = self._compute_multiround_input_lengths(
159+
entry)
160+
elif isinstance(parsed_entry, str):
159161
input_length = self.model.get_token_len(parsed_entry)
160162
elif isinstance(parsed_entry, list):
163+
input_length = 0
161164
for i in range(len(parsed_entry)):
162165
if 'prompt' in parsed_entry[i]:
163166
parsed_entry[i][

opencompass/utils/repeat_analysis.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -367,8 +367,10 @@ def _collect_predictions_by_benchmark(
367367
raw_res_length = sample.get('res_length', None)
368368
if raw_res_length is not None:
369369
if isinstance(raw_res_length, list):
370-
res_length = (raw_res_length[0]
371-
if raw_res_length else 0)
370+
# Multi-turn: each turn's response is joined
371+
# by _prediction_to_text with '\n', so sum
372+
# across turns to match the combined text.
373+
res_length = sum(raw_res_length)
372374
else:
373375
res_length = raw_res_length
374376
else:

0 commit comments

Comments
 (0)