Image-to-Text
PyTorch
Safetensors
PEFT
English
remote-sensing
satellite-imagery
earth-observation
change-detection
visual-grounding
image-captioning
visual-question-answering
optical-sar-fusion
sar
multimodal
lora
Instructions to use thundercode/SatQuery with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- PEFT
How to use thundercode/SatQuery with PEFT:
Task type is invalid.
- Notebooks
- Google Colab
- Kaggle
File size: 6,868 Bytes
b6e40ec | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 | """Generate models/manifest.json and models/checksums.sha256 from the real artifact files.
RULE: nothing in the manifest is typed by hand. Every byte count and every sha256 is computed
here by reading the file. Where a value cannot be determined from disk it is emitted as null,
never guessed.
Read-only with respect to the artifacts. Writes only the two generated files.
"""
import hashlib
import json
import os
import sys
import datetime
SRC = r"C:/Users/anish/satquery-ai"
OUT_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "repo", "models")
OUT_DIR = os.path.abspath(OUT_DIR)
CONFIG_HASH = "78f1e3700da15aa1" # verified by running get_config().hash
# The six released artifacts. Paths are relative to SRC.
ARTIFACTS = [
{
"id": "change_head",
"task": "change",
"kind": "trained_head",
"path": "artifacts/change/levir_change_v001/head.pt",
"hf_path": "change/head.pt",
"backbone": None,
"architecture": "STANet-style Siamese change detector (ResNet-18 + PAM)",
"source_metric_artifact": "artifacts/change/eval_test/eval_result.json",
},
{
"id": "change_vqa_head",
"task": "change_vqa",
"kind": "trained_head",
"path": "artifacts/change_vqa/run/head.pt",
"hf_path": "change_vqa/head.pt",
"backbone": "STANet change detector (frozen, backing the head's change features)",
"architecture": "change_vqa_head_v1",
"source_metric_artifact": "artifacts/change_vqa/run/PROMOTION.json",
},
{
"id": "optical_sar_fusion_head",
"task": "optical_sar",
"kind": "trained_head",
"path": "artifacts/optical_sar/fusion_head_production_v001/head.pt",
"hf_path": "optical_sar/head.pt",
"backbone": "antofuller/CROMA (CROMA_base.pt, revision 0dd28e3d633b)",
"architecture": "CROMA-base fusion head (input_dim 2318 -> hidden 512 -> 19 classes)",
"source_metric_artifact": "artifacts/optical_sar/fusion_head_production_v001/pre_registered_115_metric.json",
},
{
"id": "grounding_head",
"task": "grounding",
"kind": "trained_head",
"path": "artifacts/grounding/remoteclip_grounding_v001/head.pt",
"hf_path": "grounding/head.pt",
"backbone": "chendelong/RemoteCLIP (RemoteCLIP-ViT-B-32.pt, revision bf1d8a3ccf2d)",
"architecture": "RemoteCLIP ViT-B/32 grounding head (feature_dim 2048, hidden 512)",
"source_metric_artifact": "artifacts/grounding/remoteclip_grounding_v001/eval_result_canonical.json",
},
{
"id": "router_adapter",
"task": "router",
"kind": "trained_adapter",
"path": "artifacts/router/router_adapter_v001/adapter.pt",
"hf_path": "router/adapter.pt",
"backbone": "sentence-transformers/all-MiniLM-L6-v2 (revision 1110a243fdf4)",
"architecture": "task/modality adapter over frozen MiniLM embeddings (~50,822 params)",
"source_metric_artifact": "artifacts/router/threshold_sweep_val.json",
},
{
"id": "vlm_lora_adapter",
"task": "vlm",
"kind": "lora_adapter",
"path": ".scratch/phase6_real_adapter/phase6_adapter/adapter_model.safetensors",
"hf_path": "vlm/adapter_model.safetensors",
"backbone": "HuggingFaceTB/SmolVLM-500M-Instruct (revision a7da5b986cb5)",
"architecture": "PEFT LoRA (r=16, alpha=32, dropout=0.05) on text_model projections",
"source_metric_artifact": "artifacts/vlm/phase6_closure.json",
"acceptance": "ACCEPTANCE-REJECTED (metrics usable; not promoted)",
},
]
def sha256_of(path, chunk=1 << 20):
h = hashlib.sha256()
with open(path, "rb") as fh:
while True:
b = fh.read(chunk)
if not b:
break
h.update(b)
return h.hexdigest()
def read_json(path):
try:
with open(path, encoding="utf-8") as fh:
return json.load(fh)
except Exception:
return None
def main():
entries = []
missing = []
for a in ARTIFACTS:
full = os.path.join(SRC, a["path"])
e = dict(a)
e["config_hash"] = CONFIG_HASH
if not os.path.exists(full):
e["bytes"] = None
e["sha256"] = None
e["status"] = "MISSING_ON_DISK"
missing.append(a["path"])
else:
e["bytes"] = os.path.getsize(full)
e["sha256"] = sha256_of(full)
e["status"] = "PRESENT"
# pull the artifact's own declared parameter count where it records one
e["parameters"] = None
src_metric = os.path.join(SRC, a.get("source_metric_artifact") or "")
if os.path.exists(src_metric):
d = read_json(src_metric)
if isinstance(d, dict):
art = d.get("artifact")
if isinstance(art, dict):
e["parameters"] = art.get("parameters")
entries.append(e)
manifest = {
"schema": "satquery_model_manifest_v1",
"generated_utc": datetime.datetime.now(datetime.timezone.utc)
.replace(microsecond=0)
.isoformat(),
"generator": "release/tools/generate_model_manifest.py",
"note": (
"Generated by reading the files. No byte count or hash is typed by hand. "
"Backbones are NOT redistributed; they are fetched from the Hugging Face Hub, "
"pinned by revision."
),
"config_hash": CONFIG_HASH,
"release_repo": "thundercode/SatQuery",
"artifact_count": len(entries),
"artifacts": entries,
}
os.makedirs(OUT_DIR, exist_ok=True)
mpath = os.path.join(OUT_DIR, "manifest.json")
with open(mpath, "w", encoding="utf-8", newline="\n") as fh:
json.dump(manifest, fh, indent=2, ensure_ascii=False)
fh.write("\n")
cpath = os.path.join(OUT_DIR, "checksums.sha256")
with open(cpath, "w", encoding="utf-8", newline="\n") as fh:
fh.write("# sha256 of the six released artifacts, keyed by their path in this repository.\n")
fh.write("# Verify with: sha256sum -c checksums.sha256\n")
for e in entries:
if e["sha256"]:
# sha256sum format: "<hash> <name>"
fh.write(f"{e['sha256']} {e['hf_path']}\n")
print(f"wrote {mpath}")
print(f"wrote {cpath}")
print()
for e in entries:
b = f"{e['bytes']:,}" if e["bytes"] is not None else "-"
h = (e["sha256"] or "-")[:16]
print(f" {e['status']:16} {e['id']:24} {b:>14} {h}… {e['path']}")
if missing:
print()
print("MISSING FILES (manifest records null, never a guess):")
for m in missing:
print(" " + m)
return 1
return 0
if __name__ == "__main__":
sys.exit(main())
|