VHLO 언어

VHLO 언어란 무엇인가요?

VHLO (버전이 지정된 StableHLO) 언어는 직렬화 및 안정성을 위해 사용됩니다. 개별 프로그램 요소의 버전을 관리하여 특정 시점에서 StableHLO 언어의 스냅샷을 제공합니다.

VHLO는 버전이 지정된 작업, 유형, 속성이 포함된 추가 전용 언어입니다. 즉, 기능이 언어에 추가되면 시맨틱에 영향을 미치는 어떤 방식으로도 수정할 수 없습니다.

작업, 유형 또는 속성을 변경하려면 언어에 새 버전을 추가해야 합니다. 예를 들어 가상의 my_op가 0.9.0에서는 StableHLO에 추가되었지만 0.11.0에서는 변경된 경우 VHLO에서는 다음과 같이 됩니다.

// This represents the StableHLO version of the op from 0.9.0 -> 0.10.0
// Both the lower and the upper bound of versions are inclusive
def VHLO_MyOpV1 : VHLO_Op<"my_op_v1", "0.9.0", "0.10.0"> {
  let arguments = (ins
    VHLO_AnyType:$operand
  );
  let results = (outs VHLO_AnyType:$result);
}

// This represents the StableHLO version of the op from 0.11.0 -> current
def VHLO_MyOpV2 : VHLO_Op<"my_op_v2", "0.11.0", "current"> {
  let arguments = (ins
    VHLO_AnyType:$operand,
    VHLO_AnyAttr:$attr  // New attribute added to StableHLO in 0.11.0
  );
  let results = (outs VHLO_AnyType:$result);
}

StableHLO 언어에는 최신 버전의 작업만 있습니다. 실행 중인 예에서 v0.11.0의 StableHLO 언어에는 operandattr가 있는 StableHLO_MyOp만 있는 반면 VHLO는 작업 발전의 각 단계를 캡처합니다.

VHLO가 유용한 이유

버전이 지정된 언어를 사용하면 이전 버전의 StableHLO 작업 세트를 타겟팅할 수 있습니다. 이는 VHLO 언어 내 작업 간 변환의 이후 버전과의 호환성을 캡슐화합니다.

향후 호환성: 향후 호환성은 VHLO로 변환하고 작업을 대상 버전으로 다운그레이드함으로써 제공됩니다. VHLO 프로그램의 모든 연산/유형/어터를 대상 버전으로 다운그레이드할 수 있는 경우, 대상 버전 이상의 버전을 실행하는 소비자에서는 역직렬화가 가능하고 StableHLO로 전환될 수 있습니다. 이는 VHLO에 해당 시점의 명령 세트 스냅샷이 있기 때문입니다.

향후 호환성 이미지

이전 버전의 opset에 없는 작업이나 기능이 사용되는 경우 이 다운그레이드 변환은 실패합니다. 즉, 이후 버전과의 호환성은 런타임이 아닌 생산자에서 검색됩니다.

이전 버전과의 호환성: 필요한 경우 VHLO 작업을 최신 버전으로 업그레이드한 다음 작업을 다시 StableHLO로 변환하면 이전 버전과의 호환성이 제공됩니다. 호환성 기간 내의 모든 VHLO 프로그램은 StableHLO로 업그레이드할 수 있습니다. 즉, 서로 다른 버전의 소비자가 동일한 VHLO 페이로드를 이전 버전에서 역직렬화할 수 있습니다.

이전 버전과의 호환성 이미지

무엇보다도 VHLO는 직렬화 뒤에서 추상화됩니다. 즉, ML 프레임워크 (생산자)는 StableHLO 작업만 타겟팅하면 되고 컴파일러 백엔드 (소비자)는 최신 버전인 StableHLO 작업 세트만 지원해야 합니다. VHLO와의 변환은 StableHLO 저장소에 유지관리된 기계를 사용하여 처리됩니다.

MLIR 바이트 코드 형식 버전

이후 버전과의 호환성을 유지하기 위해 StableHLO 버전에는 연결된 MLIR 바이트 코드 형식 버전이 있습니다. 또한 최신 버전의 StableHLO는 최신 버전의 MLIR 바이트 코드 형식을 사용합니다. MLIR 바이트 코드 형식 버전이 증가하면 StableHLO의 다음 출시에서 부 버전을 늘리고 최신 MLIR 바이트 코드 형식 버전을 사용하도록 Version.cpp를 업데이트합니다.

MLIR 바이트 코드 형식과 StableHLO에서 이를 사용하는 근거에 관한 자세한 내용은 bytecode.md를 참고하세요.

호환되지 않는 변경사항 적용

호환성에 영향을 미치는 모든 변경사항은 RFC 프로세스를 거쳐야 합니다. 여기에는 기능 추가, 지원 중단, 이름 변경이 포함됩니다. RFC가 승인되면 다음과 같은 참여 가이드라인이 제공됩니다.

Version.h에서 버전 번호를 범프합니다.

VHLO 작업, 속성, 유형 또는 변환을 업데이트하기 전에 Version.h에서 부 버전 번호를 높입니다. 새로 추가된 VHLO 기능은 이 상위 버전을 사용합니다. 예를 들어 0.10.0 --> 0.11.0를 누른 후 VhloOps.td의 새 작업은 다음을 사용합니다.

VHLO_Op<"abs_v2", "0.11.0", "current">

필수 VHLO 구현 및 전환 추가

새 기능을 통합하는 데 필요한 정확한 코드는 다양하지만 대부분의 경우 다음 사항이 변경됩니다.

호환성 관련 제출의 최근 예는 FP8 유형 두 개를 추가하고 #1379에서 VHLO에서 구현한 것이었습니다.

단위 테스트 추가 / 업데이트

호환되지 않는 변경사항의 기여자가 기능의 양성 및 음성 단위 테스트와 호환성 단위 테스트를 모두 담당합니다.

호환성 단위 테스트에는 stablehlo_legalize_to_vhlo.mlir를 업데이트하여 최신 버전의 VHLO로 StableHLO를 왕복하는 것은 물론, 이후 버전과의 추가 호환성 테스트가 필요합니다.

몇 가지 예를 살펴보면 다음과 같습니다.

버전이 지정된 직렬화 테스트 추가

stablehlo_legalize_to_vhlo.mlir에 테스트 포인트를 추가한 후 .0_X_0.mlir.bc 확장자를 가진 해당 파일의 바이트 코드 버전과 함께 다음과 같이 stablehlo_legalize_to_vhlo.0_X_0.mlir이라는 파일의 버전이 지정된 사본을 만듭니다. 향후 및 하위 호환성 테스트를 위해 적절한 FileCheck 줄을 추가합니다.

$ export TARGET_VERSION=0.X.0
$ export TARGET_FILENAME=${TARGET_VERSION//./_}
$ cp stablehlo/tests/stablehlo_legalize_to_vhlo.mlir stablehlo/tests/stablehlo_legalize_to_vhlo.$TARGET_FILENAME.mlir
$ build/bin/stablehlo-translate --serialize --target=$TARGET_VERSION --strip-debuginfo stablehlo/tests/stablehlo_legalize_to_vhlo.$TARGET_FILENAME.mlir > stablehlo/tests/stablehlo_legalize_to_vhlo.$TARGET_FILENAME.mlir.bc

# Replace RUN commands in stablehlo/tests/stablehlo_legalize_to_vhlo.0_X_0.mlir with the following for 0.X.0:
// RUN: stablehlo-opt --mlir-print-op-generic %s.bc | FileCheck %s
// RUN: stablehlo-translate --deserialize %s.bc | stablehlo-translate --serialize --target=0.X.0 | stablehlo-opt --mlir-print-op-generic | FileCheck %s
// RUN: diff <(stablehlo-translate --deserialize %s.bc | stablehlo-opt) <(stablehlo-opt --strip-debuginfo %s)
// RUN: diff %s.bc <(stablehlo-translate --serialize --target=0.X.0 --strip-debuginfo %s)

#1430의 버전이 지정된 테스트 예