Skip to content

Commit 20fafe4

Browse files
authored
Merge branch 'main' into mini-fixes
2 parents 2e43555 + c2b83e2 commit 20fafe4

10 files changed

Lines changed: 278 additions & 53 deletions

File tree

.github/release.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@ changelog:
55
categories:
66
- title: New Features 🎉
77
labels:
8-
- feature/enhancement
8+
- feature
9+
- title: Enhancement ⚙️
10+
labels:
11+
- enhancement
912
- title: Documentation 📚
1013
labels:
1114
- documentation

community_tasks/slr_bench_evals.py

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
# MIT License
2+
3+
# Copyright (c) 2025 Lukas Helff
4+
5+
# Permission is hereby granted, free of charge, to any person obtaining a copy
6+
# of this software and associated documentation files (the "Software"), to deal
7+
# in the Software without restriction, including without limitation the rights
8+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
# copies of the Software, and to permit persons to whom the Software is
10+
# furnished to do so, subject to the following conditions:
11+
12+
# The above copyright notice and this permission notice shall be included in all
13+
# copies or substantial portions of the Software.
14+
15+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
# SOFTWARE.
22+
23+
"""
24+
SLR-Bench is a large-scale benchmark for scalable logical reasoning with language models, comprising 19,000 prompts organized into 20 curriculum levels.
25+
The tasks progressively increase in relational, arithmetic, and recursive complexity, requiring models to synthesize Prolog rules that classify train compositions.
26+
For more details see: https://huggingface.co/datasets/AIML-TUDA/SLR-Bench
27+
The paper can be found here: https://arxiv.org/abs/2506.15787
28+
Before using this task, please ensure that SWI-Prolog and evaluate are installed on your system, as they are required for symbolic verification of the generated Prolog programs.
29+
"""
30+
31+
import logging
32+
import shutil
33+
34+
import numpy as np
35+
from evaluate import load
36+
37+
from lighteval.metrics.utils.metric_utils import SampleLevelComputation, SampleLevelMetric
38+
from lighteval.tasks.lighteval_task import LightevalTaskConfig
39+
from lighteval.tasks.requests import Doc, SamplingMethod
40+
41+
42+
logger = logging.getLogger(__name__)
43+
44+
45+
# Check for SWI-Prolog installation
46+
if shutil.which("swipl") is None:
47+
raise ImportError(
48+
"SWI-Prolog (swipl) is not installed or not in PATH. "
49+
"Please install SWI-Prolog to use this task. "
50+
"You can install required dependencies with: pip install -r community_tasks/slr_bench_requirements.txt"
51+
)
52+
53+
# Load the symbolic judge for evaluating Prolog programs
54+
symbolic_judge = load("AIML-TUDA/VerifiableRewardsForScalableLogicalReasoning")
55+
56+
57+
def prompt_fn(line: dict, task_name: str):
58+
"""Defines how to go from a dataset line to a doc object."""
59+
return Doc(
60+
task_name=task_name, query=line["prompt"], choices=[str(line.get("validation program", ""))], gold_index=0
61+
)
62+
63+
64+
class VerifiableRewardMetric(SampleLevelComputation):
65+
def compute(self, doc, model_response, **kwargs):
66+
try:
67+
prediction = model_response.final_text[0]
68+
validation_program = doc.choices[0] if doc.choices else ""
69+
ref_format = [
70+
{
71+
"validation_program": validation_program,
72+
"evaluation_config": {"positive_predicate": "eastbound", "negative_predicate": "westbound"},
73+
}
74+
]
75+
76+
results = symbolic_judge.compute(predictions=[prediction], references=ref_format)
77+
return results["accuracy"]
78+
79+
except Exception as e:
80+
logger.error("Error during the computation of the metric")
81+
raise RuntimeError(f"Failed to compute verifiable reward metric: {e}")
82+
83+
84+
custom_metric = SampleLevelMetric(
85+
metric_name="verifiable_reward",
86+
higher_is_better=True,
87+
category=SamplingMethod.GENERATIVE,
88+
sample_level_fn=VerifiableRewardMetric(),
89+
corpus_level_fn=np.mean,
90+
)
91+
92+
# Define the subsets available in the SLR-Bench dataset
93+
CONFIGURATIONS = ["All", "Basic", "Easy", "Medium", "Hard"]
94+
95+
96+
class SLRBenchTask(LightevalTaskConfig):
97+
"""Task configuration for SLR-Bench evaluation."""
98+
99+
def __init__(
100+
self,
101+
config: str,
102+
):
103+
name = f"slr_bench_{config.lower()}"
104+
super().__init__(
105+
name=name,
106+
hf_subset=f"v1-{config}",
107+
prompt_function=prompt_fn,
108+
hf_repo="AIML-TUDA/SLR-Bench",
109+
metrics=[custom_metric],
110+
hf_avail_splits=["train", "validation", "test"],
111+
evaluation_splits=["test"],
112+
few_shots_split="train",
113+
few_shots_select="random_sampling_from_train",
114+
suite=["community"],
115+
generation_size=4096,
116+
stop_sequence=None,
117+
version=1,
118+
)
119+
120+
121+
# Create a single task instance for each configuration
122+
TASKS = [SLRBenchTask(config) for config in CONFIGURATIONS]
123+
124+
# Export tasks table
125+
TASKS_TABLE = TASKS
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
evaluate
2+
swipl

docs/source/use-inference-providers-as-backend.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,4 +66,4 @@ model_parameters:
6666
org_to_bill: "my-organization"
6767
```
6868

69-
For more detailed error handling and provider-specific information, refer to the [Hugging Face Inference Providers documentation](https://huggingface.co/docs/inference-endpoints/guides/inference_providers).
69+
For more detailed error handling and provider-specific information, refer to the [Hugging Face Inference Providers documentation](https://huggingface.co/docs/inference-providers/en/index).

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ dependencies = [
8888
]
8989

9090
[project.optional-dependencies]
91-
litellm = ["litellm[caching]", "diskcache"]
91+
litellm = ["litellm[caching]>=1.66.0", "diskcache"]
9292
tgi = ["text-generation>=0.7.0"]
9393
optimum = ["optimum==1.12.0"]
9494
quantization = ["bitsandbytes>=0.41.0", "auto-gptq>=0.4.2"]

src/lighteval/metrics/metrics.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -526,8 +526,12 @@ class Metrics(Enum):
526526
metric_name="extractive_match",
527527
sample_level_fn=MultilingualExtractiveMatchMetric(
528528
language=Language.ENGLISH,
529-
gold_extraction_target=[IndicesExtractionConfig(prefix_for_extraction="NativeLetters")],
530-
pred_extraction_target=[IndicesExtractionConfig(prefix_for_extraction="NativeLetters")],
529+
gold_extraction_target=[
530+
IndicesExtractionConfig(prefix_for_extraction="NativeLetters", try_extract_without_anchor=True)
531+
],
532+
pred_extraction_target=[
533+
IndicesExtractionConfig(prefix_for_extraction="NativeLetters", try_extract_without_anchor=True)
534+
],
531535
precision=6,
532536
),
533537
category=SamplingMethod.GENERATIVE,
@@ -539,8 +543,12 @@ class Metrics(Enum):
539543
sample_level_fn=PassAtK(
540544
sample_scoring_function=MultilingualExtractiveMatchMetric(
541545
language=Language.ENGLISH,
542-
gold_extraction_target=[IndicesExtractionConfig(prefix_for_extraction="NativeLetters")],
543-
pred_extraction_target=[IndicesExtractionConfig(prefix_for_extraction="NativeLetters")],
546+
gold_extraction_target=[
547+
IndicesExtractionConfig(prefix_for_extraction="NativeLetters", try_extract_without_anchor=True)
548+
],
549+
pred_extraction_target=[
550+
IndicesExtractionConfig(prefix_for_extraction="NativeLetters", try_extract_without_anchor=True)
551+
],
544552
precision=6,
545553
),
546554
),

src/lighteval/models/endpoints/inference_providers_model.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ def __init__(self, config: InferenceProvidersModelConfig) -> None:
116116
self.API_RETRY_SLEEP = 3
117117
self.API_RETRY_MULTIPLIER = 2
118118
self.pairwise_tokenization = False
119-
self.semaphore = asyncio.Semaphore(config.parallel_calls_count) # Limit concurrent API calls
119+
self.parallel_calls_count = config.parallel_calls_count
120120

121121
self.client = AsyncInferenceClient(
122122
provider=self.provider,
@@ -179,13 +179,16 @@ async def __call_api_parallel(
179179
):
180180
results = []
181181

182+
# Initialize semaphore for the current event loop
183+
semaphore = asyncio.Semaphore(self.parallel_calls_count)
184+
182185
num_sampless = [num_samples for _ in prompts] if not isinstance(num_samples, list) else num_samples
183186
assert len(prompts) == len(num_sampless), (
184187
f"Length of prompts and max_new_tokenss should be the same but are {len(prompts)}, {len(num_sampless)}"
185188
)
186189

187190
async def bounded_api_call(prompt, num_samples):
188-
async with self.semaphore:
191+
async with semaphore:
189192
return await self.__call_api(prompt, num_samples)
190193

191194
tasks = [bounded_api_call(prompt, num_samples) for prompt, num_samples in zip(prompts, num_sampless)]

0 commit comments

Comments
 (0)