dstpr 0.2.4__tar.gz → 0.2.5__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dstpr
3
- Version: 0.2.4
3
+ Version: 0.2.5
4
4
  Summary: A high-throughput, domain-specific text preprocessing cascading pipeline filter to rank core sentences in texts and filter away boilerplate.
5
5
  Author-email: Stephen Meisenbacher <sjmeis@gtgd.com>
6
6
  Maintainer-email: Stephen Meisenbacher <sjmeis@gtgd.com>
@@ -12,22 +12,38 @@ from dstpr.profiles import DomainProfile
12
12
 
13
13
  def get_optimal_gpu_batch_size(target_vram_ratio: float = 0.75) -> int:
14
14
  if not torch.cuda.is_available():
15
- return 64
15
+ return 64, 32
16
16
  device = torch.cuda.current_device()
17
17
  free_bytes, _ = torch.cuda.mem_get_info(device)
18
18
  free_mb = free_bytes / (1024 ** 2)
19
- # Estimate ~1.2MB memory per sample in FP16
20
- ideal = int((free_mb * target_vram_ratio) / 1.2)
21
- if ideal <= 128:
22
- return 128
23
- power_of_two = 1 << (ideal.bit_length() - 1)
24
- return min(max(power_of_two, 128), 4096)
19
+ usable_mb = free_mb * target_vram_ratio
20
+
21
+ # Single-sentence Bi-Encoder: ~1.2 MB peak per sample (L <= 40)
22
+ ideal_bi = int(usable_mb / 1.2)
23
+ # Paired-input Cross-Encoder: ~4.5 MB peak per sample (L <= 128)
24
+ ideal_cross = int(usable_mb / 4.5)
25
+
26
+ def snap_pow2(val: int, min_val: int, max_val: int) -> int:
27
+ if val <= min_val:
28
+ return min_val
29
+ val = min(val, max_val)
30
+ return 1 << (val.bit_length() - 1)
31
+
32
+ bi_batch = snap_pow2(ideal_bi, min_val=128, max_val=2048)
33
+ cross_batch = snap_pow2(ideal_cross, min_val=64, max_val=512)
34
+
35
+ return bi_batch, cross_batch
25
36
 
26
37
  class ParallelPreprocessingPipeline:
27
- def __init__(self, profile: DomainProfile, doc_chunk_size: int = 100, embedding_model: str = "sentence-transformers/all-MiniLM-L6-v2", use_gpu: bool = False,):
38
+ def __init__(self, profile: DomainProfile, doc_chunk_size: int = 100,
39
+ embedding_model: str = "sentence-transformers/all-MiniLM-L6-v2",
40
+ cross_model: str = "cross-encoder/ms-marco-MiniLM-L-6-v2",
41
+ use_gpu: bool = False
42
+ ):
28
43
  self.profile = profile
29
44
  self.doc_chunk_size = doc_chunk_size
30
45
  self.embedding_model = embedding_model
46
+ self.cross_model = cross_model
31
47
  self.use_gpu = use_gpu and torch.cuda.is_available()
32
48
 
33
49
  self.router = None
@@ -43,8 +59,6 @@ class ParallelPreprocessingPipeline:
43
59
  if self.use_gpu:
44
60
  torch.backends.cuda.matmul.allow_tf32 = True
45
61
  torch.backends.cudnn.allow_tf32 = True
46
- self.inference_batch_size = get_optimal_gpu_batch_size()
47
- print(f"GPU Auto-Calibrated Batch Size: {self.inference_batch_size}")
48
62
 
49
63
  dtype = torch.bfloat16 if torch.cuda.is_bf16_supported() else torch.float16
50
64
  self.bi_encoder = SentenceTransformer(
@@ -54,14 +68,16 @@ class ParallelPreprocessingPipeline:
54
68
  )
55
69
 
56
70
  self.cross_encoder = CrossEncoder(
57
- "cross-encoder/ms-marco-MiniLM-L6-v2",
71
+ self.cross_model,
58
72
  device="cuda",
59
73
  model_kwargs={"dtype": dtype}
60
74
  )
61
75
  else:
62
- self.inference_batch_size = 256
63
76
  self.bi_encoder = SentenceTransformer(self.embedding_model, device=device)
64
- self.cross_encoder = CrossEncoder("cross-encoder/ms-marco-MiniLM-L-6-v2", device=device)
77
+ self.cross_encoder = CrossEncoder(self.cross_model, device=device)
78
+
79
+ self.bi_batch_size, self.cross_batch_size = get_optimal_gpu_batch_size()
80
+ print(f"Auto-Calibrated Batch Size: Bi | {self.bi_batch_size}, Cross | {self.cross_batch_size}")
65
81
 
66
82
  self.router = SemanticSectionRouter(profile=self.profile, model=self.bi_encoder)
67
83
  self.ranker = HybridRanker(
@@ -81,7 +97,6 @@ class ParallelPreprocessingPipeline:
81
97
  continue
82
98
 
83
99
  sents = clean_and_split_chunks(raw_text, self.profile)
84
- n_sents = len(sents)
85
100
  doc_sentence_counts.append(len(sents))
86
101
  flat_sentences.extend(sents)
87
102
 
@@ -102,7 +117,7 @@ class ParallelPreprocessingPipeline:
102
117
  flat_candidates, flat_cand_embs, doc_cand_counts = self.router.route_sentences(
103
118
  sentences=flat_sentences,
104
119
  doc_sentence_counts=doc_sentence_counts,
105
- batch_size=self.inference_batch_size,
120
+ batch_size=self.bi_batch_size
106
121
  )
107
122
 
108
123
  filtered_doc_sentences = self.ranker.rank_and_filter(
@@ -110,7 +125,7 @@ class ParallelPreprocessingPipeline:
110
125
  flat_cand_embs=flat_cand_embs,
111
126
  doc_cand_counts=doc_cand_counts,
112
127
  cross_prob_threshold=threshold,
113
- batch_size=self.inference_batch_size,
128
+ batch_size=self.cross_batch_size
114
129
  )
115
130
 
116
131
  return [sanitize_outputs(sents, self.profile) for sents in filtered_doc_sentences]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dstpr
3
- Version: 0.2.4
3
+ Version: 0.2.5
4
4
  Summary: A high-throughput, domain-specific text preprocessing cascading pipeline filter to rank core sentences in texts and filter away boilerplate.
5
5
  Author-email: Stephen Meisenbacher <sjmeis@gtgd.com>
6
6
  Maintainer-email: Stephen Meisenbacher <sjmeis@gtgd.com>
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "dstpr"
7
- version = "0.2.4"
7
+ version = "0.2.5"
8
8
  description = "A high-throughput, domain-specific text preprocessing cascading pipeline filter to rank core sentences in texts and filter away boilerplate."
9
9
  readme = {file = "README.md", content-type = "text/markdown"}
10
10
  license = {file = "LICENSE"}
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes