anhtld commited on
Commit
cb715f5
·
verified ·
1 Parent(s): 507e110

auto-sync 2026-07-03T17:26:48Z workspace

Browse files
workspace/cil/metrics.py CHANGED
@@ -140,10 +140,72 @@ def measured_support_gap(
140
  raise MetricInputError(
141
  "SupportGap requires evaluated generated candidates or a generated set "
142
  "that is a subset of measured hidden chart branches"
143
- )
144
  return support_gap(best_hidden_chart, best_measured_generated_candidate)
145
 
146
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
147
  def car_decomposition(
148
  *,
149
  best_hidden_chart: Number,
@@ -515,6 +577,30 @@ def _maybe_float(value: Any) -> float | None:
515
  return numeric if math.isfinite(numeric) else None
516
 
517
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
518
  def _mean(values: Iterable[float]) -> float | None:
519
  clean = [float(value) for value in values if math.isfinite(float(value))]
520
  return sum(clean) / len(clean) if clean else None
 
140
  raise MetricInputError(
141
  "SupportGap requires evaluated generated candidates or a generated set "
142
  "that is a subset of measured hidden chart branches"
143
+ )
144
  return support_gap(best_hidden_chart, best_measured_generated_candidate)
145
 
146
 
147
+ def outcome_safety_violation(outcome: Mapping[str, Any] | None) -> bool | None:
148
+ """Return a safety label from an outcome payload, preserving unknowns.
149
+
150
+ Missing or null ``safety_violation`` labels are unknown, not safe.
151
+ """
152
+
153
+ if not isinstance(outcome, Mapping) or "safety_violation" not in outcome:
154
+ return None
155
+ return _parse_optional_bool(outcome.get("safety_violation"))
156
+
157
+
158
+ def safety_label_coverage(outcomes: Sequence[Any], *, k: int | None = None) -> float:
159
+ """Fraction of outcomes with known safety labels."""
160
+
161
+ prefix = _prefix(outcomes, k)
162
+ if not prefix:
163
+ return 0.0
164
+ known = sum(outcome_safety_violation(outcome) is not None for outcome in prefix)
165
+ return known / len(prefix)
166
+
167
+
168
+ def unsafe_rate(outcomes: Sequence[Any], *, k: int | None = None) -> float | None:
169
+ """Unsafe rate over outcomes with known safety labels."""
170
+
171
+ labels = [
172
+ label
173
+ for outcome in _prefix(outcomes, k)
174
+ if (label := outcome_safety_violation(outcome)) is not None
175
+ ]
176
+ if not labels:
177
+ return None
178
+ return sum(float(label) for label in labels) / len(labels)
179
+
180
+
181
+ def any_unsafe(outcomes: Sequence[Any], *, k: int | None = None) -> float | None:
182
+ """Whether any known safety label is unsafe."""
183
+
184
+ labels = [
185
+ label
186
+ for outcome in _prefix(outcomes, k)
187
+ if (label := outcome_safety_violation(outcome)) is not None
188
+ ]
189
+ if not labels:
190
+ return None
191
+ return 1.0 if any(labels) else 0.0
192
+
193
+
194
+ def selected_unsafe(
195
+ outcomes: Sequence[Any],
196
+ *,
197
+ selected_index: int = 0,
198
+ k: int | None = None,
199
+ ) -> float | None:
200
+ """Unsafe label for the selected candidate, if that label is known."""
201
+
202
+ prefix = _prefix(outcomes, k)
203
+ if selected_index < 0 or selected_index >= len(prefix):
204
+ raise IndexError("selected_index must refer to an element inside the K-prefix")
205
+ label = outcome_safety_violation(prefix[selected_index])
206
+ return None if label is None else float(label)
207
+
208
+
209
  def car_decomposition(
210
  *,
211
  best_hidden_chart: Number,
 
577
  return numeric if math.isfinite(numeric) else None
578
 
579
 
580
+ def _parse_optional_bool(value: Any) -> bool | None:
581
+ if value is None:
582
+ return None
583
+ if isinstance(value, bool):
584
+ return value
585
+ if isinstance(value, (int, float)):
586
+ numeric = float(value)
587
+ return bool(numeric) if math.isfinite(numeric) else None
588
+ if isinstance(value, str):
589
+ normalized = value.strip().lower()
590
+ if normalized in {"", "null", "none", "nan", "n/a", "na", "unknown"}:
591
+ return None
592
+ if normalized in {"1", "true", "t", "yes", "y", "unsafe", "violation"}:
593
+ return True
594
+ if normalized in {"0", "false", "f", "no", "n", "safe", "ok"}:
595
+ return False
596
+ try:
597
+ numeric = float(normalized)
598
+ except ValueError:
599
+ return None
600
+ return bool(numeric) if math.isfinite(numeric) else None
601
+ return None
602
+
603
+
604
  def _mean(values: Iterable[float]) -> float | None:
605
  clean = [float(value) for value in values if math.isfinite(float(value))]
606
  return sum(clean) / len(clean) if clean else None
workspace/data/cil_charts_rgb_refs/test/object_embeddings_rgb_layout.npz ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:4e8773e46aef035fe87b3a6b631ae0bd9c82ba2c7310c62545a6b8c8a86373d5
3
+ size 62832
workspace/data/cil_charts_rgb_refs/train/object_embeddings_rgb_layout.npz ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:fe97ac428d6b0ed4da7060eb6f697c1392b4a8a09988a10c0f633b1e457bd568
3
+ size 291165
workspace/data/cil_charts_rgb_refs/val/object_embeddings_rgb_layout.npz ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:411ee7d4c96458879f14fc9460c0e10d5309d83aacd5552c6bcbe089e81838bc
3
+ size 63579