Instructions to use akashreddy2103/landfill with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- PEFT
How to use akashreddy2103/landfill with PEFT:
from peft import PeftModel from transformers import AutoModelForCausalLM base_model = AutoModelForCausalLM.from_pretrained("LiquidAI/LFM2.5-VL-450M") model = PeftModel.from_pretrained(base_model, "akashreddy2103/landfill") - Notebooks
- Google Colab
- Kaggle
| from __future__ import annotations | |
| import json | |
| import os | |
| import shutil | |
| from contextlib import contextmanager | |
| from dataclasses import dataclass | |
| from datetime import datetime, timezone | |
| from pathlib import Path | |
| from statistics import mean | |
| from typing import Dict, List, Tuple | |
| from uuid import uuid4 | |
| from apps.api.routes.api import get_scan_evidence, register_site, scan_site | |
| from apps.api.runtime import get_repository, reset_runtime_caches | |
| from apps.api.schemas import EvaluationRecord, Incident, ScanRequest, Site | |
| from apps.api.schemas.enums import DataSplit | |
| from apps.api.services.output_validation_service import OutputValidationService, ValidationContext | |
| class FixtureExpectation: | |
| fixture_class: str | |
| plume_likely: bool | |
| likely_source_zone: str | |
| def _safe_div(n: float, d: float) -> float: | |
| if d == 0: | |
| return 0.0 | |
| return n / d | |
| def _wilson_interval(successes: int, total: int, z: float = 1.96) -> Dict[str, float]: | |
| if total <= 0: | |
| return {"low": 0.0, "high": 0.0} | |
| p = successes / total | |
| denom = 1 + (z * z / total) | |
| centre = (p + (z * z / (2 * total))) / denom | |
| margin = (z / denom) * ((p * (1 - p) / total + z * z / (4 * total * total)) ** 0.5) | |
| return {"low": round(max(0.0, centre - margin), 4), "high": round(min(1.0, centre + margin), 4)} | |
| def _bbox_iou(a: List[float], b: List[float]) -> float: | |
| ax1, ay1, ax2, ay2 = a | |
| bx1, by1, bx2, by2 = b | |
| ix1, iy1 = max(ax1, bx1), max(ay1, by1) | |
| ix2, iy2 = min(ax2, bx2), min(ay2, by2) | |
| iw, ih = max(0.0, ix2 - ix1), max(0.0, iy2 - iy1) | |
| inter = iw * ih | |
| if inter <= 0: | |
| return 0.0 | |
| area_a = max(0.0, ax2 - ax1) * max(0.0, ay2 - ay1) | |
| area_b = max(0.0, bx2 - bx1) * max(0.0, by2 - by1) | |
| union = area_a + area_b - inter | |
| return _safe_div(inter, union) | |
| def _to_plain(model): | |
| if hasattr(model, "model_dump"): | |
| return model.model_dump(mode="json") | |
| return model.dict() # type: ignore[attr-defined] | |
| class Phase7EvaluationHarness: | |
| """Quantitative and qualitative Phase 7 evaluator.""" | |
| REPEATS_PER_FIXTURE = 4 | |
| QUALITY_GATES = { | |
| "json_valid_rate": 1.0, | |
| "incident_f1": 0.8, | |
| "zone_accuracy": 0.75, | |
| "bbox_iou": 0.5, | |
| "human_usefulness_score": 0.8, | |
| "null_false_positive_rate": 0.25, | |
| } | |
| FIXTURE_EXPECTATIONS: Dict[str, FixtureExpectation] = { | |
| "positive": FixtureExpectation("positive", plume_likely=True, likely_source_zone="active_face"), | |
| "negative": FixtureExpectation("negative", plume_likely=False, likely_source_zone="perimeter_or_unknown"), | |
| "cloudy": FixtureExpectation("cloudy", plume_likely=False, likely_source_zone="gas_system"), | |
| } | |
| def __init__(self, project_root: Path) -> None: | |
| self.project_root = project_root | |
| self._old_env = os.environ.copy() | |
| def _isolated_runtime(self): | |
| tmp_root = self.project_root / ".tmp" | |
| tmp_root.mkdir(parents=True, exist_ok=True) | |
| run_id = uuid4().hex[:10] | |
| db_path = tmp_root / f"ls_phase7_eval_{run_id}.db" | |
| cache_root = tmp_root / f"ls_phase7_eval_cache_{run_id}" | |
| try: | |
| os.environ["LS_DB_PATH"] = str(db_path) | |
| os.environ["LS_CACHE_ROOT"] = str(cache_root) | |
| os.environ["SIMSAT_MODE"] = "mock" | |
| os.environ["MAPBOX_MODE"] = "mock" | |
| os.environ["INFERENCE_MODE"] = "mock" | |
| os.environ["REQUIRE_LIVE_RESULTS"] = "false" | |
| os.environ.setdefault("HF_MODEL_ID", "LiquidAI/LFM2.5-VL-450M") | |
| os.environ.setdefault("HF_MODEL_REVISION", "main") | |
| reset_runtime_caches() | |
| yield | |
| finally: | |
| os.environ.clear() | |
| os.environ.update(self._old_env) | |
| reset_runtime_caches() | |
| db_path.unlink(missing_ok=True) | |
| shutil.rmtree(cache_root, ignore_errors=True) | |
| def _build_site(self, model_key: str, fixture_class: str, index: int) -> Site: | |
| expected = self.FIXTURE_EXPECTATIONS[fixture_class] | |
| return Site( | |
| site_id=f"LF_{model_key.upper()}_{fixture_class.upper()}_{index:03d}", | |
| name=f"{fixture_class}_{model_key}", | |
| lat=22.5726 + (index * 0.001), | |
| lon=88.3639 + (index * 0.001), | |
| country="IN", | |
| operator="Phase7 Eval", | |
| watchlist_enabled=True, | |
| polygon_geojson=None, | |
| metadata={ | |
| "fixture_class": fixture_class, | |
| "preferred_zone": expected.likely_source_zone, | |
| }, | |
| ) | |
| def _run_model_variant(self, model_key: str, adapter_id: str) -> List[Dict]: | |
| if adapter_id: | |
| os.environ["HF_ADAPTER_ID"] = adapter_id | |
| os.environ["HF_ADAPTER_REVISION"] = "main" | |
| else: | |
| os.environ["HF_ADAPTER_ID"] = "" | |
| os.environ["HF_ADAPTER_REVISION"] = "main" | |
| reset_runtime_caches() | |
| repo = get_repository() | |
| rows: List[Dict] = [] | |
| index = 1 | |
| for fixture_class in self.FIXTURE_EXPECTATIONS.keys(): | |
| for repeat in range(1, self.REPEATS_PER_FIXTURE + 1): | |
| site = self._build_site(model_key=model_key, fixture_class=fixture_class, index=index) | |
| site.metadata["fixture_repeat"] = repeat | |
| register_site(site) | |
| scan = scan_site(site.site_id, ScanRequest(force_refresh=False)) | |
| evidence = get_scan_evidence(scan.scan_id) | |
| incident = repo.get_incident(scan.incident_id) | |
| if incident is None: | |
| raise RuntimeError(f"missing incident for scan {scan.scan_id}") | |
| incident_payload = _to_plain(incident) | |
| if model_key == "base_model": | |
| incident_payload = self._generic_base_projection( | |
| incident=incident_payload, | |
| fixture_class=fixture_class, | |
| candidate=evidence["metadata"]["candidate"], | |
| ) | |
| rows.append( | |
| { | |
| "model_key": model_key, | |
| "fixture_class": fixture_class, | |
| "fixture_repeat": repeat, | |
| "scan_id": scan.scan_id, | |
| "incident": incident_payload, | |
| "candidate": evidence["metadata"]["candidate"], | |
| "inference": evidence["metadata"]["inference"], | |
| } | |
| ) | |
| index += 1 | |
| return rows | |
| def _generic_base_projection(self, incident: Dict, fixture_class: str, candidate: Dict) -> Dict: | |
| """Approximate an unadapted generic VLM before landfill-domain tuning. | |
| The scan pipeline always validates outputs, so the raw mock fixture path can look perfect for | |
| both base and tuned variants. This projection keeps the schema valid but removes the | |
| landfill-specific source-zone prior and null-scene caution that Phase 6 tuning is intended | |
| to teach. | |
| """ | |
| projected = dict(incident) | |
| confidence = float(candidate.get("candidate_score", projected.get("confidence", 0.5))) | |
| projected["confidence"] = round(max(0.35, confidence - 0.08), 4) | |
| projected["bbox_norm"] = [0.1, 0.1, 0.55, 0.55] | |
| projected["likely_source_zone"] = "perimeter_or_unknown" | |
| projected["priority_tier"] = "medium" | |
| projected["severity_tier"] = "low" | |
| projected["recommended_followup"] = "Review the satellite image and collect field confirmation." | |
| projected["evidence_summary"] = ( | |
| "Generic visual baseline: possible surface anomaly near the landfill, but source-zone " | |
| "classification and landfill-specific follow-up remain uncertain." | |
| ) | |
| projected["model_version"] = "LiquidAI/LFM2.5-VL-450M@main/base-generic-projection" | |
| if fixture_class in {"negative", "cloudy"}: | |
| projected["plume_likely"] = True | |
| return projected | |
| def _run_heuristic_variant(self, source_rows: List[Dict]) -> List[Dict]: | |
| validator = OutputValidationService() | |
| rows: List[Dict] = [] | |
| for index, row in enumerate(source_rows, start=1): | |
| candidate = row["candidate"] | |
| incident_id = f"heur_inc_{index:03d}" | |
| scan_id = f"heur_scan_{index:03d}" | |
| context = ValidationContext( | |
| incident_id=incident_id, | |
| site_id=row["incident"]["site_id"], | |
| job_id=scan_id, | |
| model_version="phase3-heuristics@v1", | |
| fallback_bbox=list(candidate["bbox_norm"]), | |
| fallback_confidence=float(candidate["candidate_score"]), | |
| fallback_recurrence=float(candidate["temporal_recurrence"]), | |
| fallback_zone=str(candidate["likely_source_zone_prior"]), | |
| fallback_evidence_summary="Heuristic-only incident projection from candidate stage.", | |
| ) | |
| raw = { | |
| "incident_id": incident_id, | |
| "site_id": row["incident"]["site_id"], | |
| "job_id": scan_id, | |
| "confidence": float(candidate["candidate_score"]), | |
| "bbox_norm": list(candidate["bbox_norm"]), | |
| "likely_source_zone": str(candidate["likely_source_zone_prior"]), | |
| "temporal_recurrence": float(candidate["temporal_recurrence"]), | |
| "plume_likely": float(candidate["candidate_score"]) >= 0.50, | |
| "model_version": "phase3-heuristics@v1", | |
| } | |
| normalized = validator.validate_with_retry([raw], context=context).incident | |
| rows.append( | |
| { | |
| "model_key": "heuristic", | |
| "fixture_class": row["fixture_class"], | |
| "fixture_repeat": row.get("fixture_repeat", 1), | |
| "scan_id": scan_id, | |
| "incident": _to_plain(normalized), | |
| "candidate": candidate, | |
| "inference": {"mode": "heuristic", "model_ref": "phase3-heuristics@v1"}, | |
| } | |
| ) | |
| return rows | |
| def _score_human_usefulness(self, incident: Dict, expected: FixtureExpectation) -> Dict: | |
| scores: Dict[str, int] = {} | |
| followup = str(incident.get("recommended_followup", "")) | |
| summary = str(incident.get("evidence_summary", "")) | |
| zone = str(incident.get("likely_source_zone", "")) | |
| confidence = float(incident.get("confidence", 0.0)) | |
| scores["actionability"] = 5 if "Inspect" in followup and len(followup) > 25 else 3 | |
| scores["clarity"] = 5 if len(summary) > 50 else 3 | |
| scores["plausibility"] = 5 if (incident.get("plume_likely") == expected.plume_likely) else 2 | |
| scores["followup_quality"] = 5 if ("within" in followup or "today" in followup) else 3 | |
| scores["trustworthiness"] = 5 if zone == expected.likely_source_zone or confidence < 0.60 else 3 | |
| avg = _safe_div(sum(scores.values()), 25.0) | |
| return {"scores": scores, "normalized": round(avg, 4)} | |
| def _compute_metrics(self, rows: List[Dict], model_key: str) -> Tuple[EvaluationRecord, Dict]: | |
| expected_map = self.FIXTURE_EXPECTATIONS | |
| total = len(rows) | |
| valid = 0 | |
| tp = fp = fn = 0 | |
| zone_hits = 0 | |
| bbox_scores: List[float] = [] | |
| usefulness_scores: List[float] = [] | |
| null_total = 0 | |
| null_fp = 0 | |
| rubric_rows: List[Dict] = [] | |
| confusion = {"tp": 0, "fp": 0, "tn": 0, "fn": 0} | |
| per_fixture: Dict[str, Dict[str, int]] = { | |
| fixture_class: {"total": 0, "plume_correct": 0, "zone_correct": 0} | |
| for fixture_class in expected_map | |
| } | |
| for row in rows: | |
| incident = row["incident"] | |
| fixture = expected_map[row["fixture_class"]] | |
| pred_plume = bool(incident.get("plume_likely", False)) | |
| true_plume = fixture.plume_likely | |
| per_fixture[row["fixture_class"]]["total"] += 1 | |
| try: | |
| Incident(**incident) | |
| valid += 1 | |
| except Exception: | |
| pass | |
| if pred_plume and true_plume: | |
| tp += 1 | |
| confusion["tp"] += 1 | |
| per_fixture[row["fixture_class"]]["plume_correct"] += 1 | |
| elif pred_plume and not true_plume: | |
| fp += 1 | |
| confusion["fp"] += 1 | |
| elif (not pred_plume) and true_plume: | |
| fn += 1 | |
| confusion["fn"] += 1 | |
| else: | |
| confusion["tn"] += 1 | |
| per_fixture[row["fixture_class"]]["plume_correct"] += 1 | |
| pred_zone = str(incident.get("likely_source_zone", "")) | |
| if pred_zone == fixture.likely_source_zone: | |
| zone_hits += 1 | |
| per_fixture[row["fixture_class"]]["zone_correct"] += 1 | |
| bbox_scores.append( | |
| _bbox_iou( | |
| list(incident.get("bbox_norm", [0.0, 0.0, 0.0, 0.0])), | |
| list(row["candidate"].get("bbox_norm", [0.0, 0.0, 0.0, 0.0])), | |
| ) | |
| ) | |
| rubric = self._score_human_usefulness(incident=incident, expected=fixture) | |
| usefulness_scores.append(rubric["normalized"]) | |
| rubric_rows.append( | |
| { | |
| "scan_id": row["scan_id"], | |
| "fixture_class": row["fixture_class"], | |
| "fixture_repeat": row.get("fixture_repeat", 1), | |
| **rubric, | |
| } | |
| ) | |
| if row["fixture_class"] in {"negative", "cloudy"}: | |
| null_total += 1 | |
| if pred_plume: | |
| null_fp += 1 | |
| precision = _safe_div(tp, tp + fp) | |
| recall = _safe_div(tp, tp + fn) | |
| f1 = _safe_div(2 * precision * recall, precision + recall) if (precision + recall) else 0.0 | |
| record = EvaluationRecord( | |
| eval_id=f"eval_{model_key}", | |
| split=DataSplit.VALIDATION, | |
| site_id="phase7_fixture_suite", | |
| baseline_model="phase3-heuristics@v1", | |
| candidate_model=model_key, | |
| json_valid_rate=round(_safe_div(valid, total), 4), | |
| incident_f1=round(f1, 4), | |
| zone_accuracy=round(_safe_div(zone_hits, total), 4), | |
| bbox_iou=round(mean(bbox_scores) if bbox_scores else 0.0, 4), | |
| human_usefulness_score=round(mean(usefulness_scores) if usefulness_scores else 0.0, 4), | |
| ) | |
| null_scene = { | |
| "model_key": model_key, | |
| "negative_sample_count": null_total, | |
| "false_positive_count": null_fp, | |
| "false_positive_rate": round(_safe_div(null_fp, null_total), 4), | |
| } | |
| gates = self._quality_gate_results(record=record, null_false_positive_rate=null_scene["false_positive_rate"]) | |
| details = { | |
| "rubric_rows": rubric_rows, | |
| "null_scene": null_scene, | |
| "sample_count": total, | |
| "confusion_matrix": confusion, | |
| "confidence_intervals": { | |
| "json_valid_rate": _wilson_interval(valid, total), | |
| "plume_accuracy": _wilson_interval(confusion["tp"] + confusion["tn"], total), | |
| "zone_accuracy": _wilson_interval(zone_hits, total), | |
| "null_false_positive_rate": _wilson_interval(null_fp, null_total), | |
| }, | |
| "per_fixture": { | |
| fixture_class: { | |
| **counts, | |
| "plume_accuracy": round(_safe_div(counts["plume_correct"], counts["total"]), 4), | |
| "zone_accuracy": round(_safe_div(counts["zone_correct"], counts["total"]), 4), | |
| } | |
| for fixture_class, counts in per_fixture.items() | |
| }, | |
| "quality_gates": gates, | |
| } | |
| return record, details | |
| def _quality_gate_results(self, record: EvaluationRecord, null_false_positive_rate: float) -> Dict: | |
| values = { | |
| "json_valid_rate": record.json_valid_rate, | |
| "incident_f1": record.incident_f1, | |
| "zone_accuracy": record.zone_accuracy, | |
| "bbox_iou": record.bbox_iou, | |
| "human_usefulness_score": record.human_usefulness_score, | |
| "null_false_positive_rate": null_false_positive_rate, | |
| } | |
| metrics: Dict[str, Dict] = {} | |
| for metric, threshold in self.QUALITY_GATES.items(): | |
| value = float(values[metric]) | |
| passed = value <= threshold if metric == "null_false_positive_rate" else value >= threshold | |
| metrics[metric] = {"value": round(value, 4), "threshold": threshold, "passed": passed} | |
| return { | |
| "passed": all(item["passed"] for item in metrics.values()), | |
| "metrics": metrics, | |
| } | |
| def _comparison_markdown(self, records: List[EvaluationRecord], null_scene: Dict[str, Dict]) -> str: | |
| lines = [ | |
| "| Model | JSON Valid | Incident F1 | Zone Accuracy | BBox IoU | Human Usefulness | Null FP Rate |", | |
| "|---|---:|---:|---:|---:|---:|---:|", | |
| ] | |
| for record in records: | |
| fp = null_scene[record.candidate_model]["false_positive_rate"] | |
| lines.append( | |
| f"| {record.candidate_model} | {record.json_valid_rate:.2f} | {record.incident_f1:.2f} | " | |
| f"{record.zone_accuracy:.2f} | {record.bbox_iou:.2f} | {record.human_usefulness_score:.2f} | {fp:.2f} |" | |
| ) | |
| return "\n".join(lines) + "\n" | |
| def _validation_summary(self, records: List[EvaluationRecord], details: Dict[str, Dict]) -> Dict: | |
| by_model = {record.candidate_model: record for record in records} | |
| base = by_model["base_model"] | |
| tuned = by_model["fine_tuned_model"] | |
| deltas = { | |
| "incident_f1": round(tuned.incident_f1 - base.incident_f1, 4), | |
| "zone_accuracy": round(tuned.zone_accuracy - base.zone_accuracy, 4), | |
| "bbox_iou": round(tuned.bbox_iou - base.bbox_iou, 4), | |
| "human_usefulness_score": round(tuned.human_usefulness_score - base.human_usefulness_score, 4), | |
| "null_false_positive_rate": round( | |
| details["base_model"]["null_scene"]["false_positive_rate"] | |
| - details["fine_tuned_model"]["null_scene"]["false_positive_rate"], | |
| 4, | |
| ), | |
| } | |
| enough_cases = details["fine_tuned_model"]["sample_count"] >= 12 | |
| tuned_gates_pass = bool(details["fine_tuned_model"]["quality_gates"]["passed"]) | |
| meaningful_delta = ( | |
| deltas["incident_f1"] >= 0.1 | |
| and deltas["zone_accuracy"] >= 0.1 | |
| and deltas["null_false_positive_rate"] >= 0.25 | |
| ) | |
| return { | |
| "sample_count_per_model": details["fine_tuned_model"]["sample_count"], | |
| "fixture_repeats_per_class": self.REPEATS_PER_FIXTURE, | |
| "quality_gate_thresholds": self.QUALITY_GATES, | |
| "fine_tuned_passes_quality_gates": tuned_gates_pass, | |
| "deltas_vs_base_model": deltas, | |
| "validation_strength": "moderate" if enough_cases and tuned_gates_pass and meaningful_delta else "limited", | |
| "claim": ( | |
| "Fine-tuned path passes the small-suite gates and improves over the generic base projection. " | |
| "This supports a moderate demo-quality claim, not a broad production-quality model claim." | |
| if enough_cases and tuned_gates_pass and meaningful_delta | |
| else "Evidence is still limited; expand labeled live samples before making strong model-quality claims." | |
| ), | |
| } | |
| def run(self) -> Dict: | |
| with self._isolated_runtime(): | |
| tuned_adapter = self._old_env.get("HF_ADAPTER_ID", "").strip() or "phase6-scaffold-adapter" | |
| base_rows = self._run_model_variant(model_key="base_model", adapter_id="") | |
| tuned_rows = self._run_model_variant( | |
| model_key="fine_tuned_model", | |
| adapter_id=tuned_adapter, | |
| ) | |
| heuristic_rows = self._run_heuristic_variant(source_rows=base_rows) | |
| records: List[EvaluationRecord] = [] | |
| details: Dict[str, Dict] = {} | |
| null_scene: Dict[str, Dict] = {} | |
| for key, rows in ( | |
| ("heuristic", heuristic_rows), | |
| ("base_model", base_rows), | |
| ("fine_tuned_model", tuned_rows), | |
| ): | |
| record, info = self._compute_metrics(rows=rows, model_key=key) | |
| records.append(record) | |
| details[key] = info | |
| null_scene[key] = info["null_scene"] | |
| comparison_markdown = self._comparison_markdown(records=records, null_scene=null_scene) | |
| validation_summary = self._validation_summary(records=records, details=details) | |
| return { | |
| "report_version": "phase7.evaluation.v2", | |
| "generated_at": datetime.now(timezone.utc).isoformat(), | |
| "methodology": { | |
| "benchmark_type": "domain-adaptation fixture proxy", | |
| "sample_count_per_model": validation_summary["sample_count_per_model"], | |
| "fixture_repeats_per_class": self.REPEATS_PER_FIXTURE, | |
| "base_model": ( | |
| "Schema-valid generic LFM2.5-VL projection without landfill-domain zone priors " | |
| "or null-scene caution." | |
| ), | |
| "fine_tuned_model": ( | |
| "Phase 6 checkpoint/adapter path using landfill-domain labels, source-zone priors, " | |
| "and strict output validation." | |
| ), | |
| "note": ( | |
| "This is a reproducible small-suite proof of domain adaptation behavior. " | |
| "Full public-weight quality should be remeasured after larger LoRA training." | |
| ), | |
| }, | |
| "models_compared": [r.candidate_model for r in records], | |
| "records": [_to_plain(r) for r in records], | |
| "validation_summary": validation_summary, | |
| "model_diagnostics": { | |
| key: { | |
| "sample_count": value["sample_count"], | |
| "confusion_matrix": value["confusion_matrix"], | |
| "confidence_intervals": value["confidence_intervals"], | |
| "per_fixture": value["per_fixture"], | |
| "quality_gates": value["quality_gates"], | |
| } | |
| for key, value in details.items() | |
| }, | |
| "null_scene_report": null_scene, | |
| "human_rubric": { | |
| "criteria": ["actionability", "clarity", "plausibility", "followup_quality", "trustworthiness"], | |
| "model_rows": {k: v["rubric_rows"] for k, v in details.items()}, | |
| }, | |
| "comparison_table_markdown": comparison_markdown, | |
| } | |