Download satlink/examples/quickstart.py from lulidong/rs: direct link, hf CLI and curl.
- Browser
- Download file 2.87 kB
-
https://huggingface.co/lulidong/rs/resolve/main/satlink/examples/quickstart.py
- Command line
-
hf download hf://lulidong/rs/satlink/examples/quickstart.py
-
curl -L -o quickstart.py https://huggingface.co/lulidong/rs/resolve/main/satlink/examples/quickstart.py
2.87 kB
| """The shortest end-to-end call of satlink, as an application would write it. | |
| python -m satlink.examples.quickstart --image satlink/assets/grid3x3_600x600.png --out /tmp/qs | |
| Runs both halves in one process for readability. In deployment they are two processes on two | |
| machines and the only thing that crosses is `codes.json` (or the packed bytes) -- which is the | |
| point: nothing here reaches across the split except that file. | |
| """ | |
| import argparse | |
| import os | |
| import sys | |
| import satlink | |
| def main(): | |
| ap = argparse.ArgumentParser() | |
| ap.add_argument("--image", required=True, help="PNG or BMP") | |
| ap.add_argument("--out", default="/tmp/satlink_quickstart") | |
| ap.add_argument("--sat-weights", default="satlink/weights/sat_encoder.pt") | |
| ap.add_argument("--decoder", default="satlink/weights/ground_decoder.pt") | |
| ap.add_argument("--model", default=None, help="RSThinker dir; omit to skip the LLM step") | |
| ap.add_argument("--question", default="describe the image") | |
| ap.add_argument("--batch", type=int, default=64, help="crops per encoder call") | |
| ap.add_argument("--dtype", default="float16") | |
| a = ap.parse_args() | |
| os.makedirs(a.out, exist_ok=True) | |
| # ---------------------------------------------------------------- 星上 | |
| # The profile is a deployment constant; here it is read off the file so the example runs on | |
| # any input. In flight the size is known ahead of time and this lookup does not happen. | |
| from satlink.imageio import StripReader | |
| with StripReader(a.image) as r: | |
| w, h = r.width, r.height | |
| sat = satlink.Satellite(a.sat_weights, w, h, dtype=a.dtype) | |
| frame = sat.encode_file(a.image, batch=a.batch) | |
| codes = os.path.join(a.out, "codes.json") | |
| sat.save(frame, codes) | |
| wire = sat.to_wire(frame) | |
| print(f"星上 {w}x{h} -> {sat.n_crops} 个切片 x {frame.profile.n_tok} token " | |
| f"= {len(wire)} 字节下行,压缩比 {sat.compression_ratio:.1f}x") | |
| print(f" 落盘 {codes}") | |
| # ---------------------------------------------------------------- 链路 | |
| # 下行只有码字。帧尺寸和 token 几何都不在流里,是两端约定的常量,所以这里要显式给出。 | |
| # 这里直接把 profile 传过去,它把四个常量一起带上——只对齐 n_tok 而漏掉 bits, | |
| # 正是会解出错误长度的那种失误。 | |
| frame = satlink.frame_from_wire(wire, profile=frame.profile) | |
| # ---------------------------------------------------------------- 地面 | |
| recon = os.path.join(a.out, "recon.png") | |
| satlink.Ground(a.decoder).reconstruct(frame).save(recon) | |
| print(f"地面 重建 -> {recon}") | |
| if a.model: | |
| vlm = satlink.GroundVLM(a.model, decoder=a.decoder) | |
| print(f" Q: {a.question}\n A: {vlm.ask(frame, a.question, max_new=128)}") | |
| return 0 | |
| if __name__ == "__main__": | |
| sys.exit(main()) | |