Skip to content

Commit df6b73e

Browse files
chinyixiangsiawchencheehookhckoaywanhakim
authored
Enable LLM Traces for sandbox (#51)
* Updates on Getting Started section on README (#16) * Updated Getting Started with GenAIStudio section on README Signed-off-by: siawchen <[email protected]> * Updated README Signed-off-by: siawchen <[email protected]> --------- Signed-off-by: siawchen <[email protected]> Signed-off-by: wwanarif <[email protected]> * add more keywords, and retry another question (#18) Signed-off-by: cheehook <[email protected]> Signed-off-by: wwanarif <[email protected]> * let initial inputs at least match one key for prompt. (#17) Signed-off-by: haoci <[email protected]> Co-authored-by: haoci <[email protected]> Signed-off-by: wwanarif <[email protected]> * moved hardcoded internal dns into configmap (#19) * moved hardcoded internal dns into configmap Signed-off-by: wwanarif <[email protected]> * udpate setup script to apply internal dns configmap Signed-off-by: wwanarif <[email protected]> --------- Signed-off-by: wwanarif <[email protected]> Signed-off-by: wwanarif <[email protected]> * Update manifests and app-backend Dockerfile to resolve missing Gateway dependency (#22) Signed-off-by: wwanarif <[email protected]> Signed-off-by: wwanarif <[email protected]> * add new basic workflow after solving the bug (#20) * add new basic workflow after solving the bug Signed-off-by: cheehook <[email protected]> * change 001 test case to basic workflow Signed-off-by: cheehook <[email protected]> --------- Signed-off-by: cheehook <[email protected]> Signed-off-by: wwanarif <[email protected]> * add keycloak theme under assets (#23) Signed-off-by: wwanarif <[email protected]> Co-authored-by: wwanarif <[email protected]> Signed-off-by: wwanarif <[email protected]> * fix format (#26) Signed-off-by: ZhangJianyu <[email protected]> Co-authored-by: ZhangJianyu <[email protected]> Signed-off-by: wwanarif <[email protected]> * keycloak integration, mysql enablement, megaservice refactor and import sample button (#27) * refactor backend from 'projects' to 'workflows' Signed-off-by: wwanarif <[email protected]> * enabled keycloak and mysql integration Signed-off-by: wwanarif <[email protected]> * update e2e workflow Signed-off-by: wwanarif <[email protected]> * removed gateway dependency Signed-off-by: wwanarif <[email protected]> * fixed @tabler/icons-react version Signed-off-by: wwanarif <[email protected]> * update templates to always pull opea images Signed-off-by: wwanarif <[email protected]> * add button to import sample-workflows in studio-fe and fix UI_FEATURES disabling in app-fe Signed-off-by: wwanarif <[email protected]> * Fix Input and output alignment to follow latest images Signed-off-by: Chin, Yi Xiang <[email protected]> * replace harbor with local registry as the default under onpremise k8 setup Signed-off-by: wwanarif <[email protected]> * enabled remote svc healthcheck before running microsvc Signed-off-by: wwanarif <[email protected]> * integrate mysql playbook under the setup genai studio playbook Signed-off-by: wwanarif <[email protected]> * Fix input for simple llm example Signed-off-by: Chin, Yi Xiang <[email protected]> * temp update mysqlhost in e2e CI Signed-off-by: wwanarif <[email protected]> * update microservice image names Signed-off-by: wwanarif <[email protected]> * udpate retriever variables Signed-off-by: wwanarif <[email protected]> --------- Signed-off-by: wwanarif <[email protected]> Signed-off-by: wwanarif <[email protected]> Signed-off-by: Chin, Yi Xiang <[email protected]> Co-authored-by: wwanarif <[email protected]> Co-authored-by: Chin, Yi Xiang <[email protected]> Signed-off-by: wwanarif <[email protected]> * temp fix for retriever deployment (#29) Signed-off-by: wwanarif <[email protected]> Signed-off-by: wwanarif <[email protected]> * update readme for v1.2 (#31) Signed-off-by: cheehook <[email protected]> Signed-off-by: wwanarif <[email protected]> * update studio fe table UI and updated studio be according to the dataprep refactor (#32) * update worflows table Signed-off-by: Chin, Yi Xiang <[email protected]> * update workflows table namings and moved screenshot from sample-workflows to assets Signed-off-by: wwanarif <[email protected]> * update for latest dataprep refactor Signed-off-by: wwanarif <[email protected]> * update e2e CI workflow Signed-off-by: wwanarif <[email protected]> * update dataprep image name Signed-off-by: wwanarif <[email protected]> * update studio-fe dockerfile Signed-off-by: wwanarif <[email protected]> --------- Signed-off-by: Chin, Yi Xiang <[email protected]> Signed-off-by: wwanarif <[email protected]> Co-authored-by: Chin, Yi Xiang <[email protected]> Signed-off-by: wwanarif <[email protected]> * update docker publish workflow (#33) Signed-off-by: wwanarif <[email protected]> Signed-off-by: wwanarif <[email protected]> * remove HF_TOKEN in configmaps if not NA, updated tgi inputs params and image, increase timeouts (#34) Signed-off-by: wwanarif <[email protected]> Signed-off-by: wwanarif <[email protected]> * fixes for k8s deploy scripts (#35) Signed-off-by: Tsai, Louie <[email protected]> Signed-off-by: wwanarif <[email protected]> * fix embedding svc crashloopback during sandbox launch (#45) * update app-fe dockerfile Signed-off-by: wwanarif <[email protected]> * update embedding templates for env variables Signed-off-by: wwanarif <[email protected]> --------- Signed-off-by: wwanarif <[email protected]> Signed-off-by: wwanarif <[email protected]> * tidying up setup genai studio scripts Signed-off-by: wwanarif <[email protected]> Signed-off-by: wwanarif <[email protected]> * added commands script for registry Signed-off-by: wwanarif <[email protected]> Signed-off-by: wwanarif <[email protected]> * update esbuild version Signed-off-by: wwanarif <[email protected]> Signed-off-by: wwanarif <[email protected]> * update setup genai studio scripts Signed-off-by: wwanarif <[email protected]> Signed-off-by: wwanarif <[email protected]> * [Feat] Add GenAI Studio UI improvement (#48) * [Feat] Add GenAI Studio UI improvement [+] Add hover animation and arrowmark when create new edges [+] Add different icons for nodes based on category [+] Add minimap to render an overview of flow [+] Add Toast notification to warn user for incorrect node connection [+] Add package.json dependencies Co-authored-by: Hao Ruan <[email protected]> Signed-off-by: lianyueh <[email protected]> * Fix handle position err and color Signed-off-by: lianyueh <[email protected]> --------- Signed-off-by: lianyueh <[email protected]> Co-authored-by: lianyueh <[email protected]> Signed-off-by: wwanarif <[email protected]> * Add GitHub Action to check and close stale issues and PRs (#49) Signed-off-by: Sun, Xuehao <[email protected]> Signed-off-by: wwanarif <[email protected]> * initial push for v1.3 Signed-off-by: wwanarif <[email protected]> Signed-off-by: wwanarif <[email protected]> * fixed manifest issues Signed-off-by: wwanarif <[email protected]> Signed-off-by: wwanarif <[email protected]> * Rework canvas 1. multiple output anchor 2. loop back connection 3. remove utilities tab Signed-off-by: cheehook <[email protected]> Signed-off-by: wwanarif <[email protected]> * remove utility tab Signed-off-by: cheehook <[email protected]> Signed-off-by: wwanarif <[email protected]> * add tools scripts for agents Signed-off-by: cheehook <[email protected]> Signed-off-by: wwanarif <[email protected]> * fix output anchors overlapping Signed-off-by: wwanarif <[email protected]> * Revert "fix output anchors overlapping" This reverts commit 794a31a. Signed-off-by: wwanarif <[email protected]> * fix output anchors overlapping Signed-off-by: wwanarif <[email protected]> * update agent nodes Signed-off-by: wwanarif <[email protected]> * Modify app-backend for multiple megaservices and dynamic microservice ports Signed-off-by: chinyixiang <[email protected]> Signed-off-by: wwanarif <[email protected]> * update tools files Signed-off-by: wwanarif <[email protected]> * fix agent nodes Signed-off-by: wwanarif <[email protected]> * enable agent reasoning Signed-off-by: cheehook <[email protected]> Signed-off-by: wwanarif <[email protected]> * fix tool bug and collapsible inference settings Signed-off-by: wwanarif <[email protected]> * fix thinking is popping for non agent Signed-off-by: cheehook <[email protected]> Signed-off-by: wwanarif <[email protected]> * app-backend and templates changes to enable agentqna Signed-off-by: chinyixiang <[email protected]> Signed-off-by: wwanarif <[email protected]> * expose strategy in node configs Signed-off-by: cheehook <[email protected]> Signed-off-by: wwanarif <[email protected]> * enable llmtrace for sandbox Signed-off-by: wwanarif <[email protected]> --------- Signed-off-by: siawchen <[email protected]> Signed-off-by: wwanarif <[email protected]> Signed-off-by: cheehook <[email protected]> Signed-off-by: haoci <[email protected]> Signed-off-by: wwanarif <[email protected]> Signed-off-by: ZhangJianyu <[email protected]> Signed-off-by: Chin, Yi Xiang <[email protected]> Signed-off-by: Tsai, Louie <[email protected]> Signed-off-by: lianyueh <[email protected]> Signed-off-by: Sun, Xuehao <[email protected]> Signed-off-by: chinyixiang <[email protected]> Co-authored-by: siawchen <[email protected]> Co-authored-by: cheehook <[email protected]> Co-authored-by: haoci <[email protected]> Co-authored-by: wanhakim <[email protected]> Co-authored-by: wwanarif <[email protected]> Co-authored-by: Neo Zhang Jianyu <[email protected]> Co-authored-by: ZhangJianyu <[email protected]> Co-authored-by: Louie Tsai <[email protected]> Co-authored-by: Hao Ruan <[email protected]> Co-authored-by: lianyueh <[email protected]> Co-authored-by: Sun, Xuehao <[email protected]>
1 parent 7d829ca commit df6b73e

29 files changed

+1568
-71
lines changed

app-backend/Dockerfile

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,16 @@ RUN pip install --no-cache-dir --upgrade pip==24.3.1 setuptools==75.3.0 && \
2020

2121
COPY ./templates/microservices/* /home/user/templates/microservices/
2222
COPY ./megaservice.py /home/user/megaservice.py
23+
COPY ./orchestrator.py /home/user/GenAIComps/comps/cores/mega/orchestrator.py
2324
COPY config/* /home/user/config/
2425

2526
ENV PYTHONPATH=/home/user/GenAIComps
27+
ENV TELEMETRY_ENDPOINT="http://my-otel-collector-opentelemetry-collector.opentelemetry.svc.cluster.local:4318/v1/traces"
28+
# ENV embedding_tei_langchain_0_port=9007 \
29+
# llm_tgi_0_port=9008 \
30+
# prepare_doc_redis_prep_0_port=9009 \
31+
# reranking_tei_0_port=9010 \
32+
# retriever_redis_0_port=9011
2633

2734
USER user
2835

app-backend/micro_service.py

Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
# Copyright (C) 2024 Intel Corporation
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
import asyncio
5+
import os
6+
from collections import defaultdict, deque
7+
from enum import Enum
8+
from typing import Any, List, Optional, Type
9+
10+
from ..proto.docarray import TextDoc
11+
from .constants import ServiceRoleType, ServiceType
12+
from .http_service import HTTPService
13+
from .logger import CustomLogger
14+
from .utils import check_ports_availability
15+
16+
opea_microservices = {}
17+
18+
logger = CustomLogger("micro_service")
19+
logflag = os.getenv("LOGFLAG", False)
20+
21+
22+
class MicroService(HTTPService):
23+
"""MicroService class to create a microservice."""
24+
25+
def __init__(
26+
self,
27+
name: str = "",
28+
service_role: ServiceRoleType = ServiceRoleType.MICROSERVICE,
29+
service_type: ServiceType = ServiceType.LLM,
30+
protocol: str = "http",
31+
host: str = "localhost",
32+
port: int = 8080,
33+
api_key: str = None,
34+
ssl_keyfile: Optional[str] = None,
35+
ssl_certfile: Optional[str] = None,
36+
endpoint: Optional[str] = "/",
37+
input_datatype: Type[Any] = TextDoc,
38+
output_datatype: Type[Any] = TextDoc,
39+
provider: Optional[str] = None,
40+
provider_endpoint: Optional[str] = None,
41+
use_remote_service: Optional[bool] = False,
42+
description: Optional[str] = None,
43+
dynamic_batching: bool = False,
44+
dynamic_batching_timeout: int = 1,
45+
dynamic_batching_max_batch_size: int = 32,
46+
):
47+
"""Init the microservice."""
48+
self.service_role = service_role
49+
self.service_type = service_type
50+
self.protocol = protocol
51+
self.host = host
52+
self.port = port
53+
self.api_key = api_key
54+
self.endpoint = endpoint
55+
self.input_datatype = input_datatype
56+
self.output_datatype = output_datatype
57+
self.use_remote_service = use_remote_service
58+
self.description = description
59+
self.dynamic_batching = dynamic_batching
60+
self.dynamic_batching_timeout = dynamic_batching_timeout
61+
self.dynamic_batching_max_batch_size = dynamic_batching_max_batch_size
62+
self.uvicorn_kwargs = {}
63+
64+
if ssl_keyfile:
65+
self.uvicorn_kwargs["ssl_keyfile"] = ssl_keyfile
66+
67+
if ssl_certfile:
68+
self.uvicorn_kwargs["ssl_certfile"] = ssl_certfile
69+
70+
if not use_remote_service:
71+
72+
if self.protocol.lower() == "http":
73+
if not (check_ports_availability(self.host, self.port)):
74+
raise RuntimeError(f"port:{self.port}")
75+
76+
self.provider = provider
77+
self.provider_endpoint = provider_endpoint
78+
self.endpoints = []
79+
80+
runtime_args = {
81+
"protocol": self.protocol,
82+
"host": self.host,
83+
"port": self.port,
84+
"title": name,
85+
"description": "OPEA Microservice Infrastructure",
86+
}
87+
88+
super().__init__(uvicorn_kwargs=self.uvicorn_kwargs, runtime_args=runtime_args)
89+
90+
# create a batch request processor loop if using dynamic batching
91+
if self.dynamic_batching:
92+
self.buffer_lock = asyncio.Lock()
93+
self.request_buffer = defaultdict(deque)
94+
self.add_startup_event(self._dynamic_batch_processor())
95+
96+
self._async_setup()
97+
98+
# overwrite name
99+
self.name = f"{name}/{self.__class__.__name__}" if name else self.__class__.__name__
100+
101+
async def _dynamic_batch_processor(self):
102+
if logflag:
103+
logger.info("dynamic batch processor looping...")
104+
while True:
105+
await asyncio.sleep(self.dynamic_batching_timeout)
106+
runtime_batch: dict[Enum, list[dict]] = {} # {ServiceType.Embedding: [{"request": xx, "response": yy}, {}]}
107+
108+
async with self.buffer_lock:
109+
# prepare the runtime batch, access to buffer is locked
110+
if self.request_buffer:
111+
for service_type, request_lst in self.request_buffer.items():
112+
batch = []
113+
# grab min(MAX_BATCH_SIZE, REQUEST_SIZE) requests from buffer
114+
for _ in range(min(self.dynamic_batching_max_batch_size, len(request_lst))):
115+
batch.append(request_lst.popleft())
116+
117+
runtime_batch[service_type] = batch
118+
119+
# Run batched inference on the batch and set results
120+
for service_type, batch in runtime_batch.items():
121+
if not batch:
122+
continue
123+
results = await self.dynamic_batching_infer(service_type, batch)
124+
125+
for req, result in zip(batch, results):
126+
req["response"].set_result(result)
127+
128+
async def dynamic_batching_infer(self, service_type: Enum, batch: list[dict]):
129+
"""Need to implement."""
130+
raise NotImplementedError("Unimplemented dynamic batching inference!")
131+
132+
def _validate_env(self):
133+
"""Check whether to use the microservice locally."""
134+
if self.use_remote_service:
135+
raise Exception(
136+
"Method not allowed for a remote service, please "
137+
"set use_remote_service to False if you want to use a local micro service!"
138+
)
139+
140+
@property
141+
def endpoint_path(self):
142+
if self.api_key:
143+
return f"{self.host}{self.endpoint}"
144+
else:
145+
return f"{self.protocol}://{self.host}:{self.port}{self.endpoint}"
146+
147+
@property
148+
def api_key_value(self):
149+
return self.api_key
150+
151+
152+
def register_microservice(
153+
name: str,
154+
service_role: ServiceRoleType = ServiceRoleType.MICROSERVICE,
155+
service_type: ServiceType = ServiceType.UNDEFINED,
156+
protocol: str = "http",
157+
host: str = "localhost",
158+
port: int = 8080,
159+
ssl_keyfile: Optional[str] = None,
160+
ssl_certfile: Optional[str] = None,
161+
endpoint: Optional[str] = "/",
162+
input_datatype: Type[Any] = TextDoc,
163+
output_datatype: Type[Any] = TextDoc,
164+
provider: Optional[str] = None,
165+
provider_endpoint: Optional[str] = None,
166+
methods: List[str] = ["POST"],
167+
dynamic_batching: bool = False,
168+
dynamic_batching_timeout: int = 1,
169+
dynamic_batching_max_batch_size: int = 32,
170+
):
171+
def decorator(func):
172+
if name not in opea_microservices:
173+
micro_service = MicroService(
174+
name=name,
175+
service_role=service_role,
176+
service_type=service_type,
177+
protocol=protocol,
178+
host=host,
179+
port=port,
180+
ssl_keyfile=ssl_keyfile,
181+
ssl_certfile=ssl_certfile,
182+
endpoint=endpoint,
183+
input_datatype=input_datatype,
184+
output_datatype=output_datatype,
185+
provider=provider,
186+
provider_endpoint=provider_endpoint,
187+
dynamic_batching=dynamic_batching,
188+
dynamic_batching_timeout=dynamic_batching_timeout,
189+
dynamic_batching_max_batch_size=dynamic_batching_max_batch_size,
190+
)
191+
opea_microservices[name] = micro_service
192+
opea_microservices[name].app.router.add_api_route(endpoint, func, methods=methods)
193+
194+
return func
195+
196+
return decorator

app-backend/opea_telemetry.py

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
# Copyright (C) 2024 Intel Corporation
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
import contextlib
5+
import inspect
6+
import os
7+
from functools import wraps
8+
9+
from opentelemetry import trace
10+
from opentelemetry.context.contextvars_context import ContextVarsRuntimeContext
11+
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter as HTTPSpanExporter
12+
from opentelemetry.sdk.resources import SERVICE_NAME, Resource
13+
from opentelemetry.sdk.trace import TracerProvider
14+
from opentelemetry.sdk.trace.export import BatchSpanProcessor
15+
from opentelemetry.sdk.trace.export.in_memory_span_exporter import InMemorySpanExporter
16+
17+
from ..mega.logger import CustomLogger
18+
19+
logger = CustomLogger("OpeaComponent")
20+
21+
22+
def detach_ignore_err(self, token: object) -> None:
23+
"""Resets Context to a previous value.
24+
25+
Args:
26+
token: A reference to a previous Context.
27+
"""
28+
try:
29+
self._current_context.reset(token) # type: ignore
30+
except Exception as e:
31+
pass
32+
33+
34+
# bypass the ValueError that ContextVar context was created in a different Context from StreamingResponse
35+
ContextVarsRuntimeContext.detach = detach_ignore_err
36+
37+
resource = Resource.create({SERVICE_NAME: "opea"})
38+
traceProvider = TracerProvider(resource=resource)
39+
40+
ENABLE_OPEA_TELEMETRY = False
41+
telemetry_endpoint = os.environ.get("TELEMETRY_ENDPOINT")
42+
if telemetry_endpoint is not None:
43+
44+
ENABLE_OPEA_TELEMETRY = True
45+
logger.info(f" Has Telemetry Endpoint : {telemetry_endpoint}")
46+
traceProvider.add_span_processor(BatchSpanProcessor(HTTPSpanExporter(endpoint=telemetry_endpoint)))
47+
48+
in_memory_exporter = InMemorySpanExporter()
49+
traceProvider.add_span_processor(BatchSpanProcessor(in_memory_exporter))
50+
trace.set_tracer_provider(traceProvider)
51+
52+
tracer = trace.get_tracer(__name__)
53+
54+
55+
def opea_telemetry(func):
56+
if inspect.iscoroutinefunction(func):
57+
58+
@wraps(func)
59+
async def wrapper(*args, **kwargs):
60+
with tracer.start_as_current_span(func.__name__) if ENABLE_OPEA_TELEMETRY else contextlib.nullcontext():
61+
res = await func(*args, **kwargs)
62+
return res
63+
64+
else:
65+
66+
@wraps(func)
67+
def wrapper(*args, **kwargs):
68+
with tracer.start_as_current_span(func.__name__) if ENABLE_OPEA_TELEMETRY else contextlib.nullcontext():
69+
res = func(*args, **kwargs)
70+
return res
71+
72+
return wrapper

0 commit comments

Comments
 (0)