Optimization And Visualization Design
jhj
2026년 08월 12일
Design Spec: FAISS CPU Multi-Index Scaling, YOLO FP16/ONNX, and Results.plot() Visualization
- Date: 2026-08-12
- Topic: CPU FAISS Matcher Index Scaling (
IndexIVFFlat,IndexHNSWFlat), YOLO FP16/ONNX Pipeline Integration, andResults.plot()Visualization Completion - Target Repository:
lumipet-reid
1. Overview & Objectives
The goal of this enhancement is to improve inference speed, scalability, and usability of the lumipet-reid system without introducing breaking changes or breaking existing API contracts.
Key Objectives
- CPU FAISS Scalability: Replace the single
IndexFlatIPbrute-force matcher with a flexible multi-index strategy on CPU, supportingIndexFlatIP,IndexIVFFlat, andIndexHNSWFlat. Include dynamic fallbacks when vector count is small. - YOLO Pipeline Optimization: Add explicit support for
half=True(FP16) half-precision inference and ONNX Runtime model loading inYoloPredictorto align detector acceleration with the feature extractor. Results.plot()Completion: Fully implement the# TODOinResults.plot()to generate annotated BGR OpenCV numpy image arrays (np.ndarray) with customizable options (show_conf,show_similarity,line_thickness,font_scale).
2. Component Architecture & Data Flow
flowchart TD
subgraph Config Layer
cfg["reid/cfg/default.yaml & reid/core/config.py"]
end
subgraph Matching Engine
cfg -->|"matcher_index_type, faiss_nlist, faiss_nprobe, faiss_hnsw_m"| FaissMatcher["reid/models/matcher/faiss.py"]
FaissMatcher --> IndexChoice{"Vector Count & Config"}
IndexChoice -->|N < min_vectors OR type='flat'| FlatIP["faiss.IndexFlatIP"]
IndexChoice -->|type='ivfflat'| IVFFlat["faiss.IndexIVFFlat (Quantized)"]
IndexChoice -->|type='hnsw'| HNSW["faiss.IndexHNSWFlat (Graph)"]
end
subgraph Detection Engine
cfg -->|"yolo_fp16, use_onnx"| YoloPredictor["reid/models/yolo/detect/predict.py"]
YoloPredictor -->|fp16 & CUDA| FP16Infer["self.model.track(..., half=True)"]
YoloPredictor -->|use_onnx| ONNXInfer["YOLO(onnx_path)"]
end
subgraph Core & Visualization
Results["reid/core/types.py: Results"] -->|"plot()"| Plotter["OpenCV Annotation Helper"]
Plotter --> BGRImage["Annotated np.ndarray (BGR)"]
end
3. Detailed Component Specifications
3.1. FAISS CPU Multi-Index Strategy (reid/models/matcher/faiss.py)
Configuration Parameters
matcher_index_type(str): Index type to construct ("flat","ivfflat","hnsw"). Default:"flat".faiss_nlist(int): Number of Voronoi clusters forIVFFlat. Default:32.faiss_nprobe(int): Number of centroids to query forIVFFlat. Default:4.faiss_hnsw_m(int): Number of graph links per node forHNSWFlat. Default:32.faiss_min_ivf_vectors(int): Minimum vectors needed to buildIVFFlat. Default:100.
Index Construction Logic
IndexFlatIP: Direct cosine similarity matrix multiplication. Used whenindex_type == "flat"or when $N < \text{faiss_min_ivf_vectors}$.IndexIVFFlat:- Quantizer:
faiss.IndexFlatIP(d). nlist:min(faiss_nlist, max(1, N // 4)).- Training:
index.train(embeddings_f32)prior toindex.add(embeddings_f32). - Runtime Search:
index.nprobe = min(faiss_nprobe, index.nlist).
- Quantizer:
IndexHNSWFlat:faiss.IndexHNSWFlat(d, faiss_hnsw_m, faiss.METRIC_INNER_PRODUCT).- Directly
index.add(embeddings_f32).
- Safety & Concurrency:
- CPU-only execution using
faiss.omp_set_num_threads()to match machine CPU thread pool.
- CPU-only execution using
3.2. YOLO Detector FP16 & ONNX Support (reid/models/yolo/detect/predict.py)
- FP16 Inference:
- In
YoloPredictor.inference(), check ifgetattr(self.cfg, "yolo_fp16", False)orgetattr(self.cfg, "fp16", False)isTrueanddevice != "cpu". - Pass
half=Truetoself.model.track(...)orself.model(...).
- In
- ONNX Loading:
- In
YoloPredictor.__init__(), ifgetattr(self.cfg, "use_onnx", False)is enabled andonnx_detector_pathexists on disk, initialize model withYOLO(onnx_detector_path).
- In
3.3. Results.plot() Visualization (reid/core/types.py)
Signature
def plot(
self,
show_conf: bool = True,
show_similarity: bool = True,
line_thickness: Optional[int] = None,
font_scale: Optional[float] = None,
k_colors: Optional[dict] = None
) -> np.ndarray:
Behavior
- Check if
self.orig_imgis present. If missing, raiseValueError("Results object has no orig_img to plot."). - Create a copy of
orig_img(annotated = self.orig_img.copy()). - Compute dynamic
line_thicknessandfont_scalebased on image resolution if not provided. - Iterate over
zip(self.boxes, self.match_results):- For each box, pick color based on
MatchResult.cat_id(deterministic color hashing per ID) or green for Known, gray for Unknown. - Draw filled bounding box corner / outline using
cv2.rectangle. - Construct label text:
- e.g.,
"Nabi | Sim: 0.88"or"Nabi | Conf: 0.95, Sim: 0.88"or"Unknown".
- e.g.,
- Draw background rectangle behind label text for high contrast and draw label text with
cv2.putText.
- For each box, pick color based on
- Return
annotatedasnp.ndarray(BGR image).
4. Configuration Updates
reid/cfg/default.yaml
# Matcher Index Parameters
matcher_index_type: "flat" # Options: "flat", "ivfflat", "hnsw"
faiss_nlist: 32
faiss_nprobe: 4
faiss_hnsw_m: 32
faiss_min_ivf_vectors: 100
# Detector FP16
yolo_fp16: False
reid/core/config.py
Add dataclass field definitions with default values:
matcher_index_type: str = "flat"faiss_nlist: int = 32faiss_nprobe: int = 4faiss_hnsw_m: int = 32faiss_min_ivf_vectors: int = 100yolo_fp16: bool = False
5. Error Handling & Edge Cases
- Empty / Small Embedding DB:
- If $N=0$,
FaissMatchersetsis_fitted = Falsewithout errors. - If $N < \text{faiss_min_ivf_vectors}$, automatically fallback to
IndexFlatIP.
- If $N=0$,
- Missing Original Image in
Results.plot():- Raise informative
ValueError.
- Raise informative
- No Detections:
Results.plot()safely returns an exact copy oforig_imgwith zero drawings.
- CUDA Not Available for FP16:
- If
device == "cpu", gracefully ignorehalf=Trueto prevent CPU crash.
- If
6. Testing & Verification Plan
tests/test_faiss_matcher.py:- Test
FaissMatcherfitting with 10 dummy vectors using"flat","ivfflat", and"hnsw". Verify fallback behavior for small vector counts. - Test matching accuracy with 500 dummy vectors for
"ivfflat"and"hnsw".
- Test
tests/test_results_plot.py:- Create synthetic
Resultsobject with dummy image array and 2 BBoxes (MatchResult(cat_id="Nabi", similarity=0.9, is_known=True)andMatchResult(cat_id="Unknown", similarity=0.3, is_known=False)). - Call
results.plot()and assert returned type isnp.ndarraywith shape equal to input image.
- Create synthetic
- Integration Check:
- Run pipeline via
reid/cli.pyor synthetic test loop to verify end-to-end functionality.
- Run pipeline via
C
Contents
