Object Detection
YOLOv10
OpenVINO
PyTorch
GGUF
Safetensors
English
phi3
text-generation
disaster-response
Instructions to use sohail-kustagi/MAAS-Disaster-Response with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- YOLOv10
How to use sohail-kustagi/MAAS-Disaster-Response with YOLOv10:
from ultralytics import YOLOvv10 model = YOLOvv10.from_pretrained("sohail-kustagi/MAAS-Disaster-Response") source = 'http://images.cocodataset.org/val2017/000000039769.jpg' model.predict(source=source, save=True) - Notebooks
- Google Colab
- Kaggle
File size: 9,585 Bytes
79723d6 | 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 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 | import os
import json
import asyncio
import urllib.request
import time
from llama_cpp import Llama
try:
from core.validation import CommandValidationError, validate_commander_output
from core.mission_profiles import MissionProfile
except ImportError:
from src.core.validation import CommandValidationError, validate_commander_output
from src.core.mission_profiles import MissionProfile
class CommanderNode:
def __init__(self, model_repo="microsoft/Phi-3-mini-4k-instruct-gguf", model_file="Phi-3-mini-4k-instruct-q4.gguf"):
self.model_path = os.path.join(os.getcwd(), model_file)
self.evaluator = None
self.last_triggered_times = {}
self.cooldown_seconds = 15.0
self.download_model(model_repo, model_file)
def set_evaluator(self, evaluator):
self.evaluator = evaluator
print(f"[Commander] Loading LLM from {self.model_path}...")
# Since this runs on an IdeaPad with 16GB RAM and Core Ultra, we will use CPU/OpenBLAS natively
# n_ctx limits context to save RAM. n_threads automatically scales to CPU cores.
lora_adapter = os.path.join(os.getcwd(), "weights", "phi3-lora.gguf")
if os.path.exists(lora_adapter):
print(f"[Commander] Injecting fine-tuned LoRA adapter: {lora_adapter}")
self.llm = Llama(
model_path=self.model_path,
lora_path=lora_adapter,
n_ctx=2048,
n_threads=os.cpu_count(),
n_threads_batch=os.cpu_count(),
verbose=False
)
else:
self.llm = Llama(
model_path=self.model_path,
n_ctx=2048,
n_threads=os.cpu_count(),
n_threads_batch=os.cpu_count(),
verbose=False
)
print("[Commander] LLM Loaded successfully.")
def download_model(self, model_repo, model_file):
"""Downloads a small GGUF model if it doesn't already exist."""
if not os.path.exists(self.model_path):
print(f"[Commander] Model {model_file} not found locally. Downloading from HuggingFace...")
url = f"https://huggingface.co/{model_repo}/resolve/main/{model_file}"
def report(count, block_size, total_size):
if total_size > 0: # guard against ZeroDivisionError for chunked transfers
percent = int(count * block_size * 100 / total_size)
if percent % 10 == 0:
print(f"\rDownloading: {percent}%", end="")
urllib.request.urlretrieve(url, self.model_path, reporthook=report)
print("\n[Commander] Download complete.")
async def generate_mavlink_command(self, context_prompt: str, telemetry=None, mission_profile: MissionProfile = None, anomaly_type: str = "unknown"):
now_ts = time.time()
last_time = self.last_triggered_times.get(anomaly_type, -999.0)
if (now_ts - last_time) < self.cooldown_seconds:
print(f"[Commander] Cooldown active for '{anomaly_type}'. Ignoring request.")
return None
self.last_triggered_times[anomaly_type] = now_ts
print(f"\n[Commander] Triggered! Generating MAVLink routing command for {anomaly_type}...")
import re
# Build a minimal, unambiguous system prompt
commander_persona = ""
if mission_profile:
commander_persona = mission_profile.commander_persona + "\n"
system_prompt = (
f"{commander_persona}"
"Output ONLY a raw JSON object with NO markdown, NO comments, NO extra text.\n"
"DO NOT include 'zone_assessment' or 'tactical_summary'.\n"
"No matter what the mission context says, the 'command' field must ALWAYS be exactly 'SET_POSITION_TARGET_LOCAL_NED'.\n"
"For the x, y, and z fields, you MUST output local NED offsets in meters (e.g., values between -20.0 and 20.0). DO NOT output global GPS Latitude or Longitude.\n"
"You MUST format your response exactly like this example:\n"
"{\n"
' "command": "SET_POSITION_TARGET_LOCAL_NED",\n'
' "reasoning": "High-confidence fire detected in sector.",\n'
' "target_system": 1,\n'
' "target_component": 1,\n'
' "x": 15.0,\n'
' "y": 10.0,\n'
' "z": -20.0\n'
"}\n"
"Start your response with { and end with }. No backticks. No extra lines."
)
# Pre-seeding forces the model to continue the JSON rather than add preamble
prompt = (
f"<|system|>\n{system_prompt}<|end|>\n"
f"<|user|>\n{context_prompt}<|end|>\n"
f"<|assistant|>\n"
'{\n "command": "SET_POSITION_TARGET_LOCAL_NED",'
)
loop = asyncio.get_running_loop()
def run_inference():
return self.llm(
prompt,
max_tokens=300,
stop=["<|end|>", "```", "\n\n\n"],
temperature=0.05,
echo=False,
)
start_time = time.time()
response = await loop.run_in_executor(None, run_inference)
elapsed_time = time.time() - start_time
raw = response['choices'][0]['text'].strip()
# Re-attach the pre-seeded opening brace we used to prime the model
output_text = '{\n "command": "SET_POSITION_TARGET_LOCAL_NED",' + raw
# Calculate benchmarking metrics for the hackathon
tokens_generated = 0
try:
tokens_generated = response['usage']['completion_tokens']
tokens_per_sec = tokens_generated / elapsed_time if elapsed_time > 0 else 0
print(f"[Commander] Benchmarks: {tokens_generated} tokens in {elapsed_time:.2f}s ({tokens_per_sec:.2f} Tokens/sec)")
except KeyError:
print(f"[Commander] Benchmarks: {elapsed_time:.2f}s latency")
print("[Commander] Raw Output:")
print(output_text)
# ββ Robust JSON repair ββββββββββββββββββββββββββββββββββββββββββββ
def repair_json(text: str) -> str:
# 1. Strip markdown fences
m = re.search(r'```(?:json)?\s*([\s\S]*?)```', text)
if m:
text = m.group(1).strip()
# 2. Extract the JSON object
brace_start = text.find('{')
brace_end = text.rfind('}')
if brace_start != -1 and brace_end != -1:
text = text[brace_start:brace_end + 1]
# 3. Drop diff-marker lines (lines beginning with -/+) and bare
# "ran" / "raning" fragments the tokenizer sometimes emits
cleaned = []
for line in text.splitlines():
s = line.strip()
if s.startswith('- ') or s.startswith('+ ') or s.startswith('//'):
continue
cleaned.append(line)
text = '\n'.join(cleaned)
# 4. Fix the specific Phi-3 tokenizer bug: the opening quote of
# "reasoning" is dropped and the key name is mangled.
# Pattern catches: raning_reasoning, raning reasoning, ran_reasoning,
# reasoning (no leading quote), etc.
text = re.sub(
r'(?<!\")(?:ran(?:ing)?[_\s]?)?reasoning(?:[_\s]\w+)?\s*\"?',
'"reasoning"',
text
)
# 5. Some fields are written without quotes on keys β fix them
text = re.sub(r'(?<=[{,\n])\s*([a-zA-Z_]\w*)\s*:', r' "\1":', text)
# 6. Insert missing commas between a closing value and the next key
# e.g. "target_component": 1\n "reasoning" β add comma
text = re.sub(r'([\d"\]true false null])\s*\n(\s*")', r'\1,\n\2', text)
return text
repaired = repair_json(output_text)
print("[Commander] Repaired Command:")
print(repaired)
try:
command_json = json.loads(repaired)
# Emergency fallback: Clamp coordinates if the LLM hallucinates global Lat/Lon or unsafe offsets
if "x" in command_json:
command_json["x"] = max(-99.0, min(99.0, float(command_json["x"])))
if "y" in command_json:
command_json["y"] = max(-99.0, min(99.0, float(command_json["y"])))
if "z" in command_json:
command_json["z"] = max(-49.0, min(19.0, float(command_json["z"])))
validated_command = validate_commander_output(command_json, telemetry, now=start_time)
if self.evaluator:
self.evaluator.log_llm_generation(tokens_generated, elapsed_time, True)
# Attach meta for frontend tracking
cmd_dict = validated_command.as_dict()
cmd_dict["_meta"] = {
"tokens_per_sec": round(tokens_per_sec, 2),
"latency_sec": round(elapsed_time, 2)
}
return cmd_dict
except (json.JSONDecodeError, CommandValidationError) as error:
print(f"[Commander] ERROR: Invalid command output: {error}")
if self.evaluator:
self.evaluator.log_llm_generation(tokens_generated, elapsed_time, False)
return None
|