Skip to content

Commit 0493f89

Browse files
authored
[Feature] Add Multi-Round inferencer in GenInferencer and add Multi-IF dataset (#2557)
* add * fix parallel * fix lint
1 parent 33c903f commit 0493f89

11 files changed

Lines changed: 2296 additions & 13 deletions

File tree

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
from opencompass.openicl.icl_inferencer import GenInferencer
2+
from opencompass.openicl.icl_raw_prompt_template import RawPromptTemplate
3+
from opencompass.openicl.icl_retriever import ZeroRetriever
4+
from opencompass.datasets import MultiIFDataset, MultiIFEvaluator
5+
6+
multiif_reader_cfg = dict(
7+
input_columns=['dialogue'],
8+
output_column='reference',
9+
)
10+
11+
multiif_infer_cfg = dict(
12+
prompt_template=dict(
13+
type=RawPromptTemplate,
14+
messages=[{'expand_column': 'dialogue'}],
15+
format_variables=False,
16+
),
17+
retriever=dict(type=ZeroRetriever),
18+
inferencer=dict(
19+
type=GenInferencer,
20+
multiround=True,
21+
),
22+
)
23+
24+
multiif_eval_cfg = dict(
25+
evaluator=dict(type=MultiIFEvaluator),
26+
pred_role='BOT',
27+
)
28+
29+
multiif_datasets = [
30+
dict(
31+
abbr='Multi-IF',
32+
type=MultiIFDataset,
33+
path='opencompass/MultiIF',
34+
reader_cfg=multiif_reader_cfg,
35+
infer_cfg=multiif_infer_cfg,
36+
eval_cfg=multiif_eval_cfg,
37+
),
38+
]
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from .multiif import MultiIFDataset, MultiIFEvaluator # noqa: F401, F403
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
# flake8: noqa
2+
# yapf: disable
3+
4+
# Copyright 2023 The Google Research Authors.
5+
#
6+
# Licensed under the Apache License, Version 2.0 (the "License");
7+
# you may not use this file except in compliance with the License.
8+
# You may obtain a copy of the License at
9+
#
10+
# http://www.apache.org/licenses/LICENSE-2.0
11+
#
12+
# Unless required by applicable law or agreed to in writing, software
13+
# distributed under the License is distributed on an "AS IS" BASIS,
14+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
# See the License for the specific language governing permissions and
16+
# limitations under the License.
17+
18+
import dataclasses
19+
from typing import Dict, List, Optional, Union
20+
21+
from . import instructions_registry
22+
23+
24+
@dataclasses.dataclass
25+
class InputExample:
26+
key: int
27+
instruction_id_list: List[str]
28+
prompt: str
29+
kwargs: List[Dict[str, Optional[Union[str, int]]]]
30+
31+
32+
@dataclasses.dataclass
33+
class OutputExample:
34+
instruction_id_list: List[str]
35+
prompt: str
36+
response: str
37+
follow_all_instructions: bool
38+
follow_instruction_list: List[bool]
39+
40+
41+
def test_instruction_following_strict(
42+
inp,
43+
response,
44+
):
45+
"""Tests response to see if instrutions are followed."""
46+
instruction_list = inp.instruction_id_list
47+
is_following_list = []
48+
49+
for index, instruction_id in enumerate(instruction_list):
50+
instruction_cls = instructions_registry.INSTRUCTION_DICT[
51+
instruction_id]
52+
instruction = instruction_cls(instruction_id)
53+
instruction.build_description(**inp.kwargs[index])
54+
args = instruction.get_instruction_args()
55+
if args and 'prompt' in args:
56+
instruction.build_description(prompt=inp.prompt)
57+
58+
if response.strip() and instruction.check_following(response):
59+
is_following_list.append(True)
60+
else:
61+
is_following_list.append(False)
62+
63+
return OutputExample(
64+
instruction_id_list=inp.instruction_id_list,
65+
prompt=inp.prompt,
66+
response=response,
67+
follow_all_instructions=all(is_following_list),
68+
follow_instruction_list=is_following_list,
69+
)
70+
71+
72+
def test_instruction_following_loose(
73+
inp,
74+
response,
75+
):
76+
"""Tests response for an upper bound for following instructions."""
77+
r = response.split('\n')
78+
response_remove_first = '\n'.join(r[1:]).strip()
79+
response_remove_last = '\n'.join(r[:-1]).strip()
80+
response_remove_both = '\n'.join(r[1:-1]).strip()
81+
revised_response = response.replace('*', '')
82+
revised_response_remove_first = response_remove_first.replace('*', '')
83+
revised_response_remove_last = response_remove_last.replace('*', '')
84+
revised_response_remove_both = response_remove_both.replace('*', '')
85+
all_responses = [
86+
response,
87+
revised_response,
88+
response_remove_first,
89+
response_remove_last,
90+
response_remove_both,
91+
revised_response_remove_first,
92+
revised_response_remove_last,
93+
revised_response_remove_both,
94+
]
95+
instruction_list = inp.instruction_id_list
96+
is_following_list = []
97+
98+
for index, instruction_id in enumerate(instruction_list):
99+
instruction_cls = instructions_registry.INSTRUCTION_DICT[
100+
instruction_id]
101+
instruction = instruction_cls(instruction_id)
102+
103+
instruction.build_description(**inp.kwargs[index])
104+
args = instruction.get_instruction_args()
105+
if args and 'prompt' in args:
106+
instruction.build_description(prompt=inp.prompt)
107+
108+
is_following = False
109+
for r in all_responses:
110+
if r.strip() and instruction.check_following(r):
111+
is_following = True
112+
break
113+
114+
is_following_list.append(is_following)
115+
116+
return OutputExample(
117+
instruction_id_list=inp.instruction_id_list,
118+
prompt=inp.prompt,
119+
response=response,
120+
follow_all_instructions=all(is_following_list),
121+
follow_instruction_list=is_following_list,
122+
)

0 commit comments

Comments
 (0)