nv-ingest 2025.8.18.dev20250818__py3-none-any.whl → 2025.8.20.dev20250820__py3-none-any.whl

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.
@@ -3,8 +3,6 @@
3
3
  # SPDX-License-Identifier: Apache-2.0
4
4
 
5
5
  import multiprocessing
6
- import os
7
- import signal
8
6
  import threading
9
7
  from abc import ABC, abstractmethod
10
8
  from dataclasses import dataclass
@@ -22,6 +20,7 @@ import logging
22
20
  import time
23
21
 
24
22
  from nv_ingest.framework.orchestration.ray.primitives.pipeline_topology import PipelineTopology, StageInfo
23
+ from nv_ingest.framework.orchestration.process.termination import kill_pipeline_process_group
25
24
  from nv_ingest.framework.orchestration.ray.primitives.ray_stat_collector import RayStatsCollector
26
25
  from nv_ingest.framework.orchestration.ray.util.pipeline.pid_controller import PIDController, ResourceConstraintManager
27
26
  from nv_ingest.framework.orchestration.ray.util.pipeline.tools import wrap_callable_as_stage
@@ -120,24 +119,19 @@ class RayPipelineSubprocessInterface(PipelineInterface):
120
119
 
121
120
  def stop(self) -> None:
122
121
  """
123
- Stops the subprocess pipeline. Tries terminate(), then escalates to SIGKILL on the process group if needed.
122
+ Stops the subprocess pipeline and its entire process group to ensure
123
+ any child processes (e.g., the simple message broker) are terminated.
124
124
  """
125
- if not self._process.is_alive():
125
+ try:
126
+ pid = int(self._process.pid)
127
+ except Exception:
126
128
  return
127
129
 
130
+ # Always attempt to terminate the entire process group
128
131
  try:
129
- self._process.terminate()
130
- self._process.join(timeout=5.0)
132
+ kill_pipeline_process_group(pid)
131
133
  except Exception as e:
132
- logger.warning(f"Failed to terminate process cleanly: {e}")
133
-
134
- if self._process.is_alive():
135
- try:
136
- pgid = os.getpgid(self._process.pid)
137
- os.killpg(pgid, signal.SIGKILL)
138
- except Exception as e:
139
- logger.error(f"Failed to force-kill process group: {e}")
140
- self._process.join(timeout=3.0)
134
+ logger.warning(f"kill_pipeline_process_group failed: {e}")
141
135
 
142
136
 
143
137
  class RayPipelineInterface(PipelineInterface):
@@ -14,7 +14,8 @@ import yaml
14
14
  from typing import Optional
15
15
 
16
16
  from nv_ingest.pipeline.pipeline_schema import PipelineConfigSchema
17
- from nv_ingest.pipeline.default_pipeline_impl import DEFAULT_LIBMODE_PIPELINE_YAML
17
+ from nv_ingest.pipeline.default_libmode_pipeline_impl import DEFAULT_LIBMODE_PIPELINE_YAML
18
+ from nv_ingest.pipeline.default_pipeline_impl import DEFAULT_PIPELINE_YAML
18
19
  from nv_ingest.framework.orchestration.execution.options import PipelineRuntimeOverrides
19
20
  from nv_ingest_api.util.string_processing.yaml import substitute_env_vars_in_yaml_content
20
21
 
@@ -64,6 +65,35 @@ def load_pipeline_config(config_path: str) -> PipelineConfigSchema:
64
65
  return PipelineConfigSchema(**processed_config)
65
66
 
66
67
 
68
+ def load_default_pipeline_config() -> PipelineConfigSchema:
69
+ """
70
+ Load and validate the embedded default (non-libmode) pipeline configuration.
71
+
72
+ Returns
73
+ -------
74
+ PipelineConfigSchema
75
+ Validated default pipeline configuration.
76
+
77
+ Raises
78
+ ------
79
+ ValueError
80
+ If the default YAML cannot be parsed or validated.
81
+ """
82
+ logger.info("Loading embedded default pipeline configuration")
83
+
84
+ substituted_content = substitute_env_vars_in_yaml_content(DEFAULT_PIPELINE_YAML)
85
+
86
+ try:
87
+ processed_config = yaml.safe_load(substituted_content)
88
+ except yaml.YAMLError as e:
89
+ error_message = (
90
+ f"Failed to parse embedded default pipeline YAML after environment variable substitution. Error: {e}"
91
+ )
92
+ raise ValueError(error_message) from e
93
+
94
+ return PipelineConfigSchema(**processed_config)
95
+
96
+
67
97
  def load_default_libmode_config() -> PipelineConfigSchema:
68
98
  """
69
99
  Load and validate the default libmode pipeline configuration.
@@ -195,4 +225,5 @@ def resolve_pipeline_config(provided_config: Optional[PipelineConfigSchema], lib
195
225
  if libmode:
196
226
  return load_default_libmode_config()
197
227
  else:
198
- raise ValueError("pipeline_config must be provided when libmode is False")
228
+ # For non-libmode, fall back to embedded default pipeline implementation
229
+ return load_default_pipeline_config()
@@ -0,0 +1,514 @@
1
+ # SPDX-FileCopyrightText: Copyright (c) 2024-25, NVIDIA CORPORATION & AFFILIATES.
2
+ # All rights reserved.
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+ # noqa
6
+ # flake8: noqa
7
+ # pylint: disable=line-too-long
8
+
9
+ """
10
+ Default pipeline implementation for libmode.
11
+
12
+ This module contains the default libmode pipeline configuration as a string,
13
+ allowing the pipeline to be loaded without requiring external YAML files.
14
+ """
15
+
16
+ DEFAULT_LIBMODE_PIPELINE_YAML = """# Default Ingestion Pipeline Configuration for Library Mode
17
+ # This file replicates the static pipeline defined in pipeline_builders.py
18
+
19
+ name: "NVIngest default libmode pipeline"
20
+ description: "This is the default ingestion pipeline for NVIngest in library mode"
21
+ stages:
22
+ # Source
23
+ - name: "source_stage"
24
+ type: "source"
25
+ phase: 0 # PRE_PROCESSING
26
+ actor: "nv_ingest.framework.orchestration.ray.stages.sources.message_broker_task_source:MessageBrokerTaskSourceStage"
27
+ config:
28
+ broker_client:
29
+ client_type: "simple"
30
+ host: $MESSAGE_CLIENT_HOST|"0.0.0.0"
31
+ port: $MESSAGE_CLIENT_PORT|7671
32
+ task_queue: "ingest_task_queue"
33
+ poll_interval: 0.1
34
+ replicas:
35
+ min_replicas: 1
36
+ max_replicas:
37
+ strategy: "static"
38
+ value: 1
39
+ static_replicas:
40
+ strategy: "static"
41
+ value: 1
42
+ runs_after: []
43
+
44
+ # Pre-processing
45
+ - name: "metadata_injector"
46
+ type: "stage"
47
+ phase: 0 # PRE_PROCESSING
48
+ actor: "nv_ingest.framework.orchestration.ray.stages.injectors.metadata_injector:MetadataInjectionStage"
49
+ config: {}
50
+ replicas:
51
+ min_replicas: 0
52
+ max_replicas:
53
+ strategy: "static"
54
+ value: 1
55
+ static_replicas:
56
+ strategy: "static"
57
+ value: 1
58
+ runs_after:
59
+ - "source_stage"
60
+
61
+ # Primitive Extraction
62
+ - name: "pdf_extractor"
63
+ type: "stage"
64
+ phase: 1 # EXTRACTION
65
+ actor: "nv_ingest.framework.orchestration.ray.stages.extractors.pdf_extractor:PDFExtractorStage"
66
+ config:
67
+ pdfium_config:
68
+ auth_token: $NGC_API_KEY|""
69
+ yolox_endpoints: [
70
+ $YOLOX_GRPC_ENDPOINT|"",
71
+ $YOLOX_HTTP_ENDPOINT|"https://ai.api.nvidia.com/v1/cv/nvidia/nemoretriever-page-elements-v2"
72
+ ]
73
+ yolox_infer_protocol: $YOLOX_INFER_PROTOCOL|http
74
+ nemoretriever_parse_config:
75
+ auth_token: $NGC_API_KEY|""
76
+ nemoretriever_parse_endpoints: [
77
+ $NEMORETRIEVER_PARSE_GRPC_ENDPOINT|"",
78
+ $NEMORETRIEVER_PARSE_HTTP_ENDPOINT|"https://integrate.api.nvidia.com/v1/chat/completions"
79
+ ]
80
+ nemoretriever_parse_infer_protocol: $NEMORETRIEVER_PARSE_INFER_PROTOCOL|http
81
+ nemoretriever_parse_model_name: $NEMORETRIEVER_PARSE_MODEL_NAME|"nvidia/nemoretriever-parse"
82
+ yolox_endpoints: [
83
+ $YOLOX_GRPC_ENDPOINT|"",
84
+ $YOLOX_HTTP_ENDPOINT|"https://ai.api.nvidia.com/v1/cv/nvidia/nemoretriever-page-elements-v2"
85
+ ]
86
+ yolox_infer_protocol: $YOLOX_INFER_PROTOCOL|http
87
+ replicas:
88
+ min_replicas: 0
89
+ max_replicas:
90
+ strategy: "memory_thresholding"
91
+ memory_per_replica_mb: 10000 # Heuristic max consumption
92
+ static_replicas:
93
+ strategy: "memory_static_global_percent"
94
+ memory_per_replica_mb: 10000
95
+ limit: 16
96
+
97
+ - name: "audio_extractor"
98
+ type: "stage"
99
+ phase: 1 # EXTRACTION
100
+ actor: "nv_ingest.framework.orchestration.ray.stages.extractors.audio_extractor:AudioExtractorStage"
101
+ config:
102
+ audio_extraction_config:
103
+ audio_endpoints: [
104
+ $AUDIO_GRPC_ENDPOINT|"grpc.nvcf.nvidia.com:443",
105
+ $AUDIO_HTTP_ENDPOINT|""
106
+ ]
107
+ function_id: $AUDIO_FUNCTION_ID|"1598d209-5e27-4d3c-8079-4751568b1081"
108
+ audio_infer_protocol: $AUDIO_INFER_PROTOCOL|grpc
109
+ auth_token: $NGC_API_KEY|""
110
+ replicas:
111
+ min_replicas: 0
112
+ max_replicas:
113
+ strategy: "static"
114
+ value: 2
115
+ static_replicas:
116
+ strategy: "static"
117
+ value: 2
118
+
119
+ - name: "docx_extractor"
120
+ type: "stage"
121
+ phase: 1 # EXTRACTION
122
+ actor: "nv_ingest.framework.orchestration.ray.stages.extractors.docx_extractor:DocxExtractorStage"
123
+ config:
124
+ docx_extraction_config:
125
+ yolox_endpoints: [
126
+ $YOLOX_GRPC_ENDPOINT|"",
127
+ $YOLOX_HTTP_ENDPOINT|"https://ai.api.nvidia.com/v1/cv/nvidia/nemoretriever-page-elements-v2"
128
+ ]
129
+ yolox_infer_protocol: $YOLOX_INFER_PROTOCOL|http
130
+ auth_token: $NGC_API_KEY|""
131
+ replicas:
132
+ min_replicas: 0
133
+ max_replicas:
134
+ strategy: "static"
135
+ value: 2
136
+ static_replicas:
137
+ strategy: "static"
138
+ value: 1
139
+
140
+ - name: "pptx_extractor"
141
+ type: "stage"
142
+ phase: 1 # EXTRACTION
143
+ actor: "nv_ingest.framework.orchestration.ray.stages.extractors.pptx_extractor:PPTXExtractorStage"
144
+ config:
145
+ pptx_extraction_config:
146
+ yolox_endpoints: [
147
+ $YOLOX_GRPC_ENDPOINT|"",
148
+ $YOLOX_HTTP_ENDPOINT|"https://ai.api.nvidia.com/v1/cv/nvidia/nemoretriever-page-elements-v2"
149
+ ]
150
+ yolox_infer_protocol: $YOLOX_INFER_PROTOCOL|http
151
+ auth_token: $NGC_API_KEY|""
152
+ replicas:
153
+ min_replicas: 0
154
+ max_replicas:
155
+ strategy: "static"
156
+ value: 2
157
+ static_replicas:
158
+ strategy: "static"
159
+ value: 1
160
+
161
+ - name: "image_extractor"
162
+ type: "stage"
163
+ phase: 1 # EXTRACTION
164
+ actor: "nv_ingest.framework.orchestration.ray.stages.extractors.image_extractor:ImageExtractorStage"
165
+ config:
166
+ image_extraction_config:
167
+ yolox_endpoints: [
168
+ $YOLOX_GRPC_ENDPOINT|"",
169
+ $YOLOX_HTTP_ENDPOINT|"https://ai.api.nvidia.com/v1/cv/nvidia/nemoretriever-page-elements-v2"
170
+ ]
171
+ yolox_infer_protocol: $YOLOX_INFER_PROTOCOL|http
172
+ auth_token: $NGC_API_KEY|""
173
+ replicas:
174
+ min_replicas: 0
175
+ max_replicas:
176
+ strategy: "static"
177
+ value: 2
178
+ static_replicas:
179
+ strategy: "static"
180
+ value: 1
181
+
182
+ - name: "html_extractor"
183
+ type: "stage"
184
+ phase: 1 # EXTRACTION
185
+ actor: "nv_ingest.framework.orchestration.ray.stages.extractors.html_extractor:HtmlExtractorStage"
186
+ config: {}
187
+ replicas:
188
+ min_replicas: 0
189
+ max_replicas:
190
+ strategy: "static"
191
+ value: 2
192
+ static_replicas:
193
+ strategy: "static"
194
+ value: 1
195
+
196
+ - name: "infographic_extractor"
197
+ type: "stage"
198
+ phase: 1 # EXTRACTION
199
+ actor: "nv_ingest.framework.orchestration.ray.stages.extractors.infographic_extractor:InfographicExtractorStage"
200
+ config:
201
+ endpoint_config:
202
+ ocr_endpoints: [
203
+ $OCR_GRPC_ENDPOINT|"grpc.nvcf.nvidia.com:443",
204
+ $OCR_HTTP_ENDPOINT|""
205
+ ]
206
+ ocr_infer_protocol: $OCR_INFER_PROTOCOL|grpc
207
+ auth_token: $NGC_API_KEY|""
208
+ replicas:
209
+ min_replicas: 0
210
+ max_replicas:
211
+ strategy: "static"
212
+ value: 2
213
+ static_replicas:
214
+ strategy: "static"
215
+ value: 1
216
+
217
+ - name: "table_extractor"
218
+ type: "stage"
219
+ phase: 1 # EXTRACTION
220
+ actor: "nv_ingest.framework.orchestration.ray.stages.extractors.table_extractor:TableExtractorStage"
221
+ config:
222
+ endpoint_config:
223
+ yolox_endpoints: [
224
+ $YOLOX_TABLE_STRUCTURE_GRPC_ENDPOINT|"",
225
+ $YOLOX_TABLE_STRUCTURE_HTTP_ENDPOINT|"https://ai.api.nvidia.com/v1/cv/nvidia/nemoretriever-table-structure-v1"
226
+ ]
227
+ yolox_infer_protocol: $YOLOX_TABLE_STRUCTURE_INFER_PROTOCOL|"http"
228
+ ocr_endpoints: [
229
+ $OCR_GRPC_ENDPOINT|"",
230
+ $OCR_HTTP_ENDPOINT|"https://ai.api.nvidia.com/v1/cv/baidu/paddleocr"
231
+ ]
232
+ ocr_infer_protocol: $PADDLE_INFER_PROTOCOL|"http"
233
+ auth_token: $NGC_API_KEY|""
234
+ replicas:
235
+ min_replicas: 0
236
+ max_replicas:
237
+ strategy: "memory_thresholding"
238
+ memory_per_replica_mb: 10000
239
+ static_replicas:
240
+ strategy: "memory_static_global_percent"
241
+ memory_per_replica_mb: 10000
242
+ limit: 6
243
+
244
+ - name: "chart_extractor"
245
+ type: "stage"
246
+ phase: 1 # EXTRACTION
247
+ actor: "nv_ingest.framework.orchestration.ray.stages.extractors.chart_extractor:ChartExtractorStage"
248
+ config:
249
+ endpoint_config:
250
+ yolox_endpoints: [
251
+ $YOLOX_GRAPHIC_ELEMENTS_GRPC_ENDPOINT|"",
252
+ $YOLOX_GRAPHIC_ELEMENTS_HTTP_ENDPOINT|"https://ai.api.nvidia.com/v1/cv/nvidia/nemoretriever-graphic-elements-v1"
253
+ ]
254
+ yolox_infer_protocol: $YOLOX_GRAPHIC_ELEMENTS_INFER_PROTOCOL|"http"
255
+ ocr_endpoints: [
256
+ $OCR_GRPC_ENDPOINT|"",
257
+ $OCR_HTTP_ENDPOINT|"https://ai.api.nvidia.com/v1/cv/baidu/paddleocr"
258
+ ]
259
+ ocr_infer_protocol: $OCR_INFER_PROTOCOL|"http"
260
+ auth_token: $NGC_API_KEY|""
261
+ replicas:
262
+ min_replicas: 0
263
+ max_replicas:
264
+ strategy: "memory_thresholding"
265
+ memory_per_replica_mb: 10000
266
+ static_replicas:
267
+ strategy: "memory_static_global_percent"
268
+ memory_per_replica_mb: 10000
269
+ limit: 6
270
+
271
+ # Post-processing / Mutators
272
+ - name: "image_filter"
273
+ type: "stage"
274
+ phase: 3 # MUTATION
275
+ actor: "nv_ingest.framework.orchestration.ray.stages.mutate.image_filter:ImageFilterStage"
276
+ replicas:
277
+ min_replicas: 0
278
+ max_replicas:
279
+ strategy: "static"
280
+ value: 1
281
+ static_replicas:
282
+ strategy: "static"
283
+ value: 1
284
+
285
+ - name: "image_dedup"
286
+ type: "stage"
287
+ phase: 3 # MUTATION
288
+ actor: "nv_ingest.framework.orchestration.ray.stages.mutate.image_dedup:ImageDedupStage"
289
+ replicas:
290
+ min_replicas: 0
291
+ max_replicas:
292
+ strategy: "static"
293
+ value: 1
294
+ static_replicas:
295
+ strategy: "static"
296
+ value: 1
297
+
298
+ - name: "text_splitter"
299
+ type: "stage"
300
+ phase: 3 # MUTATION
301
+ actor: "nv_ingest.framework.orchestration.ray.stages.transforms.text_splitter:TextSplitterStage"
302
+ config:
303
+ chunk_size: 512
304
+ chunk_overlap: 20
305
+ replicas:
306
+ min_replicas: 0
307
+ max_replicas:
308
+ strategy: "static"
309
+ value: 3
310
+ static_replicas:
311
+ strategy: "static"
312
+ value: 1
313
+
314
+ # Transforms and Synthesis
315
+ - name: "image_caption"
316
+ type: "stage"
317
+ phase: 4 # TRANSFORM
318
+ actor: "nv_ingest.framework.orchestration.ray.stages.transforms.image_caption:ImageCaptionTransformStage"
319
+ config:
320
+ api_key: $NGC_API_KEY|""
321
+ endpoint_url: $VLM_CAPTION_ENDPOINT|"https://integrate.api.nvidia.com/v1/chat/completions"
322
+ model_name: $VLM_CAPTION_MODEL_NAME|"nvidia/llama-3.1-nemotron-nano-vl-8b-v1"
323
+ prompt: "Caption the content of this image:"
324
+ replicas:
325
+ min_replicas: 0
326
+ max_replicas:
327
+ strategy: "static"
328
+ value: 1
329
+ static_replicas:
330
+ strategy: "static"
331
+ value: 1
332
+
333
+ - name: "text_embedder"
334
+ type: "stage"
335
+ phase: 4 # TRANSFORM
336
+ actor: "nv_ingest.framework.orchestration.ray.stages.transforms.text_embed:TextEmbeddingTransformStage"
337
+ config:
338
+ api_key: $NGC_API_KEY|""
339
+ embedding_model: $EMBEDDING_NIM_MODEL_NAME|"nvidia/llama-3.2-nv-embedqa-1b-v2"
340
+ embedding_nim_endpoint: $EMBEDDING_NIM_ENDPOINT|"https://integrate.api.nvidia.com/v1"
341
+ replicas:
342
+ min_replicas: 0
343
+ max_replicas:
344
+ strategy: "static"
345
+ value: 2
346
+ static_replicas:
347
+ strategy: "static"
348
+ value: 1
349
+
350
+ # Storage and Output
351
+ - name: "image_storage"
352
+ type: "stage"
353
+ phase: 5 # RESPONSE
354
+ actor: "nv_ingest.framework.orchestration.ray.stages.storage.image_storage:ImageStorageStage"
355
+ replicas:
356
+ min_replicas: 0
357
+ max_replicas:
358
+ strategy: "static"
359
+ value: 1
360
+ static_replicas:
361
+ strategy: "static"
362
+ value: 1
363
+
364
+ - name: "embedding_storage"
365
+ type: "stage"
366
+ phase: 5 # RESPONSE
367
+ actor: "nv_ingest.framework.orchestration.ray.stages.storage.store_embeddings:EmbeddingStorageStage"
368
+ replicas:
369
+ min_replicas: 0
370
+ max_replicas:
371
+ strategy: "static"
372
+ value: 1
373
+ static_replicas:
374
+ strategy: "static"
375
+ value: 1
376
+
377
+ - name: "broker_response"
378
+ type: "stage"
379
+ phase: 5 # RESPONSE
380
+ actor: "nv_ingest.framework.orchestration.ray.stages.sinks.message_broker_task_sink:MessageBrokerTaskSinkStage"
381
+ config:
382
+ broker_client:
383
+ client_type: "simple"
384
+ host: "localhost"
385
+ port: 7671
386
+ replicas:
387
+ min_replicas: 1
388
+ max_replicas:
389
+ strategy: "static"
390
+ value: 2
391
+ static_replicas:
392
+ strategy: "static"
393
+ value: 1
394
+
395
+ # Telemetry and Drain
396
+ - name: "otel_tracer"
397
+ type: "stage"
398
+ phase: 6 # TELEMETRY
399
+ actor: "nv_ingest.framework.orchestration.ray.stages.telemetry.otel_tracer:OpenTelemetryTracerStage"
400
+ config:
401
+ otel_endpoint: $OTEL_EXPORTER_OTLP_ENDPOINT|"http://localhost:4317"
402
+ replicas:
403
+ min_replicas: 0
404
+ max_replicas:
405
+ strategy: "static"
406
+ value: 1
407
+ static_replicas:
408
+ strategy: "static"
409
+ value: 1
410
+
411
+ - name: "default_drain"
412
+ type: "sink"
413
+ phase: 7 # DRAIN
414
+ actor: "nv_ingest.framework.orchestration.ray.stages.sinks.default_drain:DefaultDrainSink"
415
+ config: {}
416
+ replicas:
417
+ min_replicas: 1
418
+ max_replicas:
419
+ strategy: "static"
420
+ value: 1
421
+ static_replicas:
422
+ strategy: "static"
423
+ value: 1
424
+
425
+ edges:
426
+ # Intake
427
+ - from: "source_stage"
428
+ to: "metadata_injector"
429
+ queue_size: 32
430
+
431
+ # Document Extractors
432
+ - from: "metadata_injector"
433
+ to: "pdf_extractor"
434
+ queue_size: 32
435
+ - from: "pdf_extractor"
436
+ to: "audio_extractor"
437
+ queue_size: 32
438
+ - from: "audio_extractor"
439
+ to: "docx_extractor"
440
+ queue_size: 32
441
+ - from: "docx_extractor"
442
+ to: "pptx_extractor"
443
+ queue_size: 32
444
+ - from: "pptx_extractor"
445
+ to: "image_extractor"
446
+ queue_size: 32
447
+ - from: "image_extractor"
448
+ to: "html_extractor"
449
+ queue_size: 32
450
+ - from: "html_extractor"
451
+ to: "infographic_extractor"
452
+ queue_size: 32
453
+
454
+ # Primitive Extractors
455
+ - from: "infographic_extractor"
456
+ to: "table_extractor"
457
+ queue_size: 32
458
+ - from: "table_extractor"
459
+ to: "chart_extractor"
460
+ queue_size: 32
461
+ - from: "chart_extractor"
462
+ to: "image_filter"
463
+ queue_size: 32
464
+
465
+ # Primitive Mutators
466
+ - from: "image_filter"
467
+ to: "image_dedup"
468
+ queue_size: 32
469
+ - from: "image_dedup"
470
+ to: "text_splitter"
471
+ queue_size: 32
472
+
473
+ # Primitive Transforms
474
+ - from: "text_splitter"
475
+ to: "image_caption"
476
+ queue_size: 32
477
+ - from: "image_caption"
478
+ to: "text_embedder"
479
+ queue_size: 32
480
+ - from: "text_embedder"
481
+ to: "image_storage"
482
+ queue_size: 32
483
+
484
+ # Primitive Storage
485
+ - from: "image_storage"
486
+ to: "embedding_storage"
487
+ queue_size: 32
488
+ - from: "embedding_storage"
489
+ to: "broker_response"
490
+ queue_size: 32
491
+
492
+ # Response and Telemetry
493
+ - from: "broker_response"
494
+ to: "otel_tracer"
495
+ queue_size: 32
496
+ - from: "otel_tracer"
497
+ to: "default_drain"
498
+ queue_size: 32
499
+
500
+ # Pipeline Runtime Configuration
501
+ pipeline:
502
+ disable_dynamic_scaling: $INGEST_DISABLE_DYNAMIC_SCALING|true
503
+ dynamic_memory_threshold: $INGEST_DYNAMIC_MEMORY_THRESHOLD|0.75
504
+ static_memory_threshold: $INGEST_STATIC_MEMORY_THRESHOLD|0.75
505
+ pid_controller:
506
+ kp: $INGEST_DYNAMIC_MEMORY_KP|0.2
507
+ ki: $INGEST_DYNAMIC_MEMORY_KI|0.01
508
+ ema_alpha: $INGEST_DYNAMIC_MEMORY_EMA_ALPHA|0.1
509
+ target_queue_depth: $INGEST_DYNAMIC_MEMORY_TARGET_QUEUE_DEPTH|0
510
+ penalty_factor: $INGEST_DYNAMIC_MEMORY_PENALTY_FACTOR|0.1
511
+ error_boost_factor: $INGEST_DYNAMIC_MEMORY_ERROR_BOOST_FACTOR|1.5
512
+ rcm_memory_safety_buffer_fraction: $INGEST_DYNAMIC_MEMORY_RCM_MEMORY_SAFETY_BUFFER_FRACTION|0.15
513
+ launch_simple_broker: $INGEST_LAUNCH_SIMPLE_BROKER|true
514
+ """