

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

# 계보 엔터티 쿼리
<a name="querying-lineage-entities"></a>

Amazon SageMaker AI는 계보 엔터티를 사용할 때 자동으로 계보 엔터티의 그래프를 생성합니다. 이 데이터를 쿼리하여 다양한 질문에 답할 수 있습니다. 다음은 SDK for Python에서 이 데이터를 쿼리하는 방법에 대한 지침을 제공합니다.

Amazon SageMaker Studio에서 등록된 모델 계보를 보는 방법에 대한 자세한 내용은 [Studio에서 모델 계보 세부 정보 보기](model-registry-lineage-view-studio.md) 섹션을 참조하세요.

계보 엔터티를 쿼리하여 다음을 수행할 수 있습니다.
+ 모델 생성에 사용된 모든 데이터세트를 검색합니다.
+ 엔드포인트 생성에 들어간 모든 작업을 검색합니다.
+ 데이터세트를 사용하는 모든 모델을 검색합니다.
+ 모델을 사용하는 모든 엔드포인트를 검색합니다.
+ 특정 데이터세트에서 파생된 엔드포인트를 검색합니다.
+ 훈련 작업을 생성한 파이프라인 실행을 검색합니다.
+ 조사, 거버넌스 및 재현성을 위해 엔터티 간의 관계를 검색합니다.
+ 아티팩트를 사용하는 모든 다운스트림 시험을 검색합니다.
+ 아티팩트를 사용하는 모든 업스트림 시험을 검색합니다.
+ 제공된 S3 uri를 사용하는 아티팩트 목록을 검색합니다.
+ 데이터세트 아티팩트를 사용하는 업스트림 아티팩트를 검색합니다.
+ 데이터세트 아티팩트를 사용하는 다운스트림 아티팩트를 검색합니다.
+ 이미지 아티팩트를 사용하는 데이터세트를 검색합니다.
+ 컨텍스트를 사용하는 작업을 검색합니다.
+ 엔드포인트를 사용하는 처리 작업을 검색합니다.
+ 엔드포인트를 사용하는 변환 작업을 검색합니다.
+ 엔드포인트를 사용하는 시험 구성 요소를 검색합니다.
+ 모델 패키지 그룹과 연결된 파이프라인 실행의 ARN을 검색합니다.
+ 작업을 사용하는 모든 아티팩트를 검색합니다.
+ 모델 패키지 승인 작업을 사용하는 모든 업스트림 데이터세트를 검색합니다.
+ 모델 패키지 승인 작업에서 모델 패키지를 검색합니다.
+ 엔드포인트를 사용하는 다운스트림 엔드포인트 컨텍스트를 검색합니다.
+ 시험 구성 요소와 관련된 파이프라인 실행에 대한 ARN을 검색합니다.
+ 시험 구성 요소를 사용하는 데이터세트를 검색합니다.
+ 시험 구성 요소를 사용하는 모델을 검색합니다.
+ 시각화를 위해 계보를 탐색합니다.

**제한 사항**
+ 다음 리전에서 계보 쿼리를 사용할 수 없습니다.
  + 아프리카(케이프타운) – af-south
  + 아시아 태평양(자카르타) – ap-southeast-3
  + 아시아 태평양(오사카) – ap-northeast-3
  + 유럽(밀라노) – eu-south-1
  + 유럽(스페인) – eu-south-2
  + 이스라엘(텔아비브) – il-central-1
+ 현재 검색할 수 있는 관계의 최대 깊이는 10으로 제한됩니다.
+ 필터링은 마지막 수정 날짜, 생성 날짜, 유형 및 계보 엔터티 유형과 같은 속성으로 제한됩니다.

**Topics**
+ [계보 엔터티 쿼리 시작하기](#querying-lineage-entities-getting-started)

## 계보 엔터티 쿼리 시작하기
<a name="querying-lineage-entities-getting-started"></a>

가장 쉬운 방법은 다음 중 하나를 이용하는 것입니다.
+ [Amazon SageMaker AI SDK for Python](https://github.com/aws/sagemaker-python-sdk/blob/master/src/sagemaker/lineage/artifact.py#L397)에는 많은 일반 사용 사례가 정의되어 있습니다.
+ SageMaker AI 계보 API를 사용하여 계보 그래프에서 관계를 쿼리하는 방법을 보여주는 노트북은 [sagemaker-lineage-multihop-queries.ipynb](https://github.com/aws/amazon-sagemaker-examples/blob/master/sagemaker-lineage/sagemaker-lineage-multihop-queries.ipynb)를 참조하세요.

다음 예시는 `LineageQuery`및 `LineageFilter`API를 사용하여 계보 그래프에 대한 질문에 답하는 쿼리를 구성하고 몇 가지 사용 사례에서 엔터티 관계를 추출하는 방법을 보여줍니다.

**Example `LineageQuery` API를 사용하여 엔터티 연결 찾기**  

```
from sagemaker.lineage.context import Context, EndpointContext
from sagemaker.lineage.action import Action
from sagemaker.lineage.association import Association
from sagemaker.lineage.artifact import Artifact, ModelArtifact, DatasetArtifact

from sagemaker.lineage.query import (
    LineageQuery,
    LineageFilter,
    LineageSourceEnum,
    LineageEntityEnum,
    LineageQueryDirectionEnum,
)
# Find the endpoint context and model artifact that should be used for the lineage queries.

contexts = Context.list(source_uri=endpoint_arn)
context_name = list(contexts)[0].context_name
endpoint_context = EndpointContext.load(context_name=context_name)
```

**Example 엔드포인트와 관련된 모든 데이터세트 찾기**  

```
# Define the LineageFilter to look for entities of type `ARTIFACT` and the source of type `DATASET`.

query_filter = LineageFilter(
    entities=[LineageEntityEnum.ARTIFACT], sources=[LineageSourceEnum.DATASET]
)

# Providing this `LineageFilter` to the `LineageQuery` constructs a query that traverses through the given context `endpoint_context`
# and find all datasets.

query_result = LineageQuery(sagemaker_session).query(
    start_arns=[endpoint_context.context_arn],
    query_filter=query_filter,
    direction=LineageQueryDirectionEnum.ASCENDANTS,
    include_edges=False,
)

# Parse through the query results to get the lineage objects corresponding to the datasets
dataset_artifacts = []
for vertex in query_result.vertices:
    dataset_artifacts.append(vertex.to_lineage_object().source.source_uri)

pp.pprint(dataset_artifacts)
```

**Example 엔드포인트와 관련된 모델 찾기**  

```
# Define the LineageFilter to look for entities of type `ARTIFACT` and the source of type `MODEL`.

query_filter = LineageFilter(
    entities=[LineageEntityEnum.ARTIFACT], sources=[LineageSourceEnum.MODEL]
)

# Providing this `LineageFilter` to the `LineageQuery` constructs a query that traverses through the given context `endpoint_context`
# and find all datasets.

query_result = LineageQuery(sagemaker_session).query(
    start_arns=[endpoint_context.context_arn],
    query_filter=query_filter,
    direction=LineageQueryDirectionEnum.ASCENDANTS,
    include_edges=False,
)

# Parse through the query results to get the lineage objects corresponding to the model
model_artifacts = []
for vertex in query_result.vertices:
    model_artifacts.append(vertex.to_lineage_object().source.source_uri)

# The results of the `LineageQuery` API call return the ARN of the model deployed to the endpoint along with
# the S3 URI to the model.tar.gz file associated with the model
pp.pprint(model_artifacts)
```

**Example 엔드포인트와 관련된 시험 구성 요소 찾기**  

```
# Define the LineageFilter to look for entities of type `TRIAL_COMPONENT` and the source of type `TRAINING_JOB`.

query_filter = LineageFilter(
    entities=[LineageEntityEnum.TRIAL_COMPONENT],
    sources=[LineageSourceEnum.TRAINING_JOB],
)

# Providing this `LineageFilter` to the `LineageQuery` constructs a query that traverses through the given context `endpoint_context`
# and find all datasets.

query_result = LineageQuery(sagemaker_session).query(
    start_arns=[endpoint_context.context_arn],
    query_filter=query_filter,
    direction=LineageQueryDirectionEnum.ASCENDANTS,
    include_edges=False,
)

# Parse through the query results to get the ARNs of the training jobs associated with this Endpoint
trial_components = []
for vertex in query_result.vertices:
    trial_components.append(vertex.arn)

pp.pprint(trial_components)
```

**Example 계보의 초점 변경**  
계보의 초점이 바뀌는 다른 `start_arns`을 포함하도록 `LineageQuery`를 수정할 수 있습니다. 또한 `LineageFilter`는 여러 소스와 엔터티를 사용하여 쿼리 범위를 확장할 수 있습니다.  
다음에서는 모델을 계보 초점으로 사용하여 관련 엔드포인트와 데이터세트를 찾습니다.  

```
# Get the ModelArtifact

model_artifact_summary = list(Artifact.list(source_uri=model_package_arn))[0]
model_artifact = ModelArtifact.load(artifact_arn=model_artifact_summary.artifact_arn)
query_filter = LineageFilter(
    entities=[LineageEntityEnum.ARTIFACT],
    sources=[LineageSourceEnum.ENDPOINT, LineageSourceEnum.DATASET],
)

query_result = LineageQuery(sagemaker_session).query(
    start_arns=[model_artifact.artifact_arn],  # Model is the starting artifact
    query_filter=query_filter,
    # Find all the entities that descend from the model, i.e. the endpoint
    direction=LineageQueryDirectionEnum.DESCENDANTS,
    include_edges=False,
)

associations = []
for vertex in query_result.vertices:
    associations.append(vertex.to_lineage_object().source.source_uri)

query_result = LineageQuery(sagemaker_session).query(
    start_arns=[model_artifact.artifact_arn],  # Model is the starting artifact
    query_filter=query_filter,
    # Find all the entities that ascend from the model, i.e. the datasets
    direction=LineageQueryDirectionEnum.ASCENDANTS,
    include_edges=False,
)

for vertex in query_result.vertices:
    associations.append(vertex.to_lineage_object().source.source_uri)

pp.pprint(associations)
```

**Example `LineageQueryDirectionEnum.BOTH`를 사용하여 상위 및 하위 관계 찾기**  
방향이 `BOTH`로 설정된 경우 쿼리는 그래프를 탐색하여 상위 및 하위 관계를 찾습니다. 이 순회는 시작 노드뿐만 아니라 방문한 각 노드에서도 발생합니다. 예를 들어, 훈련 작업을 두 번 실행하고 훈련 작업에서 생성된 두 모델을 모두 엔드포인트에 배포한 경우 방향이 `BOTH`로 설정된 쿼리 결과에 두 엔드포인트가 모두 표시됩니다. 이는 동일한 이미지가 모델 훈련 및 배포에 사용되기 때문입니다. 이미지는 모델에 공통적이므로, `start_arn`과 양쪽 엔드포인트가 쿼리 결과에 나타납니다.  

```
query_filter = LineageFilter(
    entities=[LineageEntityEnum.ARTIFACT],
    sources=[LineageSourceEnum.ENDPOINT, LineageSourceEnum.DATASET],
)

query_result = LineageQuery(sagemaker_session).query(
    start_arns=[model_artifact.artifact_arn],  # Model is the starting artifact
    query_filter=query_filter,
    # This specifies that the query should look for associations both ascending and descending for the start
    direction=LineageQueryDirectionEnum.BOTH,
    include_edges=False,
)

associations = []
for vertex in query_result.vertices:
    associations.append(vertex.to_lineage_object().source.source_uri)

pp.pprint(associations)
```

**Example `LineageQuery` - `ASCENDANTS`vs. `DESCENDANTS`방향**  
계보 그래프의 방향을 이해하려면 다음 엔터티 관계 그래프(데이터세트 -> 훈련 작업 -> 모델 -> 엔드포인트)를 참고하세요.  
엔드포인트는 모델의 하위이고, 모델은 데이터세트의 하위입니다. 마찬가지로, 모델은 엔드포인트의 상위입니다. `direction` 파라미터를 사용하여 `start_arns`에서 엔터티의 하위 항목이나 상위 항목인 엔터티를 반환할지 여부를 지정할 수 있습니다. `start_arns`에 모델이 포함되어 있고 방향이 `DESCENDANTS`인 경우 쿼리는 엔드포인트를 반환합니다. 방향이 `ASCENDANTS`인 경우 쿼리는 데이터세트를 반환합니다.  

```
# In this example, we'll look at the impact of specifying the direction as ASCENDANT or DESCENDANT in a `LineageQuery`.

query_filter = LineageFilter(
    entities=[LineageEntityEnum.ARTIFACT],
    sources=[
        LineageSourceEnum.ENDPOINT,
        LineageSourceEnum.MODEL,
        LineageSourceEnum.DATASET,
        LineageSourceEnum.TRAINING_JOB,
    ],
)

query_result = LineageQuery(sagemaker_session).query(
    start_arns=[model_artifact.artifact_arn],
    query_filter=query_filter,
    direction=LineageQueryDirectionEnum.ASCENDANTS,
    include_edges=False,
)

ascendant_artifacts = []

# The lineage entity returned for the Training Job is a TrialComponent which can't be converted to a
# lineage object using the method `to_lineage_object()` so we extract the TrialComponent ARN.
for vertex in query_result.vertices:
    try:
        ascendant_artifacts.append(vertex.to_lineage_object().source.source_uri)
    except:
        ascendant_artifacts.append(vertex.arn)

print("Ascendant artifacts : ")
pp.pprint(ascendant_artifacts)

query_result = LineageQuery(sagemaker_session).query(
    start_arns=[model_artifact.artifact_arn],
    query_filter=query_filter,
    direction=LineageQueryDirectionEnum.DESCENDANTS,
    include_edges=False,
)

descendant_artifacts = []
for vertex in query_result.vertices:
    try:
        descendant_artifacts.append(vertex.to_lineage_object().source.source_uri)
    except:
        # Handling TrialComponents.
        descendant_artifacts.append(vertex.arn)

print("Descendant artifacts : ")
pp.pprint(descendant_artifacts)
```

**Example 계보 쿼리를 더 쉽게 만드는 SDK 도우미 함수**  
클래스 `EndpointContext`, `ModelArtifact`, 및 `DatasetArtifact`에는 특정 계보 쿼리를 더 쉽게 활용할 수 있도록 `LineageQuery`API에 래퍼 역할을 하는 도우미 함수가 포함되어 있습니다. 다음 예시에서는 이러한 도우미 함수를 사용하는 방법을 보여 줍니다.  

```
# Find all the datasets associated with this endpoint

datasets = []
dataset_artifacts = endpoint_context.dataset_artifacts()
for dataset in dataset_artifacts:
    datasets.append(dataset.source.source_uri)
print("Datasets : ", datasets)

# Find the training jobs associated with the endpoint
training_job_artifacts = endpoint_context.training_job_arns()
training_jobs = []
for training_job in training_job_artifacts:
    training_jobs.append(training_job)
print("Training Jobs : ", training_jobs)

# Get the ARN for the pipeline execution associated with this endpoint (if any)
pipeline_executions = endpoint_context.pipeline_execution_arn()
if pipeline_executions:
    for pipeline in pipelines_executions:
        print(pipeline)

# Here we use the `ModelArtifact` class to find all the datasets and endpoints associated with the model

dataset_artifacts = model_artifact.dataset_artifacts()
endpoint_contexts = model_artifact.endpoint_contexts()

datasets = [dataset.source.source_uri for dataset in dataset_artifacts]
endpoints = [endpoint.source.source_uri for endpoint in endpoint_contexts]

print("Datasets associated with this model : ")
pp.pprint(datasets)

print("Endpoints associated with this model : ")
pp.pprint(endpoints)

# Here we use the `DatasetArtifact` class to find all the endpoints hosting models that were trained with a particular dataset
# Find the artifact associated with the dataset

dataset_artifact_arn = list(Artifact.list(source_uri=training_data))[0].artifact_arn
dataset_artifact = DatasetArtifact.load(artifact_arn=dataset_artifact_arn)

# Find the endpoints that used this training dataset
endpoint_contexts = dataset_artifact.endpoint_contexts()
endpoints = [endpoint.source.source_uri for endpoint in endpoint_contexts]

print("Endpoints associated with the training dataset {}".format(training_data))
pp.pprint(endpoints)
```

**Example 계보 그래프 시각화 가져오기**  
샘플 노트북 [visualizer.py](https://github.com/aws/amazon-sagemaker-examples/blob/master/sagemaker-lineage/visualizer.py)에는 계보 그래프를 그리는 데 도움이 되는 도우미 클래스 `Visualizer`가 제공됩니다. 쿼리 응답이 렌더링되면 `StartArns`의 계보 관계가 표시된 그래프가 표시됩니다. `StartArns`에서 시각화는 `query_lineage`API 작업에서 반환된 다른 계보 엔터티와의 관계를 보여줍니다.  

```
# Graph APIs
# Here we use the boto3 `query_lineage` API to generate the query response to plot.

from visualizer import Visualizer

query_response = sm_client.query_lineage(
    StartArns=[endpoint_context.context_arn], Direction="Ascendants", IncludeEdges=True
)

viz = Visualizer()
viz.render(query_response, "Endpoint")
        
        query_response = sm_client.query_lineage(
    StartArns=[model_artifact.artifact_arn], Direction="Ascendants", IncludeEdges=True
)
viz.render(query_response, "Model")
```