그래프를 사용하여 애플리케이션 구축
하나의 컴파일된 모델 아카이브만 로드하고 실행하려는 경우 Model을 사용합니다. 모델과 노드를 기반으로 애플리케이션을 구축하려는 경우 Graph를 사용합니다. 공개 입력 및 출력을 추가하고, 재사용 가능한 조각을 연결하고, 스트림을 분기하고, 스트림을 결합하고, 애플리케이션을 검증하고, 실제로 실행된 내용을 저장하거나 시각화합니다.
개념적 모델은 의도적으로 작습니다.
| 개념 | 의미 |
|---|---|
Model | 디스크에서 로드된 컴파일된 모델 아카이브입니다. 예를 들어 resnet50.tar.gz 또는 yolov8.tar.gz입니다. |
Node | 하나의 처리 단계입니다. 입력, 출력, 변환, 소스, 싱크, 모델 단계 또는 보조 단계가 될 수 있습니다. |
Graph | 애플리케이션 배선 계획입니다. 어떤 노드/조각이 존재하고 데이터가 어떻게 흐르는지를 정의합니다. |
Run | Graph::build()에서 반환된 실시간 실행 핸들입니다. 입력을 푸시하고, 출력을 가져오고, 메트릭을 수집하고, 중지합니다. |
요약하면:
Graph = what to run
Run = the running instance
더 짧은 경로가 필요할 때 작업 페이지부터 시작하세요.
- 그래프는 그래프 작성 방법을 알려줍니다.
- 그래프 실행는 런타임 라이프사이클, 큐, 측정, 처리량 등을 알려줍니다.
- 노드는 일반 노드와 그룹을 매핑합니다.
- 텐서 및 샘플은 페이로드와 메타데이터를 설명합니다.
대부분의 애플리케이션 코드는 공개 simaai::neat::Graph 및 simaai::neat::Run을 사용해야 합니다. 더 낮은 수준의 구현 네임스페이스를 사용하여 애플리케이션을 구축하지 마세요. 이는 고객 API가 아닙니다.
그래프가 필요한 경우는 언제인가요?
| 목표 | 권장 API |
|---|---|
| 하나의 입력에 대해 하나의 모델을 실행 | Model::run(...) 또는 Model::build(...) |
| 모델 주위에 애플리케이션 입력/출력 경계를 추가 | Graph |
| 사용자 지정 처리 노드를 사용하여 모델을 구성 | Graph::add(...) |
| 여러 앱에서 그래프 조각을 재사용 | Graph 조각을 반환/전달 |
| 여러 입력 또는 출력을 라우팅 | 명명된 nodes::Input(...) / nodes::Output(...)에 connect(...) 추가 |
| 하나의 스트림을 여러 소비자로 분기 | graphs::Branch(...) |
| 여러 스트림을 하나의 논리적 출력으로 결합 | CombinePolicy와 함께 graphs::Combine(...) |
| 실행된 토폴로지와 메트릭을 저장하거나 시각화 | save_run_json(run, ...) |
첫 번째 그래프: 하나의 입력, 하나의 모델, 하나의 출력
이것은 가장 작고 완전한 앱 스타일의 그래프입니다.
#include <neat.h>
#include <iostream>
namespace neat = simaai::neat;
int main() {
neat::Model model("resnet50.tar.gz");
neat::Graph app;
app.add(neat::nodes::Input("image"));
app.add(model);
app.add(neat::nodes::Output("classes"));
neat::Run run = app.build();
neat::Tensor image = /* create or load an image tensor */;
run.push("image", neat::TensorList{image});
std::optional<neat::Sample> result = run.pull("classes", /*timeout_ms=*/1000);
if (result) {
// Consume result->tensors, result->detections, or other Sample metadata.
}
run.stop();
}
줄 단위 설명:
nodes::Input("image")는image라는 이름의 공개 입력 노드를 선언합니다.app.add(model)은 모델의 선택된 경로를 그래프에 삽입합니다.nodes::Output("classes")는classes라는 이름의 공개 출력 노드를 선언합니다.app.build()는 전체 그래프를 검증하고 컴파일한 후Run을 반환합니다.run.push("image", ...)는 데이터를 지정된 입력으로 보냅니다.run.pull("classes", ...)는 지정된 출력에서 데이터를 수신합니다.
Python에서 동일한 구조:
import pyneat
model = pyneat.Model("resnet50.tar.gz")
app = pyneat.Graph()
app.add(pyneat.nodes.input("image"))
app.add(model)
app.add(pyneat.nodes.output("classes"))
run = app.build()
image = ... # Create or load a tensor-compatible object.
run.push("image", [image])
result = run.pull("classes", timeout_ms=1000)
run.stop()
Python의 Run.push(...)는 배치와 유사한 시퀀스를 예상합니다. 개별 텐서/샘플 객체가 아닌 [tensor] 또는 [sample]를 전달하십시오.