From f1e1d6b3b75e26fe9dc6be8d7b6f85de4a35a262 Mon Sep 17 00:00:00 2001 From: "Ishan S. Patel" Date: Thu, 30 Jul 2026 10:47:58 -0400 Subject: [PATCH] commit before cleanup --- .../auto_compact_milvus.cpython-314.pyc | Bin 0 -> 5722 bytes .../upload_npz_to_milvus.cpython-314.pyc | Bin 0 -> 3730 bytes .../auto_compact_milvus.py | 136 ++++++++++++++++++ .../upload_npz_to_milvus.py | 48 ++++--- ...20_delete_files_and_create_other_videos.py | 4 +- 5 files changed, 168 insertions(+), 20 deletions(-) create mode 100644 vision_v3/10_do_obj_det_and_clip/__pycache__/auto_compact_milvus.cpython-314.pyc create mode 100644 vision_v3/10_do_obj_det_and_clip/__pycache__/upload_npz_to_milvus.cpython-314.pyc create mode 100755 vision_v3/10_do_obj_det_and_clip/auto_compact_milvus.py mode change 100644 => 100755 vision_v3/10_do_obj_det_and_clip/upload_npz_to_milvus.py diff --git a/vision_v3/10_do_obj_det_and_clip/__pycache__/auto_compact_milvus.cpython-314.pyc b/vision_v3/10_do_obj_det_and_clip/__pycache__/auto_compact_milvus.cpython-314.pyc new file mode 100644 index 0000000000000000000000000000000000000000..dbcd09854c01fe3a86716aab908f6be931833e0b GIT binary patch literal 5722 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 F0|3aPhmrsQ literal 0 HcmV?d00001 diff --git a/vision_v3/10_do_obj_det_and_clip/__pycache__/upload_npz_to_milvus.cpython-314.pyc b/vision_v3/10_do_obj_det_and_clip/__pycache__/upload_npz_to_milvus.cpython-314.pyc new file mode 100644 index 0000000000000000000000000000000000000000..367a996f46de79e79e4b21aeb8e08c753e09589a GIT binary patch literal 3730 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 literal 0 HcmV?d00001 diff --git a/vision_v3/10_do_obj_det_and_clip/auto_compact_milvus.py b/vision_v3/10_do_obj_det_and_clip/auto_compact_milvus.py new file mode 100755 index 0000000..ad3c8c5 --- /dev/null +++ b/vision_v3/10_do_obj_det_and_clip/auto_compact_milvus.py @@ -0,0 +1,136 @@ +#!/home/thebears/envs/vector_search/bin/python + +"""Trigger and (optionally) wait on Milvus compaction for one or more collections. + +Each collection is flushed before compaction is triggered, since Milvus only +compacts sealed segments -- flushing seals any growing segments so recently +inserted data is actually eligible. + +By default this compacts every collection on the server once and exits, which is +the right shape for a cron job / systemd oneshot timer. Pass --loop to instead run +forever, re-compacting every --interval seconds (for a long-running systemd service). +""" + +from pymilvus import MilvusClient +from fnmatch import fnmatch +import argparse +import logging +import time +import random + +logger = logging.getLogger(__name__) + +DEFAULT_URI = "http://192.168.1.242:19530" + + +def compact_collections( + client, + pattern="*", + is_clustering=False, + wait=True, + poll_interval=60, + timeout=3600*10, + dry_run=False, +): + """Trigger compaction for every collection whose name matches `pattern`. + + Returns a dict of {collection_name: True/False/None}, where None means the + job was triggered but not waited on (wait=False). + """ + results = dict() + collections = [c for c in client.list_collections() if fnmatch(c, pattern)] + + if not collections: + logger.info(f"No collections matched pattern {pattern!r}") + return results + + random.shuffle(collections) + for coll_name in collections: + if dry_run: + logger.info(f"[dry-run] would flush and compact {coll_name}") + continue + + try: + client.flush(coll_name) + except Exception as e: + logger.error(f"Failed to flush {coll_name} before compaction: {e}") + results[coll_name] = False + continue + + try: + job_id = client.compact(coll_name, is_clustering=is_clustering) + except Exception as e: + logger.error(f"Failed to trigger compaction for {coll_name}: {e}") + results[coll_name] = False + continue + + logger.info(f"Triggered compaction job {job_id} for {coll_name}") + + if not wait: + results[coll_name] = None + continue + + waited = 0 + state = None + while waited < timeout: + try: + state = client.get_compaction_state(job_id) + except Exception as e: + logger.error(f"Failed to poll compaction state for {coll_name} (job {job_id}): {e}") + break + if state == "Completed": + break + time.sleep(poll_interval) + waited += poll_interval + + success = state == "Completed" + if success: + logger.info(f"Compaction of {coll_name} completed (job {job_id})") + else: + logger.warning(f"Compaction of {coll_name} (job {job_id}) ended with state={state} after {waited}s") + results[coll_name] = success + + return results + + +if __name__ == "__main__": + parser = argparse.ArgumentParser( + prog="Auto-compact Milvus collections" + ) + parser.add_argument("--uri", default=DEFAULT_URI, help="Milvus server URI") + parser.add_argument("--pattern", default="*", help="fnmatch glob to select which collections to compact") + parser.add_argument("--is-clustering", action="store_true", dest="is_clustering", + help="Trigger clustering compaction instead of a regular merge compaction") + parser.add_argument("--no-wait", action="store_false", dest="wait", + help="Trigger compaction jobs without waiting for them to finish") + parser.add_argument("--poll-interval", type=float, default=5, help="Seconds between compaction state polls") + parser.add_argument("--timeout", type=float, default=3600, help="Max seconds to wait per collection's compaction job") + parser.add_argument("--dry-run", action="store_true", help="List collections that would be compacted and exit") + parser.add_argument("--loop", action="store_true", help="Run forever, re-compacting on a fixed interval") + parser.add_argument("--interval", type=float, default=6 * 3600, help="Seconds between runs when --loop is set") + args = parser.parse_args() + + logging.basicConfig(level=logging.INFO, format="%(asctime)s|%(levelname)s|%(message)s") + + client = MilvusClient(uri=args.uri) + try: + while True: + results = compact_collections( + client, + pattern=args.pattern, + is_clustering=args.is_clustering, + wait=args.wait, + poll_interval=args.poll_interval, + timeout=args.timeout, + dry_run=args.dry_run, + ) + for coll_name, ok in results.items(): + if ok is False: + print(f"Failed: {coll_name}") + + if not args.loop: + break + logger.info(f"Sleeping {args.interval}s before next compaction pass") + time.sleep(args.interval) + finally: + client.close() diff --git a/vision_v3/10_do_obj_det_and_clip/upload_npz_to_milvus.py b/vision_v3/10_do_obj_det_and_clip/upload_npz_to_milvus.py old mode 100644 new mode 100755 index dfeabc7..bc21c59 --- a/vision_v3/10_do_obj_det_and_clip/upload_npz_to_milvus.py +++ b/vision_v3/10_do_obj_det_and_clip/upload_npz_to_milvus.py @@ -1,4 +1,6 @@ -from common_code.vector_utils import upload_vectors_to_db +#!/home/thebears/envs/vector_search/bin/python + +from common_code.vector_utils import bulk_insert_vectors_to_db, bulk_import_vectors_to_db from common_code import kwq, util, file_names, vector_utils, settings from multiprocessing import Pool from tqdm import tqdm @@ -10,7 +12,7 @@ logger = logging.getLogger(__name__) topic_subscribe = 'upload_to_vector_db' -def add_files_to_queue(paths, dry_run = False, force = False, do_upload = True, do_queue = False): +def add_files_to_queue(paths, dry_run = False, force = False, do_upload = True, do_queue = False, use_bulk_import = False): queued = set() for rt in paths: for root, dirs, files in os.walk(rt): @@ -20,22 +22,21 @@ def add_files_to_queue(paths, dry_run = False, force = False, do_upload = True, # if decide_to_put_in_queue(new_path, force = force): queued.add(new_path) - for x in tqdm(queued): - try: - if do_upload: - if os.path.exists(x+'.in_queue'): - pass - else: - upload_vectors_to_db(x) - with open(x+'.in_queue','w') as ff: - pass - if do_queue: + if do_upload: + upload_fn = bulk_import_vectors_to_db if use_bulk_import else bulk_insert_vectors_to_db + results = upload_fn(list(tqdm(queued))) + for x, ok in results.items(): + if not ok: + print('Failed: ' + str(x)) + + if do_queue: + for x in tqdm(queued): + try: kwq.publish(topic_subscribe, x, x) + except Exception as e: + print('Failed: '+str(x)+'with '+str(e)) - except Exception as e: - print('Failed: '+str(x)+'with '+str(e)) - @@ -47,16 +48,27 @@ if __name__ == "__main__": parser.add_argument("paths", nargs="*", help="Paths to monitor", default=()) parser.add_argument("--dry-run", action='store_true', help='Dry Run') parser.add_argument("--force", action='store_true', help='Force adding (do not check if already done)') - parser.add_argument("--skip_upload", action='store_true', help='Force adding (do not check if already done)') - parser.add_argument("--do_queue", action='store_true', help='Force adding (do not check if already done)') + parser.add_argument("--skip_upload", action='store_true', help='Force adding (do not check if already done)') + parser.add_argument("--do_queue", action='store_true', help='Force adding (do not check if already done)') + parser.add_argument("--bulk-import", action='store_true', dest='bulk_import', + help='EXPERIMENTAL/UNSAFE: use the Milvus server-side Bulk Import job API ' + 'instead of batched inserts. Known to crash this Milvus build when the ' + 'imported segment is loaded -- do not use against production collections.') args, _ = parser.parse_known_args() paths = args.paths force = args.force dry_run = args.dry_run do_queue = args.do_queue do_upload = not args.skip_upload + use_bulk_import = args.bulk_import if len(paths) == 0: paths = settings.dir_watch - add_files_to_queue(paths, dry_run = dry_run, force=force, do_upload = do_upload, do_queue = do_queue) + print(paths) + add_files_to_queue(paths, dry_run = dry_run, force=force, do_upload = do_upload, do_queue = do_queue, use_bulk_import = use_bulk_import) + +# %% +# from common_code.vector_utils import upload_vectors_to_db +# ff = '/srv/ftp/hummingbird/2026/07/18/hummingbird_00_20260718144349.oclip_embeds.npz' +# upload_vectors_to_db(ff) diff --git a/vision_v3/20_delete_files_and_create_other_videos/20_delete_files_and_create_other_videos.py b/vision_v3/20_delete_files_and_create_other_videos/20_delete_files_and_create_other_videos.py index b0cc4e1..324ba35 100644 --- a/vision_v3/20_delete_files_and_create_other_videos/20_delete_files_and_create_other_videos.py +++ b/vision_v3/20_delete_files_and_create_other_videos/20_delete_files_and_create_other_videos.py @@ -56,8 +56,6 @@ def get_ok_to_delete(file_path): # %% def exec_file_remove_logic(cset, dry_run = False): - - did_purge = False if isinstance(cset, dict): file_path = cset['.mp4'] @@ -92,6 +90,7 @@ def exec_file_remove_logic(cset, dry_run = False): n_frames_scored = len(det_results['scored_frames']) frac_frames_scored = n_frames_above / n_frames_scored + logger.info(f'Frac frames scored: {frac_frames_scored}') do_keep = frac_frames_scored > settings['frames_with_dets_threshold'] @@ -138,6 +137,7 @@ def perform_kafka_loop(): return logger.info(f"Executing file operations {pfm(file_to_score)}") did_purge = exec_file_remove_logic(get_cset_match(file_to_score)) + logger.info(f"Did purge? {did_purge} {get_cset_match(file_to_score)}") if not did_purge: did_convert = convert_file_with_check(file_to_score) FTPVideo(file_to_score).frames_info;