I have a gpu! I want to use it!

This commit is contained in:
lda committed 2026-01-11 00:22:06 +07:00
1 parent b5ea0232f7
commit 013c082447
12 files changed
+252 -250

No files matched your search

+1 -1
View File
@@ -5,5 +5,5 @@
"**/*.rpymc": true, "**/*.rpymc": true,
"**/cache/": true "**/cache/": true
}, },
"pylint.args": ["--generated-members", "cv2.*"] "pylint.args": ["--generated-members", "cv2.*"],
} }
BIN
View File
Binary file not shown.
+3 -3
View File
@@ -74,8 +74,8 @@ def main():
cigarette_model=cigarette_model, cigarette_model=cigarette_model,
verifier_model=verifier, verifier_model=verifier,
vlm_model=None, # Optional vlm_model=None, # Optional
store=alert_store, sinks=[video_sink, alert_store],
sinks=[video_sink], inference_interval=0,
) )
if args.rtsp: if args.rtsp:
@@ -92,7 +92,7 @@ def main():
print("Stopped by user.") print("Stopped by user.")
finally: finally:
if args.rtsp and hasattr(source, "stop"): if args.rtsp and hasattr(source, "stop"):
source.stop() source.stop() # pyright: ignore[reportAttributeAccessIssue]
if video_sink: if video_sink:
video_sink.close() video_sink.close()
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
+64 -132
View File
@@ -1,20 +1,13 @@
import logging import logging
from collections import deque from collections import deque
from typing import Optional from typing import List, Optional, Tuple
from pipeline.protocols import AlertStore, Model, StreamSource, Verifier from pipeline.protocols import Model, Sink, StreamSource, Verifier
from pipeline.types import Frame, Ticket from pipeline.types import BoundingBox, Detection, Frame, Ticket
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class ConsoleStore:
def store(self, ticket: Ticket):
logger.info(
f"[STORE] Persisting Alert! Conf: {ticket.confidence:.2f} @ Stage: {ticket.stage_confirmed}"
)
class SmokingDetectionPipeline: class SmokingDetectionPipeline:
def __init__( def __init__(
self, self,
@@ -22,19 +15,20 @@ class SmokingDetectionPipeline:
cigarette_model: Model, cigarette_model: Model,
verifier_model: Verifier, verifier_model: Verifier,
vlm_model: Optional[Verifier] = None, vlm_model: Optional[Verifier] = None,
store: Optional[AlertStore] = None, sinks: Optional[list[Sink]] = None,
sinks: Optional[list] = None, inference_interval: float = 0.5,
): ):
self.person_model = person_model self.person_model = person_model
self.cigarette_model = cigarette_model self.cigarette_model = cigarette_model
self.verifier_model = verifier_model self.verifier_model = verifier_model
self.vlm_model = vlm_model self.vlm_model = vlm_model
self.store = store or ConsoleStore()
self.sinks = sinks or [] self.sinks = sinks or []
self.inference_interval = inference_interval
self.last_inference_time = 0.0
# Buffer for temporal context (optional, for VLM or sequence logic) # Buffer for temporal context (optional, for VLM or sequence logic)
self.frame_buffer = deque(maxlen=30) self.frame_buffer = deque(maxlen=30)
logger.info("Pipeline initialized.") logger.info(f"Pipeline initialized with {len(self.sinks)} sinks.")
def process_stream(self, source: StreamSource): def process_stream(self, source: StreamSource):
"""Main loop processing the video stream.""" """Main loop processing the video stream."""
@@ -47,7 +41,11 @@ class SmokingDetectionPipeline:
if count % 100 == 0: if count % 100 == 0:
logger.info(f"Processed {count} frames...") logger.info(f"Processed {count} frames...")
self.frame_buffer.append(frame) self.frame_buffer.append(frame)
self._process_frame(frame)
# Skip inference if too soon
if (frame.timestamp - self.last_inference_time) >= self.inference_interval:
self._process_frame(frame)
self.last_inference_time = frame.timestamp
# Update sinks (Visualizers, etc) # Update sinks (Visualizers, etc)
for sink in self.sinks: for sink in self.sinks:
@@ -57,11 +55,7 @@ class SmokingDetectionPipeline:
def _process_frame(self, frame: Frame): def _process_frame(self, frame: Frame):
# --- Step 1: Broad Phase (Person Detection) --- # --- Step 1: Broad Phase (Person Detection) ---
# "Is there a human here?"
# optimization: Resize or skip frames if inference is slow
people = self.person_model.predict(frame.data) people = self.person_model.predict(frame.data)
# Add to frame detections for visualization
frame.detections.extend(people) frame.detections.extend(people)
if not people: if not people:
@@ -70,29 +64,49 @@ class SmokingDetectionPipeline:
logger.debug(f"Frame {frame.frame_id}: Found {len(people)} people.") logger.debug(f"Frame {frame.frame_id}: Found {len(people)} people.")
# --- Step 2: Narrow Phase (Cigarette Candidate) --- # --- Step 2: Narrow Phase (Cigarette Candidate) ---
# "Is the human holding something small?" candidates = self._find_candidates(frame, people)
# We could optimize by only running on crops of the 'people'
candidates = []
for person in people:
# ROI: Region of Interest (e.g., upper body or hands)
# EXPANSTION: Expand the person box to include extended arms/surroundings
h_img, w_img = frame.data.shape[:2]
margin = 0.2 # 20% expansion
if not candidates:
return # EXIT
logger.debug(f"Frame {frame.frame_id}: Found {len(candidates)} candidates.")
# --- Step 3: Verification (Classifier) ---
best_hit = self._verify_candidates(frame, candidates)
# --- Step 4: Action ---
if best_hit:
person, cig, score = best_hit
ticket = Ticket(
frame_id=frame.frame_id,
confidence=score,
evidence=[frame.data],
stage_confirmed="Verifier", # Simplified for now
)
frame.ticket = ticket
def _find_candidates(
self, frame: Frame, people: List[Detection]
) -> List[Tuple[Detection, List[Detection], Tuple[int, int]]]:
"""Runs cigarette detection on expanded person crops."""
candidates = []
h_img, w_img = frame.data.shape[:2]
margin = 0.2 # 20% expansion
for person in people:
# 1. Expand Box
pb = person.box pb = person.box
bw = pb.x2 - pb.x1 bw = pb.x2 - pb.x1
bh = pb.y2 - pb.y1 bh = pb.y2 - pb.y1
# Expanded coordinates for Step 2
ex1 = max(0, int(pb.x1 - bw * margin)) ex1 = max(0, int(pb.x1 - bw * margin))
ey1 = max(0, int(pb.y1 - bh * margin)) ey1 = max(0, int(pb.y1 - bh * margin))
ex2 = min(w_img, int(pb.x2 + bw * margin)) ex2 = min(w_img, int(pb.x2 + bw * margin))
ey2 = min(h_img, int(pb.y2 + bh * margin)) ey2 = min(h_img, int(pb.y2 + bh * margin))
# Use expanded crop for cigarette detection # 2. Crop
person_crop = frame.data[ey1:ey2, ex1:ex2] person_crop = frame.data[ey1:ey2, ex1:ex2]
# If crop is too small, skip
if ( if (
person_crop.size == 0 person_crop.size == 0
or person_crop.shape[0] < 10 or person_crop.shape[0] < 10
@@ -100,10 +114,10 @@ class SmokingDetectionPipeline:
): ):
continue continue
# 3. Detect
cig_candidates = self.cigarette_model.predict(person_crop) cig_candidates = self.cigarette_model.predict(person_crop)
# Filter out extremely small candidates (noise) # 4. Filter Noise
# User requested check similar to person_crop check (< 10px)
cig_candidates = [ cig_candidates = [
c c
for c in cig_candidates for c in cig_candidates
@@ -111,25 +125,10 @@ class SmokingDetectionPipeline:
] ]
if cig_candidates: if cig_candidates:
# Store expansion offset for later coordinate translation
# We store (ex1, ey1) as metadata on the person detection or passed tuple?
# Easiest is to pass it in the tuple: (person, cigs, offset)
candidates.append((person, cig_candidates, (ex1, ey1))) candidates.append((person, cig_candidates, (ex1, ey1)))
# Check detections (translate to global coordinates) # 5. Global Coordinate Mapping (For Visualization)
for cig in cig_candidates: for cig in cig_candidates:
# Clone or modify the cig detection to be global
# Assuming cig.box is relevant to person_crop
# Global X = person_crop_origin_x + local_x
# Global Y = person_crop_origin_y + local_y
# Update in place might affect other logic if it assumes local,
# but logic below (Expansion) seems to rely on cig.box being used on raw_person_crop
# which implies local coordinates.
# So we should create a COPY for visualization.
from pipeline.types import BoundingBox, Detection
global_cig = Detection( global_cig = Detection(
box=BoundingBox( box=BoundingBox(
x1=ex1 + cig.box.x1, x1=ex1 + cig.box.x1,
@@ -144,97 +143,47 @@ class SmokingDetectionPipeline:
) )
frame.detections.append(global_cig) frame.detections.append(global_cig)
if not candidates: return candidates
return # EXIT
logger.debug(f"Frame {frame.frame_id}: Found {len(candidates)} candidates.") def _verify_candidates(
self, frame: Frame, candidates: List[Tuple]
# --- Step 3: Verification (Classifier) --- ) -> Optional[Tuple]:
# "Is that small thing actually a cigarette?" """Runs verification on candidate crops."""
confirmed_hits = [] confirmed_hits = []
for person, cigs, (ex1, ey1) in candidates: for person, cigs, (ex1, ey1) in candidates:
for cig in cigs: for cig in cigs:
# Crop just the object. # 1. Derive Crop Coordinates
# Note: box coordinates are relative to the person crop, or global?
# Ideally, detections should be unified.
# If cigarette_model returns boxes relative to person_crop, we need to adjust them.
# For simplicity in this mock, let's assume models return GLOBAL coords or handle their own relative logic wrapping.
# However, usually crop inference returns local coords.
# Let's assume for now the cig model knows how to return global.
# OR we pass the crop to verifier.
# IMPORTANT: If cigarette model ran on a crop, its output box is relative to that crop.
# We need to map it back or just use the crop directly?
# Actually, we likely want to crop the cigarette from the person crop.
# Simplified: Just rely on the verifier taking the small patch.
# To be robust, let's assume the Detector returns a Detection with a convenient 'crop' method or we handle coordinate translation.
# But for this MVP, let's assume we pass the crop derived from the box.
# FIX: If cig_candidates came from person_crop, their boxes are relative to (0,0) of person_crop.
# We should probably run verification on the crop defined by cig.box within person_crop.
# Let's grab the actual image patch for verification
# We can'teasily re-crop from global frame without translation.
# Strategy: cig detection on person_crop is easiest.
# Re-cutting the crop:
# We need the SAME crop used for detection, or at least the same coordinate system.
# Since we used the expanded crop (person_crop created via ex1, ey1),
# cig.box is relative to that.
# We can just re-extract the crop from the frame using ex1, ey1 if we didn't save it.
# Or just use the global coordinates we know now.
# Let's derive the object crop from the expanded person crop logic.
# --- Expansion Logic ---
# Expand the box to give context
# Here we are expanding the CIGARETTE box within the PERSON crop?
# The user asked to expand the hitbox (of the human) stage two too.
# We did that in Step 2.
# Now we need to prepare the crop for VERIFICATION (Step 3).
# We take the cig box (relative to expanded person crop) and add context?
cig_w = cig.box.x2 - cig.box.x1 cig_w = cig.box.x2 - cig.box.x1
cig_h = cig.box.y2 - cig.box.y1 cig_h = cig.box.y2 - cig.box.y1
pad_x = int(cig_w * 0.5) # Add 50% width padding pad_x = int(cig_w * 0.5)
pad_y = int(cig_h * 0.5) # Add 50% height padding pad_y = int(cig_h * 0.5)
# Coordinates relative to the expanded person crop global_cx1 = ex1 + max(0, cig.box.x1 - pad_x)
cx1 = max(0, cig.box.x1 - pad_x) global_cy1 = ey1 + max(0, cig.box.y1 - pad_y)
cy1 = max(0, cig.box.y1 - pad_y)
# We don't know the exact W/H of the expanded crop easily here without recomputing or checking boundaries
# But we can map to Global and crop from frame directly to be safe.
global_cx1 = ex1 + cx1
global_cy1 = ey1 + cy1
global_cx2 = ex1 + cig.box.x2 + pad_x global_cx2 = ex1 + cig.box.x2 + pad_x
global_cy2 = ey1 + cig.box.y2 + pad_y global_cy2 = ey1 + cig.box.y2 + pad_y
# Check bounds
h_img, w_img = frame.data.shape[:2] h_img, w_img = frame.data.shape[:2]
final_x1 = max(0, global_cx1) final_x1 = max(0, global_cx1)
final_y1 = max(0, global_cy1) final_y1 = max(0, global_cy1)
final_x2 = min(w_img, global_cx2) final_x2 = min(w_img, global_cx2)
final_y2 = min(h_img, global_cy2) final_y2 = min(h_img, global_cy2)
# 2. Crop
obj_crop = frame.data[final_y1:final_y2, final_x1:final_x2] obj_crop = frame.data[final_y1:final_y2, final_x1:final_x2]
if obj_crop.size == 0: if obj_crop.size == 0:
continue continue
# 3. Verify
score = self.verifier_model.verify(obj_crop) score = self.verifier_model.verify(obj_crop)
if score > 0.8: # High confidence threshold if score > 0.8: # High confidence
confirmed_hits.append((person, cig, score)) confirmed_hits.append((person, cig, score))
# Add verified detection to frame for visualization
from pipeline.types import BoundingBox, Detection
verified_det = Detection( verified_det = Detection(
box=BoundingBox( box=BoundingBox(
x1=ex1 + cig.box.x1, x1=ex1 + cig.box.x1,
@@ -249,23 +198,6 @@ class SmokingDetectionPipeline:
) )
frame.detections.append(verified_det) frame.detections.append(verified_det)
elif score > 0.4 and self.vlm_model:
# Ambiguous case: Send to VLM?
vlm_score = self.vlm_model.verify(
obj_crop
) # Or pass seq of frames?
if vlm_score > 0.8:
confirmed_hits.append((person, cig, vlm_score))
# --- Step 4: Action ---
if confirmed_hits: if confirmed_hits:
best_hit = max(confirmed_hits, key=lambda x: x[2]) return max(confirmed_hits, key=lambda x: x[2])
ticket = Ticket( return None
frame_id=frame.frame_id,
confidence=best_hit[2],
evidence=[frame.data], # Store frame reference
stage_confirmed="VLM"
if self.vlm_model
and best_hit[2] == 0.1 # Logic here is a bit shaky from mock
else "Verifier",
)
self.store.store(ticket)
+13 -3
View File
@@ -1,6 +1,7 @@
import logging import logging
from typing import Any, List from typing import Any, List
import torch
from ultralytics.models import YOLO from ultralytics.models import YOLO
from pipeline.protocols import Model, Verifier from pipeline.protocols import Model, Verifier
@@ -8,6 +9,13 @@ from pipeline.types import BoundingBox, Detection
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
# Auto-detect device
DEVICE = 0 if torch.cuda.is_available() else "cpu"
if DEVICE == 0:
logger.info(f"GPU detected! Using CUDA device: {torch.cuda.get_device_name(0)}")
else:
logger.info("No GPU detected. Running on CPU.")
class YoloPersonDetector(Model): class YoloPersonDetector(Model):
def __init__(self, model_path: str = "yolo11n.pt"): # Using small model for speed def __init__(self, model_path: str = "yolo11n.pt"): # Using small model for speed
@@ -16,7 +24,9 @@ class YoloPersonDetector(Model):
def predict(self, input_data: Any) -> List[Detection]: def predict(self, input_data: Any) -> List[Detection]:
# input_data: numpy array (H, W, C) # input_data: numpy array (H, W, C)
results = self.model(input_data, classes=[0], verbose=False) # 0 is person results = self.model(
input_data, classes=[0], verbose=False, device=DEVICE
) # 0 is person
detections = [] detections = []
for r in results: for r in results:
@@ -42,7 +52,7 @@ class YoloCigaretteDetector(Model):
def predict(self, input_data: Any) -> List[Detection]: def predict(self, input_data: Any) -> List[Detection]:
# This model should be trained on cigarette class # This model should be trained on cigarette class
# Assuming class 0 is cigarette for this custom model # Assuming class 0 is cigarette for this custom model
results = self.model(input_data, verbose=False) results = self.model(input_data, verbose=False, device=DEVICE)
detections = [] detections = []
for r in results: for r in results:
@@ -72,7 +82,7 @@ class YoloClassifier(Verifier):
if input_data.size == 0: if input_data.size == 0:
return 0.0 return 0.0
results = self.model(input_data, verbose=False) results = self.model(input_data, verbose=False, device=DEVICE)
# Check if we got any results # Check if we got any results
if not results: if not results:
+7 -3
View File
@@ -6,7 +6,7 @@ from typing import List, Optional
import cv2 import cv2
import numpy as np import numpy as np
from pipeline.types import Detection, Frame, Ticket from pipeline.types import Detection, Frame
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@@ -19,10 +19,14 @@ class FileAlertStore:
def __init__(self, path: str): def __init__(self, path: str):
self.path = path self.path = path
self.file = open(path, "a") # Append mode self.file = open(path, "a", encoding="utf-8") # Append mode
logger.info(f"Initialized FileAlertStore writing to {path}") logger.info(f"Initialized FileAlertStore writing to {path}")
def store(self, ticket: Ticket): def handle(self, frame: Frame):
if not frame.ticket:
return
ticket = frame.ticket
record = { record = {
"type": "alert", "type": "alert",
"frame_id": ticket.frame_id, "frame_id": ticket.frame_id,
+4 -4
View File
@@ -1,6 +1,6 @@
from typing import Any, Iterator, List, Protocol from typing import Any, Iterator, List, Protocol
from pipeline.types import Detection, Frame, Ticket from pipeline.types import Detection, Frame
class Model(Protocol): class Model(Protocol):
@@ -21,7 +21,7 @@ class StreamSource(Protocol):
... ...
class AlertStore(Protocol): class Sink(Protocol):
def store(self, ticket: Ticket): def handle(self, frame: Frame):
"""Persist the ticket.""" """Process or persist a frame (and its ticket/detections)."""
... ...
+12 -11
View File
@@ -1,5 +1,5 @@
from dataclasses import dataclass, field from dataclasses import dataclass, field
from typing import Any, List from typing import Any, List, Optional
import numpy as np import numpy as np
@@ -39,16 +39,6 @@ class Detection:
metadata: dict = field(default_factory=dict) metadata: dict = field(default_factory=dict)
@dataclass
class Frame:
"""Represents a single frame in the video stream."""
timestamp: float
data: np.ndarray # numpy array (OpenCV image)
frame_id: int
detections: List[Detection] = field(default_factory=list)
@dataclass @dataclass
class Ticket: class Ticket:
"""Represents a potential alert event.""" """Represents a potential alert event."""
@@ -58,3 +48,14 @@ class Ticket:
evidence: List[Any] # List of images or crops evidence: List[Any] # List of images or crops
stage_confirmed: str stage_confirmed: str
metadata: dict = field(default_factory=dict) metadata: dict = field(default_factory=dict)
@dataclass
class Frame:
"""Represents a single frame in the video stream."""
timestamp: float
data: np.ndarray # numpy array (OpenCV image)
frame_id: int
detections: List[Detection] = field(default_factory=list)
ticket: Optional[Ticket] = None
+14
View File
@@ -7,5 +7,19 @@ requires-python = ">=3.14"
dependencies = [ dependencies = [
"numpy>=2.4.0", "numpy>=2.4.0",
"opencv-python>=4.11.0.86", "opencv-python>=4.11.0.86",
"torch>=2.9.1",
"ultralytics>=8.3.248", "ultralytics>=8.3.248",
] ]
[[tool.uv.index]]
name = "pytorch-cu130"
url = "https://download.pytorch.org/whl/cu130"
explicit = true
[tool.uv.sources]
torch = [
{ index = "pytorch-cu130", marker = "sys_platform == 'linux' or sys_platform == 'win32'" },
]
torchvision = [
{ index = "pytorch-cu130", marker = "sys_platform == 'linux' or sys_platform == 'win32'" },
]
Generated
+134 -84
View File
@@ -5,7 +5,8 @@ resolution-markers = [
"sys_platform == 'win32'", "sys_platform == 'win32'",
"sys_platform == 'darwin'", "sys_platform == 'darwin'",
"platform_machine == 'aarch64' and sys_platform == 'linux'", "platform_machine == 'aarch64' and sys_platform == 'linux'",
"(platform_machine != 'aarch64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32')", "platform_machine != 'aarch64' and sys_platform == 'linux'",
"sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32'",
] ]
[[package]] [[package]]
@@ -134,6 +135,8 @@ source = { virtual = "." }
dependencies = [ dependencies = [
{ name = "numpy" }, { name = "numpy" },
{ name = "opencv-python" }, { name = "opencv-python" },
{ name = "torch", version = "2.9.1", source = { registry = "https://pypi.org/simple" }, marker = "sys_platform != 'linux' and sys_platform != 'win32'" },
{ name = "torch", version = "2.9.1+cu130", source = { registry = "https://download.pytorch.org/whl/cu130" }, marker = "sys_platform == 'linux' or sys_platform == 'win32'" },
{ name = "ultralytics" }, { name = "ultralytics" },
] ]
@@ -141,6 +144,8 @@ dependencies = [
requires-dist = [ requires-dist = [
{ name = "numpy", specifier = ">=2.4.0" }, { name = "numpy", specifier = ">=2.4.0" },
{ name = "opencv-python", specifier = ">=4.11.0.86" }, { name = "opencv-python", specifier = ">=4.11.0.86" },
{ name = "torch", marker = "sys_platform != 'linux' and sys_platform != 'win32'", specifier = ">=2.9.1" },
{ name = "torch", marker = "sys_platform == 'linux' or sys_platform == 'win32'", specifier = ">=2.9.1", index = "https://download.pytorch.org/whl/cu130" },
{ name = "ultralytics", specifier = ">=8.3.248" }, { name = "ultralytics", specifier = ">=8.3.248" },
] ]
@@ -310,137 +315,152 @@ wheels = [
] ]
[[package]] [[package]]
name = "nvidia-cublas-cu12" name = "nvidia-cublas"
version = "12.8.4.1" version = "13.0.0.19"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/dc/61/e24b560ab2e2eaeb3c839129175fb330dfcfc29e5203196e5541a4c44682/nvidia_cublas_cu12-12.8.4.1-py3-none-manylinux_2_27_x86_64.whl", hash = "sha256:8ac4e771d5a348c551b2a426eda6193c19aa630236b418086020df5ba9667142", size = 594346921, upload-time = "2025-03-07T01:44:31.254Z" }, { url = "https://files.pythonhosted.org/packages/02/99/8447b9ee9f070522ee66604ee819d632ab4568c68b3134cebd3837a015cd/nvidia_cublas-13.0.0.19-py3-none-manylinux_2_27_aarch64.whl", hash = "sha256:381b1a0ca636fdcb6920a871e8fc89dbfd1f6157f421ed0a6f2673e14cffd3bd", size = 539001158, upload-time = "2025-08-04T10:19:50.761Z" },
{ url = "https://files.pythonhosted.org/packages/5a/99/210e113dde53955e97042bd76dc4ad927eca04c5b4645ec157cc59f4f3ae/nvidia_cublas-13.0.0.19-py3-none-manylinux_2_27_x86_64.whl", hash = "sha256:f6723af2e8e2600a11dc384037d90d9bf93070e346c24ef2e8f9001658c99896", size = 419392356, upload-time = "2025-08-04T10:20:19.449Z" },
] ]
[[package]] [[package]]
name = "nvidia-cuda-cupti-cu12" name = "nvidia-cuda-cupti"
version = "12.8.90" version = "13.0.48"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/f8/02/2adcaa145158bf1a8295d83591d22e4103dbfd821bcaf6f3f53151ca4ffa/nvidia_cuda_cupti_cu12-12.8.90-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ea0cb07ebda26bb9b29ba82cda34849e73c166c18162d3913575b0c9db9a6182", size = 10248621, upload-time = "2025-03-07T01:40:21.213Z" }, { url = "https://files.pythonhosted.org/packages/72/63/e9c12c3ae07c1f3a0821536bc188d7bf76e1b633b3bcd2bd393b00bb3426/nvidia_cuda_cupti-13.0.48-py3-none-manylinux_2_25_aarch64.whl", hash = "sha256:67c22627ef436afcf080b48e4ad17b3f83d9e7c0d990ad0c6c0627b01fb92ccc", size = 10171189, upload-time = "2025-08-04T10:16:24.39Z" },
{ url = "https://files.pythonhosted.org/packages/ba/28/e37d62ff27b4462953fdd5713d8a78760578dfa12685c30b71b55fab57b1/nvidia_cuda_cupti-13.0.48-py3-none-manylinux_2_25_x86_64.whl", hash = "sha256:417699e216b23d81bc0bbcb7032352f81b9c5372ef73c097a01abb83125a3d09", size = 10718148, upload-time = "2025-08-04T10:16:33.605Z" },
] ]
[[package]] [[package]]
name = "nvidia-cuda-nvrtc-cu12" name = "nvidia-cuda-nvrtc"
version = "12.8.93" version = "13.0.48"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/05/6b/32f747947df2da6994e999492ab306a903659555dddc0fbdeb9d71f75e52/nvidia_cuda_nvrtc_cu12-12.8.93-py3-none-manylinux2010_x86_64.manylinux_2_12_x86_64.whl", hash = "sha256:a7756528852ef889772a84c6cd89d41dfa74667e24cca16bb31f8f061e3e9994", size = 88040029, upload-time = "2025-03-07T01:42:13.562Z" }, { url = "https://files.pythonhosted.org/packages/be/5b/f7636b3d66caefade6a0a0dc5b705c259a2062c20ad18b432b3129d348e0/nvidia_cuda_nvrtc-13.0.48-py3-none-manylinux2010_x86_64.manylinux_2_12_x86_64.whl", hash = "sha256:87e13d186905a35e7c04ad553a2abded0fba22f93b43d02e5da6f6cf73fb4d0a", size = 90214268, upload-time = "2025-08-04T10:18:09.305Z" },
{ url = "https://files.pythonhosted.org/packages/c0/bd/eb18593b43dae42312612ffbac24b8e68149e590102c3b6cc2e3d3792069/nvidia_cuda_nvrtc-13.0.48-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:6ccf1ef1b90a0763ac7536f3c17046659d89869d76b98ac358efc2e09b348365", size = 43013627, upload-time = "2025-08-04T10:17:57.338Z" },
] ]
[[package]] [[package]]
name = "nvidia-cuda-runtime-cu12" name = "nvidia-cuda-runtime"
version = "12.8.90" version = "13.0.48"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/0d/9b/a997b638fcd068ad6e4d53b8551a7d30fe8b404d6f1804abf1df69838932/nvidia_cuda_runtime_cu12-12.8.90-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:adade8dcbd0edf427b7204d480d6066d33902cab2a4707dcfc48a2d0fd44ab90", size = 954765, upload-time = "2025-03-07T01:40:01.615Z" }, { url = "https://files.pythonhosted.org/packages/55/3b/c5e5d8aafd355e2ff9922472ba71251331af6cc866e5b04a3b1dc8f58977/nvidia_cuda_runtime-13.0.48-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:b807c0bb925a307bfa667a24f24d253aef8eda3ac4be66b333f2c9d357557008", size = 2260687, upload-time = "2025-08-04T10:15:41.292Z" },
{ url = "https://files.pythonhosted.org/packages/cc/78/edb119083ca2ff0f09ab0cd597e97775ac3f575b8aa0caf10d68ed49e032/nvidia_cuda_runtime-13.0.48-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:5b54d12087a1abff81a4cbfa6556876e3afea1fc60da2e0816da374619810c89", size = 2242632, upload-time = "2025-08-04T10:15:49.339Z" },
] ]
[[package]] [[package]]
name = "nvidia-cudnn-cu12" name = "nvidia-cudnn-cu13"
version = "9.10.2.21" version = "9.13.0.50"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
dependencies = [ dependencies = [
{ name = "nvidia-cublas-cu12", marker = "(platform_machine != 'aarch64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32')" }, { name = "nvidia-cublas", marker = "sys_platform == 'linux'" },
] ]
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/ba/51/e123d997aa098c61d029f76663dedbfb9bc8dcf8c60cbd6adbe42f76d049/nvidia_cudnn_cu12-9.10.2.21-py3-none-manylinux_2_27_x86_64.whl", hash = "sha256:949452be657fa16687d0930933f032835951ef0892b37d2d53824d1a84dc97a8", size = 706758467, upload-time = "2025-06-06T21:54:08.597Z" }, { url = "https://files.pythonhosted.org/packages/8a/9c/9e99c00dc23db324244ec257d1e84d79539202ee2f185dee2c1fa97c9549/nvidia_cudnn_cu13-9.13.0.50-py3-none-manylinux_2_27_aarch64.whl", hash = "sha256:33f0aa0b64230101b348648fd0693342188071d3f8a137c0cf50051c24b3584b", size = 412337597, upload-time = "2025-09-04T20:22:31.535Z" },
{ url = "https://files.pythonhosted.org/packages/cf/68/2712854561170b2a81bea7b6b35cc1ae264d9794c0c218986e5c685d45f7/nvidia_cudnn_cu13-9.13.0.50-py3-none-manylinux_2_27_x86_64.whl", hash = "sha256:2150b4850725d30653ec3e365f0732e3e2e3eb8633cf3bd2d3117628dea8b4f9", size = 348571624, upload-time = "2025-09-04T20:23:26.544Z" },
] ]
[[package]] [[package]]
name = "nvidia-cufft-cu12" name = "nvidia-cufft"
version = "11.3.3.83" version = "12.0.0.15"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
dependencies = [ dependencies = [
{ name = "nvidia-nvjitlink-cu12", marker = "(platform_machine != 'aarch64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32')" }, { name = "nvidia-nvjitlink", marker = "sys_platform == 'linux'" },
] ]
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/1f/13/ee4e00f30e676b66ae65b4f08cb5bcbb8392c03f54f2d5413ea99a5d1c80/nvidia_cufft_cu12-11.3.3.83-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:4d2dd21ec0b88cf61b62e6b43564355e5222e4a3fb394cac0db101f2dd0d4f74", size = 193118695, upload-time = "2025-03-07T01:45:27.821Z" }, { url = "https://files.pythonhosted.org/packages/9b/e9/4e49b1baf6899e42eeec324a49d7aa2219fec42076327c4e468000dd375a/nvidia_cufft-12.0.0.15-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:1885731254835797572ff075f3daf43a2a0a2801210dea26971940dae7e1a367", size = 214053580, upload-time = "2025-08-04T10:20:45.781Z" },
{ url = "https://files.pythonhosted.org/packages/9b/9f/e298b66e584ad25bd78ad4a45b061fe7bb57a1ec011128089404ce3fcc7d/nvidia_cufft-12.0.0.15-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:9f160b1f018e80bcb0d7c0fa50564b042fa26b13edc1b1ff14b6375a9edd2812", size = 214085489, upload-time = "2025-08-04T10:21:02.975Z" },
] ]
[[package]] [[package]]
name = "nvidia-cufile-cu12" name = "nvidia-cufile"
version = "1.13.1.3" version = "1.15.0.42"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/bb/fe/1bcba1dfbfb8d01be8d93f07bfc502c93fa23afa6fd5ab3fc7c1df71038a/nvidia_cufile_cu12-1.13.1.3-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1d069003be650e131b21c932ec3d8969c1715379251f8d23a1860554b1cb24fc", size = 1197834, upload-time = "2025-03-07T01:45:50.723Z" }, { url = "https://files.pythonhosted.org/packages/ad/0a/4adf0c9bb1241cd1314fc923fde00f3749c7fc785b1e3b3f4a104cd3090c/nvidia_cufile-1.15.0.42-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c8f9813eff24d61586699c615e39817e2b4e4f642cace32733c2ab6f663a7eab", size = 1223104, upload-time = "2025-08-04T10:21:31.131Z" },
{ url = "https://files.pythonhosted.org/packages/bf/a5/636baa43399ea10d22b63e7454f22a92ace4a7eaa3c45b94607250857e2d/nvidia_cufile-1.15.0.42-py3-none-manylinux_2_27_aarch64.whl", hash = "sha256:bced4036b5a8dbf57e4d78cd4fafefec58ad754b784a9eaa272b011896754c62", size = 1136527, upload-time = "2025-08-04T10:21:22.441Z" },
] ]
[[package]] [[package]]
name = "nvidia-curand-cu12" name = "nvidia-curand"
version = "10.3.9.90" version = "10.4.0.35"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/fb/aa/6584b56dc84ebe9cf93226a5cde4d99080c8e90ab40f0c27bda7a0f29aa1/nvidia_curand_cu12-10.3.9.90-py3-none-manylinux_2_27_x86_64.whl", hash = "sha256:b32331d4f4df5d6eefa0554c565b626c7216f87a06a4f56fab27c3b68a830ec9", size = 63619976, upload-time = "2025-03-07T01:46:23.323Z" }, { url = "https://files.pythonhosted.org/packages/1e/72/7c2ae24fb6b63a32e6ae5d241cc65263ea18d08802aaae087d9f013335a2/nvidia_curand-10.4.0.35-py3-none-manylinux_2_27_aarch64.whl", hash = "sha256:133df5a7509c3e292aaa2b477afd0194f06ce4ea24d714d616ff36439cee349a", size = 61962106, upload-time = "2025-08-04T10:21:41.128Z" },
{ url = "https://files.pythonhosted.org/packages/a5/9f/be0a41ca4a4917abf5cb9ae0daff1a6060cc5de950aec0396de9f3b52bc5/nvidia_curand-10.4.0.35-py3-none-manylinux_2_27_x86_64.whl", hash = "sha256:1aee33a5da6e1db083fe2b90082def8915f30f3248d5896bcec36a579d941bfc", size = 59544258, upload-time = "2025-08-04T10:22:03.992Z" },
] ]
[[package]] [[package]]
name = "nvidia-cusolver-cu12" name = "nvidia-cusolver"
version = "11.7.3.90" version = "12.0.3.29"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
dependencies = [ dependencies = [
{ name = "nvidia-cublas-cu12", marker = "(platform_machine != 'aarch64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32')" }, { name = "nvidia-cublas", marker = "sys_platform == 'linux'" },
{ name = "nvidia-cusparse-cu12", marker = "(platform_machine != 'aarch64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32')" }, { name = "nvidia-cusparse", marker = "sys_platform == 'linux'" },
{ name = "nvidia-nvjitlink-cu12", marker = "(platform_machine != 'aarch64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32')" }, { name = "nvidia-nvjitlink", marker = "sys_platform == 'linux'" },
] ]
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/85/48/9a13d2975803e8cf2777d5ed57b87a0b6ca2cc795f9a4f59796a910bfb80/nvidia_cusolver_cu12-11.7.3.90-py3-none-manylinux_2_27_x86_64.whl", hash = "sha256:4376c11ad263152bd50ea295c05370360776f8c3427b30991df774f9fb26c450", size = 267506905, upload-time = "2025-03-07T01:47:16.273Z" }, { url = "https://files.pythonhosted.org/packages/a7/bb/2e60de9bb1f0c3395eabd91ccad00f4ba3ef736dc9190a158a9d268419f5/nvidia_cusolver-12.0.3.29-py3-none-manylinux_2_27_aarch64.whl", hash = "sha256:3bb6e65ce0beaeafdd069b320246e8f17c1cd30ddb27a0539143a3706733a4d8", size = 193104180, upload-time = "2025-08-04T10:22:19.821Z" },
{ url = "https://files.pythonhosted.org/packages/a5/87/e3c9ee227b750e5b61572e7509f586cc8d494a4f7874b5163e734ed852c2/nvidia_cusolver-12.0.3.29-py3-none-manylinux_2_27_x86_64.whl", hash = "sha256:6f54c2eed5edab54c224dd1852dde80ba76b2b78e6d3ce7344fef5dfc66d16ab", size = 193474165, upload-time = "2025-08-04T10:22:47.976Z" },
] ]
[[package]] [[package]]
name = "nvidia-cusparse-cu12" name = "nvidia-cusparse"
version = "12.5.8.93" version = "12.6.2.49"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
dependencies = [ dependencies = [
{ name = "nvidia-nvjitlink-cu12", marker = "(platform_machine != 'aarch64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32')" }, { name = "nvidia-nvjitlink", marker = "sys_platform == 'linux'" },
] ]
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/c2/f5/e1854cb2f2bcd4280c44736c93550cc300ff4b8c95ebe370d0aa7d2b473d/nvidia_cusparse_cu12-12.5.8.93-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1ec05d76bbbd8b61b06a80e1eaf8cf4959c3d4ce8e711b65ebd0443bb0ebb13b", size = 288216466, upload-time = "2025-03-07T01:48:13.779Z" }, { url = "https://files.pythonhosted.org/packages/fc/30/f32023427f2ef4ec27e8293dfddb5068de566912cd0a45eccfd400017a62/nvidia_cusparse-12.6.2.49-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:5d3269c19283a0057fb5ebfb003ae2a10c97a28a6958f4238354826b055827c7", size = 155888587, upload-time = "2025-08-04T10:23:04.091Z" },
{ url = "https://files.pythonhosted.org/packages/ba/e8/b3f7a87cc719dca926c7baee92f2544de8909573a4126c85a9f1625431e8/nvidia_cusparse-12.6.2.49-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:efcf0b01e3a0827c144feff5391456b8a06e9ce63dcd51c0943e32e605251952", size = 140247612, upload-time = "2025-08-04T10:23:29.844Z" },
] ]
[[package]] [[package]]
name = "nvidia-cusparselt-cu12" name = "nvidia-cusparselt-cu13"
version = "0.7.1" version = "0.8.0"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/56/79/12978b96bd44274fe38b5dde5cfb660b1d114f70a65ef962bcbbed99b549/nvidia_cusparselt_cu12-0.7.1-py3-none-manylinux2014_x86_64.whl", hash = "sha256:f1bb701d6b930d5a7cea44c19ceb973311500847f81b634d802b7b539dc55623", size = 287193691, upload-time = "2025-02-26T00:15:44.104Z" }, { url = "https://files.pythonhosted.org/packages/46/10/8dcd1175260706a2fc92a16a52e306b71d4c1ea0b0cc4a9484183399818a/nvidia_cusparselt_cu13-0.8.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:400c6ed1cf6780fc6efedd64ec9f1345871767e6a1a0a552a1ea0578117ea77c", size = 220791277, upload-time = "2025-08-13T19:22:40.982Z" },
{ url = "https://files.pythonhosted.org/packages/fd/53/43b0d71f4e702fa9733f8b4571fdca50a8813f1e450b656c239beff12315/nvidia_cusparselt_cu13-0.8.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:25e30a8a7323935d4ad0340b95a0b69926eee755767e8e0b1cf8dd85b197d3fd", size = 169884119, upload-time = "2025-08-13T19:23:41.967Z" },
] ]
[[package]] [[package]]
name = "nvidia-nccl-cu12" name = "nvidia-nccl-cu13"
version = "2.27.5" version = "2.27.7"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/6e/89/f7a07dc961b60645dbbf42e80f2bc85ade7feb9a491b11a1e973aa00071f/nvidia_nccl_cu12-2.27.5-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ad730cf15cb5d25fe849c6e6ca9eb5b76db16a80f13f425ac68d8e2e55624457", size = 322348229, upload-time = "2025-06-26T04:11:28.385Z" }, { url = "https://files.pythonhosted.org/packages/49/61/2c7762da6febee96341ea17d1f7309ac7559ac3cab00f3f7e1e7bd0e5d00/nvidia_nccl_cu13-2.27.7-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:5e3cc863e52bf9dd1e3ab1941bddb414098f489ae7342f6b3a274602303da123", size = 194014855, upload-time = "2025-09-23T16:30:27.56Z" },
{ url = "https://files.pythonhosted.org/packages/f1/3a/dabb10684e60edfaf1a1c9984d12a668bc1091582099d4e03ac5b9983b51/nvidia_nccl_cu13-2.27.7-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:b28a524abd8389b76a4a3f133c76a7aaa7005e47fcaa9d9603b90103927a3f93", size = 193901479, upload-time = "2025-09-23T16:30:41.165Z" },
] ]
[[package]] [[package]]
name = "nvidia-nvjitlink-cu12" name = "nvidia-nvjitlink"
version = "12.8.93" version = "13.0.39"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/f6/74/86a07f1d0f42998ca31312f998bd3b9a7eff7f52378f4f270c8679c77fb9/nvidia_nvjitlink_cu12-12.8.93-py3-none-manylinux2010_x86_64.manylinux_2_12_x86_64.whl", hash = "sha256:81ff63371a7ebd6e6451970684f916be2eab07321b73c9d244dc2b4da7f73b88", size = 39254836, upload-time = "2025-03-07T01:49:55.661Z" }, { url = "https://files.pythonhosted.org/packages/95/39/726edebeb76f3efc25c79f885429fa1227c9d200e20ea219bf724b382e19/nvidia_nvjitlink-13.0.39-py3-none-manylinux2010_x86_64.manylinux_2_12_x86_64.whl", hash = "sha256:bc3179be558329ef9687884c6faa27cdc0659bdbc642432ec8cc6cc00d182627", size = 40709605, upload-time = "2025-08-04T10:25:04.129Z" },
{ url = "https://files.pythonhosted.org/packages/bc/7a/0fb4c4413b3b14519f8934edd4dcd9f411c4e14e2a2c0ae58709e4dda255/nvidia_nvjitlink-13.0.39-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ce0d63fa5ebedf542056e7491c49feed2297c900980aa6269b6a55f478056ad7", size = 38767126, upload-time = "2025-08-04T10:24:53.05Z" },
] ]
[[package]] [[package]]
name = "nvidia-nvshmem-cu12" name = "nvidia-nvshmem-cu13"
version = "3.3.20" version = "3.3.24"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/3b/6c/99acb2f9eb85c29fc6f3a7ac4dccfd992e22666dd08a642b303311326a97/nvidia_nvshmem_cu12-3.3.20-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d00f26d3f9b2e3c3065be895e3059d6479ea5c638a3f38c9fec49b1b9dd7c1e5", size = 124657145, upload-time = "2025-08-04T20:25:19.995Z" }, { url = "https://files.pythonhosted.org/packages/b1/7e/b8797780e442eabd9046cd6eb54100b8d0cb047ebc2f70931710cb03bcfe/nvidia_nvshmem_cu13-3.3.24-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:28ae82a4d14b322b93409535de62df6b7b83f4f7672ca97fc89107c2d40ce2c2", size = 60168129, upload-time = "2025-08-22T19:56:28.818Z" },
{ url = "https://files.pythonhosted.org/packages/6f/e9/8530afb8ed38d16bbc89cec80a4dd6a52dbf59bc93e546c3658cfa8b1f9b/nvidia_nvshmem_cu13-3.3.24-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c14d09571697d2e57cb079c8daec88ab1c68cb3586532bfbd4886125a08339b7", size = 60390470, upload-time = "2025-08-22T19:56:49.848Z" },
] ]
[[package]] [[package]]
name = "nvidia-nvtx-cu12" name = "nvidia-nvtx"
version = "12.8.90" version = "13.0.39"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/a2/eb/86626c1bbc2edb86323022371c39aa48df6fd8b0a1647bc274577f72e90b/nvidia_nvtx_cu12-12.8.90-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:5b17e2001cc0d751a5bc2c6ec6d26ad95913324a4adb86788c944f8ce9ba441f", size = 89954, upload-time = "2025-03-07T01:42:44.131Z" }, { url = "https://files.pythonhosted.org/packages/38/37/0d103c84e7884382a79a569b720965141f83dd1c5df9e3e00cbc02d7099c/nvidia_nvtx-13.0.39-py3-none-manylinux1_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:cc113127785c96db8a0fe715df92db9788777b4b3d1bd713d42f75969201b5ce", size = 147197, upload-time = "2025-08-04T10:18:39.829Z" },
{ url = "https://files.pythonhosted.org/packages/86/91/8b486ba85f71a2859dd705a4ec6aab38c37a389b8b7f94343db027732999/nvidia_nvtx-13.0.39-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:cddd2e08b35144f1000631c3880c9ebbcb8a2863d762e76f92d47d30ecaf87cc", size = 148037, upload-time = "2025-08-04T10:18:31.763Z" },
] ]
[[package]] [[package]]
@@ -677,40 +697,65 @@ wheels = [
name = "torch" name = "torch"
version = "2.9.1" version = "2.9.1"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
resolution-markers = [
"sys_platform == 'darwin'",
"sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32'",
]
dependencies = [ dependencies = [
{ name = "filelock" }, { name = "filelock", marker = "sys_platform != 'linux' and sys_platform != 'win32'" },
{ name = "fsspec" }, { name = "fsspec", marker = "sys_platform != 'linux' and sys_platform != 'win32'" },
{ name = "jinja2" }, { name = "jinja2", marker = "sys_platform != 'linux' and sys_platform != 'win32'" },
{ name = "networkx" }, { name = "networkx", marker = "sys_platform != 'linux' and sys_platform != 'win32'" },
{ name = "nvidia-cublas-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, { name = "setuptools", marker = "sys_platform != 'linux' and sys_platform != 'win32'" },
{ name = "nvidia-cuda-cupti-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, { name = "sympy", marker = "sys_platform != 'linux' and sys_platform != 'win32'" },
{ name = "nvidia-cuda-nvrtc-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, { name = "typing-extensions", marker = "sys_platform != 'linux' and sys_platform != 'win32'" },
{ name = "nvidia-cuda-runtime-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" },
{ name = "nvidia-cudnn-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" },
{ name = "nvidia-cufft-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" },
{ name = "nvidia-cufile-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" },
{ name = "nvidia-curand-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" },
{ name = "nvidia-cusolver-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" },
{ name = "nvidia-cusparse-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" },
{ name = "nvidia-cusparselt-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" },
{ name = "nvidia-nccl-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" },
{ name = "nvidia-nvjitlink-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" },
{ name = "nvidia-nvshmem-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" },
{ name = "nvidia-nvtx-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" },
{ name = "setuptools" },
{ name = "sympy" },
{ name = "triton", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" },
{ name = "typing-extensions" },
] ]
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/48/50/c4b5112546d0d13cc9eaa1c732b823d676a9f49ae8b6f97772f795874a03/torch-2.9.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:1edee27a7c9897f4e0b7c14cfc2f3008c571921134522d5b9b5ec4ebbc69041a", size = 74433245, upload-time = "2025-11-12T15:22:39.027Z" }, { url = "https://files.pythonhosted.org/packages/48/50/c4b5112546d0d13cc9eaa1c732b823d676a9f49ae8b6f97772f795874a03/torch-2.9.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:1edee27a7c9897f4e0b7c14cfc2f3008c571921134522d5b9b5ec4ebbc69041a", size = 74433245, upload-time = "2025-11-12T15:22:39.027Z" },
{ url = "https://files.pythonhosted.org/packages/81/c9/2628f408f0518b3bae49c95f5af3728b6ab498c8624ab1e03a43dd53d650/torch-2.9.1-cp314-cp314-manylinux_2_28_aarch64.whl", hash = "sha256:19d144d6b3e29921f1fc70503e9f2fc572cde6a5115c0c0de2f7ca8b1483e8b6", size = 104134804, upload-time = "2025-11-12T15:22:35.222Z" },
{ url = "https://files.pythonhosted.org/packages/28/fc/5bc91d6d831ae41bf6e9e6da6468f25330522e92347c9156eb3f1cb95956/torch-2.9.1-cp314-cp314-manylinux_2_28_x86_64.whl", hash = "sha256:c432d04376f6d9767a9852ea0def7b47a7bbc8e7af3b16ac9cf9ce02b12851c9", size = 899747132, upload-time = "2025-11-12T15:23:36.068Z" },
{ url = "https://files.pythonhosted.org/packages/63/5d/e8d4e009e52b6b2cf1684bde2a6be157b96fb873732542fb2a9a99e85a83/torch-2.9.1-cp314-cp314-win_amd64.whl", hash = "sha256:d187566a2cdc726fc80138c3cdb260970fab1c27e99f85452721f7759bbd554d", size = 110934845, upload-time = "2025-11-12T15:22:48.367Z" },
{ url = "https://files.pythonhosted.org/packages/bd/b2/2d15a52516b2ea3f414643b8de68fa4cb220d3877ac8b1028c83dc8ca1c4/torch-2.9.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:cb10896a1f7fedaddbccc2017ce6ca9ecaaf990f0973bdfcf405439750118d2c", size = 74823558, upload-time = "2025-11-12T15:22:43.392Z" }, { url = "https://files.pythonhosted.org/packages/bd/b2/2d15a52516b2ea3f414643b8de68fa4cb220d3877ac8b1028c83dc8ca1c4/torch-2.9.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:cb10896a1f7fedaddbccc2017ce6ca9ecaaf990f0973bdfcf405439750118d2c", size = 74823558, upload-time = "2025-11-12T15:22:43.392Z" },
{ url = "https://files.pythonhosted.org/packages/86/5c/5b2e5d84f5b9850cd1e71af07524d8cbb74cba19379800f1f9f7c997fc70/torch-2.9.1-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:0a2bd769944991c74acf0c4ef23603b9c777fdf7637f115605a4b2d8023110c7", size = 104145788, upload-time = "2025-11-12T15:23:52.109Z" }, ]
{ url = "https://files.pythonhosted.org/packages/a9/8c/3da60787bcf70add986c4ad485993026ac0ca74f2fc21410bc4eb1bb7695/torch-2.9.1-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:07c8a9660bc9414c39cac530ac83b1fb1b679d7155824144a40a54f4a47bfa73", size = 899735500, upload-time = "2025-11-12T15:24:08.788Z" },
{ url = "https://files.pythonhosted.org/packages/db/2b/f7818f6ec88758dfd21da46b6cd46af9d1b3433e53ddbb19ad1e0da17f9b/torch-2.9.1-cp314-cp314t-win_amd64.whl", hash = "sha256:c88d3299ddeb2b35dcc31753305612db485ab6f1823e37fb29451c8b2732b87e", size = 111163659, upload-time = "2025-11-12T15:23:20.009Z" }, [[package]]
name = "torch"
version = "2.9.1+cu130"
source = { registry = "https://download.pytorch.org/whl/cu130" }
resolution-markers = [
"sys_platform == 'win32'",
"platform_machine == 'aarch64' and sys_platform == 'linux'",
"platform_machine != 'aarch64' and sys_platform == 'linux'",
]
dependencies = [
{ name = "filelock", marker = "sys_platform == 'linux' or sys_platform == 'win32'" },
{ name = "fsspec", marker = "sys_platform == 'linux' or sys_platform == 'win32'" },
{ name = "jinja2", marker = "sys_platform == 'linux' or sys_platform == 'win32'" },
{ name = "networkx", marker = "sys_platform == 'linux' or sys_platform == 'win32'" },
{ name = "nvidia-cublas", marker = "sys_platform == 'linux'" },
{ name = "nvidia-cuda-cupti", marker = "sys_platform == 'linux'" },
{ name = "nvidia-cuda-nvrtc", marker = "sys_platform == 'linux'" },
{ name = "nvidia-cuda-runtime", marker = "sys_platform == 'linux'" },
{ name = "nvidia-cudnn-cu13", marker = "sys_platform == 'linux'" },
{ name = "nvidia-cufft", marker = "sys_platform == 'linux'" },
{ name = "nvidia-cufile", marker = "sys_platform == 'linux'" },
{ name = "nvidia-curand", marker = "sys_platform == 'linux'" },
{ name = "nvidia-cusolver", marker = "sys_platform == 'linux'" },
{ name = "nvidia-cusparse", marker = "sys_platform == 'linux'" },
{ name = "nvidia-cusparselt-cu13", marker = "sys_platform == 'linux'" },
{ name = "nvidia-nccl-cu13", marker = "sys_platform == 'linux'" },
{ name = "nvidia-nvjitlink", marker = "sys_platform == 'linux'" },
{ name = "nvidia-nvshmem-cu13", marker = "sys_platform == 'linux'" },
{ name = "nvidia-nvtx", marker = "sys_platform == 'linux'" },
{ name = "setuptools", marker = "sys_platform == 'linux' or sys_platform == 'win32'" },
{ name = "sympy", marker = "sys_platform == 'linux' or sys_platform == 'win32'" },
{ name = "triton", marker = "sys_platform == 'linux'" },
{ name = "typing-extensions", marker = "sys_platform == 'linux' or sys_platform == 'win32'" },
]
wheels = [
{ url = "https://download.pytorch.org/whl/cu130/torch-2.9.1%2Bcu130-cp314-cp314-manylinux_2_28_aarch64.whl" },
{ url = "https://download.pytorch.org/whl/cu130/torch-2.9.1%2Bcu130-cp314-cp314-manylinux_2_28_x86_64.whl" },
{ url = "https://download.pytorch.org/whl/cu130/torch-2.9.1%2Bcu130-cp314-cp314-win_amd64.whl" },
{ url = "https://download.pytorch.org/whl/cu130/torch-2.9.1%2Bcu130-cp314-cp314t-manylinux_2_28_aarch64.whl" },
{ url = "https://download.pytorch.org/whl/cu130/torch-2.9.1%2Bcu130-cp314-cp314t-manylinux_2_28_x86_64.whl" },
{ url = "https://download.pytorch.org/whl/cu130/torch-2.9.1%2Bcu130-cp314-cp314t-win_amd64.whl" },
] ]
[[package]] [[package]]
@@ -720,7 +765,8 @@ source = { registry = "https://pypi.org/simple" }
dependencies = [ dependencies = [
{ name = "numpy" }, { name = "numpy" },
{ name = "pillow" }, { name = "pillow" },
{ name = "torch" }, { name = "torch", version = "2.9.1", source = { registry = "https://pypi.org/simple" }, marker = "sys_platform != 'linux' and sys_platform != 'win32'" },
{ name = "torch", version = "2.9.1+cu130", source = { registry = "https://download.pytorch.org/whl/cu130" }, marker = "sys_platform == 'linux' or sys_platform == 'win32'" },
] ]
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/42/84/577b2cef8f32094add5f52887867da4c2a3e6b4261538447e9b48eb25812/torchvision-0.24.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:cccf4b4fec7fdfcd3431b9ea75d1588c0a8596d0333245dafebee0462abe3388", size = 2005319, upload-time = "2025-11-12T15:25:23.827Z" }, { url = "https://files.pythonhosted.org/packages/42/84/577b2cef8f32094add5f52887867da4c2a3e6b4261538447e9b48eb25812/torchvision-0.24.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:cccf4b4fec7fdfcd3431b9ea75d1588c0a8596d0333245dafebee0462abe3388", size = 2005319, upload-time = "2025-11-12T15:25:23.827Z" },
@@ -738,7 +784,9 @@ name = "triton"
version = "3.5.1" version = "3.5.1"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/14/f9/0430e879c1e63a1016cb843261528fd3187c872c3a9539132efc39514753/triton-3.5.1-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f617aa7925f9ea9968ec2e1adaf93e87864ff51549c8f04ce658f29bbdb71e2d", size = 159956163, upload-time = "2025-11-11T17:52:12.999Z" },
{ url = "https://files.pythonhosted.org/packages/a4/e6/c595c35e5c50c4bc56a7bac96493dad321e9e29b953b526bbbe20f9911d0/triton-3.5.1-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d0637b1efb1db599a8e9dc960d53ab6e4637db7d4ab6630a0974705d77b14b60", size = 170480488, upload-time = "2025-11-11T17:41:18.222Z" }, { url = "https://files.pythonhosted.org/packages/a4/e6/c595c35e5c50c4bc56a7bac96493dad321e9e29b953b526bbbe20f9911d0/triton-3.5.1-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d0637b1efb1db599a8e9dc960d53ab6e4637db7d4ab6630a0974705d77b14b60", size = 170480488, upload-time = "2025-11-11T17:41:18.222Z" },
{ url = "https://files.pythonhosted.org/packages/41/1e/63d367c576c75919e268e4fbc33c1cb33b6dc12bb85e8bfe531c2a8bd5d3/triton-3.5.1-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8932391d7f93698dfe5bc9bead77c47a24f97329e9f20c10786bb230a9083f56", size = 160073620, upload-time = "2025-11-11T17:52:18.403Z" },
{ url = "https://files.pythonhosted.org/packages/16/b5/b0d3d8b901b6a04ca38df5e24c27e53afb15b93624d7fd7d658c7cd9352a/triton-3.5.1-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bac7f7d959ad0f48c0e97d6643a1cc0fd5786fe61cb1f83b537c6b2d54776478", size = 170582192, upload-time = "2025-11-11T17:41:23.963Z" }, { url = "https://files.pythonhosted.org/packages/16/b5/b0d3d8b901b6a04ca38df5e24c27e53afb15b93624d7fd7d658c7cd9352a/triton-3.5.1-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bac7f7d959ad0f48c0e97d6643a1cc0fd5786fe61cb1f83b537c6b2d54776478", size = 170582192, upload-time = "2025-11-11T17:41:23.963Z" },
] ]
@@ -765,7 +813,8 @@ dependencies = [
{ name = "pyyaml" }, { name = "pyyaml" },
{ name = "requests" }, { name = "requests" },
{ name = "scipy" }, { name = "scipy" },
{ name = "torch" }, { name = "torch", version = "2.9.1", source = { registry = "https://pypi.org/simple" }, marker = "sys_platform != 'linux' and sys_platform != 'win32'" },
{ name = "torch", version = "2.9.1+cu130", source = { registry = "https://download.pytorch.org/whl/cu130" }, marker = "sys_platform == 'linux' or sys_platform == 'win32'" },
{ name = "torchvision" }, { name = "torchvision" },
{ name = "ultralytics-thop" }, { name = "ultralytics-thop" },
] ]
@@ -780,7 +829,8 @@ version = "2.0.18"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
dependencies = [ dependencies = [
{ name = "numpy" }, { name = "numpy" },
{ name = "torch" }, { name = "torch", version = "2.9.1", source = { registry = "https://pypi.org/simple" }, marker = "sys_platform != 'linux' and sys_platform != 'win32'" },
{ name = "torch", version = "2.9.1+cu130", source = { registry = "https://download.pytorch.org/whl/cu130" }, marker = "sys_platform == 'linux' or sys_platform == 'win32'" },
] ]
sdist = { url = "https://files.pythonhosted.org/packages/1f/63/21a32e1facfeee245dbdfb7b4669faf7a36ff7c00b50987932bdab126f4b/ultralytics_thop-2.0.18.tar.gz", hash = "sha256:21103bcd39cc9928477dc3d9374561749b66a1781b35f46256c8d8c4ac01d9cf", size = 34557, upload-time = "2025-10-29T16:58:13.526Z" } sdist = { url = "https://files.pythonhosted.org/packages/1f/63/21a32e1facfeee245dbdfb7b4669faf7a36ff7c00b50987932bdab126f4b/ultralytics_thop-2.0.18.tar.gz", hash = "sha256:21103bcd39cc9928477dc3d9374561749b66a1781b35f46256c8d8c4ac01d9cf", size = 34557, upload-time = "2025-10-29T16:58:13.526Z" }
wheels = [ wheels = [