Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
19 changes: 16 additions & 3 deletions giskard/scanner/scanner.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,8 @@ def analyze(

# Initialize LLM logger if needed
if model.is_text_generation:
get_default_client().logger.reset()
llm_logger = _maybe_get_llm_logger()
llm_logger is not None and llm_logger.reset()

# Good, we can start
maybe_print("🔎 Running scan…", verbose=verbose)
Expand Down Expand Up @@ -334,7 +335,10 @@ def _get_cost_estimate(self, model, dataset, detectors):
}

def _get_cost_measure(self):
llm_logger = get_default_client().logger
llm_logger = _maybe_get_llm_logger()
if llm_logger is None:
return None

num_calls = llm_logger.get_num_calls()
num_prompt_tokens = llm_logger.get_num_prompt_tokens()
num_sampled_tokens = llm_logger.get_num_sampled_tokens()
Expand All @@ -357,7 +361,8 @@ def _print_execution_summary(self, model, issues, errors, elapsed):
)
if model.is_text_generation:
measured = self._get_cost_measure()
print(COST_SUMMARY_TEMPLATE.format(**measured))
if measured is not None:
print(COST_SUMMARY_TEMPLATE.format(**measured))
if errors:
warning(
f"{len(errors)} errors were encountered while running detectors. Please check the log to understand what went wrong. "
Expand All @@ -368,3 +373,11 @@ def _print_execution_summary(self, model, issues, errors, elapsed):
def maybe_print(*args, **kwargs):
if kwargs.pop("verbose", True):
print(*args, **kwargs)


def _maybe_get_llm_logger():
"""Get the LLM client logger if available."""
try:
return get_default_client().logger
except Exception:
return None
24 changes: 24 additions & 0 deletions tests/scan/test_scanner.py
Original file line number Diff line number Diff line change
Expand Up @@ -267,3 +267,27 @@ def test_can_limit_features_to_subset():

with pytest.raises(ValueError, match=r"No features to scan"):
scanner.analyze(model, dataset, features=[])


@mock.patch("giskard.scanner.scanner.get_default_client")
def test_scanner_does_not_break_if_llm_client_not_set(get_default_client):
"""For scans that do not require the LLM client, the scanner must not break if the client is not set."""
get_default_client.side_effect = ValueError("No client set")

scanner = Scanner()

def fake_model(*args, **kwargs):
return None

model = Model(
model=fake_model,
model_type=SupportedModelTypes.TEXT_GENERATION,
name="test",
description="test",
feature_names=["query"],
target="query",
)

dataset = Dataset(pd.DataFrame({"query": ["test"]}))

scanner.analyze(model, dataset)