StableHLO의 양자화 유형
양자화는 부동 소수점 숫자 (원래 모델에 사용된 숫자와 같음)를 정밀도가 낮은 정수로 변환하여 머신러닝 모델을 최적화하는 기법입니다. 이렇게 하면 메모리 사용량이 줄고 계산 속도가 빨라져 리소스가 제한된 기기에 모델을 배포할 때 더 효율적입니다.
StableHLO 양자화는 LiteRT 양자화 사양을 따르며, 텐서별 양자화와 축별 양자화를 모두 지원하는 균일한 양자화 스키마를 사용합니다. MLIR의 Quant 다이얼로그에서 유형 표현식을 상속하여 양자화된 데이터 유형을 나타내는 표준화된 방법을 제공합니다.
균일 양자화는 균일한 단계 크기를 사용하여 부동 소수점 값을 정수에 매핑하므로 균등하게 간격이 지정된 양자화된 값이 생성됩니다. 이는 두 가지 주요 양자화 매개변수를 사용하는 어파인 관계를 통해 달성됩니다.
균일 양자화는 부동 소수점 수를 균등하게 배치된 정수에 매핑하여 부동 소수점 수의 표현을 단순화합니다. 이 매핑은 스케일과 영점이라는 두 가지 주요 매개변수를 사용하는 아핀 변환을 통해 이루어집니다. 스케일은 연속 양자화 값 사이의 단계 크기를 결정합니다. 스케일이 작을수록 양자화된 값이 더 가까워집니다. 영점은 원래 부동 소수점 공간에서 0을 나타내는 정수 값을 정의합니다.
균일 양자화에서 원래 부동 소수점 값 (real_value)과 양자화된 정수 값 (quantized_value) 간의 관계는 다음과 같습니다.
real_value = scale * (quantized_value - zero_point)
텐서별 양자화
텐서별 양자화에서는 텐서 내의 모든 값에 단일 스케일과 0점이 사용됩니다. 텐서별 양자화 유형은 StableHLO에서 다음과 같이 표현됩니다.
quant.uniform scale:zero_point> 예: !quant.uniform<i8:f32, 0.01:50>
이는 0.01 스케일과 50 제로 포인트를 사용하여 32비트 부동 소수점 숫자 (f32)를 저장하는 데 사용되는 8비트 정수 (i8)를 나타냅니다.
축별 양자화
축별 양자화는 텐서별 양자화에 비해 더 세분화된 접근 방식을 제공합니다. 전체 텐서에 단일 스케일과 0점을 사용하는 대신 축별 양자화는 텐서의 특정 차원 quantized_dimension을 따라 슬라이스에 별도의 스케일과 0점을 할당합니다. 이는 다양한 측정기준에서 값이 크게 달라 정보와 정확도를 더 잘 보존할 수 있는 경우에 특히 유용합니다.
크기가 [4, 3, 2]인 텐서 t를 고려해 보세요. 두 번째 차원(quantized_dimension = 1)을 따라 이 텐서를 양자화합니다. 즉, 두 번째 차원의 크기가 3이므로 각각 자체 스케일과 0점을 갖는 세 개의 슬라이스가 있습니다.
t[:, 0, :]: This slice gets scale[0] and zero_point[0].
t[:, 1, :]: This slice gets scale[1] and zero_point[1].
t[:, 2, :]: This slice gets scale[2] and zero_point[2].
StableHLO에서 축별 양자화 유형은 다음과 같이 표현됩니다.
quant.uniform {scale0:zero_point0, scale1:zero_point1, ...}> 여기서 scale:zero_point의 길이는 포함된 텐서의 quantized_dimension를 따라 있는 슬라이스 수와 일치합니다.
예: tensor<4x3x2x!quant.uniform<i8:f32:1, {0.2:20, 0.1:10, 0.3:30}>>
StableHLO의 양자화 패스
StableHLO는 양자화와 관련된 다양한 변환과 최적화를 허용하는 여러 컴파일러 패스를 제공하므로 양자화된 모델을 처리하는 방식을 유연하게 지정할 수 있습니다. 이러한 패스는 다음과 같습니다.
stablehlo-legalize-qdq-to-quantized-op
이 패스는 양자화된 모델의 일반적인 패턴인 양자화 해제 작업과 부동 소수점 작업, 마지막으로 양자화 작업을 단일 양자화 작업으로 융합합니다. 세부정보
stablehlo-legalize-quantized-op-to-qdq
이 패스는 이전 패스와 반대 작업을 실행합니다. 양자화된 작업을 역양자화, 부동 소수점 연산, 양자화 연산의 동등한 시퀀스로 분해합니다. 세부정보
stablehlo-legalize-quant-to-math
이 패스는 양자화된 유형의 StableHLO 작업을 정수 유형의 동등한 작업으로 변환합니다. 표준 수학 연산을 사용하여 양자화 산술을 구현합니다. 이 분해는 양자화를 기본적으로 지원하지 않지만 양자화 산술을 사용하여 양자화된 모델의 시맨틱을 표현할 수 있는 시스템에 유용합니다. 세부정보
stablehlo-quant-legalize-to-tosa-rescale
StableHLO는 양자화된 작업을 TOSA 다이얼로그의 해당 표현으로 합법화하는 기능을 제공합니다. 이 합법화는 StableHLO와 TOSA 간의 호환성과 상호 운용성을 촉진합니다. 이 패스는 전략적으로 StableHLO 양자화 작업을 StableHLO 및 TOSA 작업의 조합으로 변환하며, TOSA 다이어렉트는 주로 rescale 작업에 사용됩니다. tosa.rescale 작업은 양자화된 값의 스케일과 0점을 조정하는 데 중요한 역할을 하며, TOSA 프레임워크 내에서 양자화된 데이터를 정확하게 표현할 수 있도록 지원합니다.
세부정보
tosa-rescale-legalize-to-stablehlo
이 패스는 TOSA rescale 작업을 StableHLO 기본 수학 작업으로 다시 작성합니다. 이 패스의 주요 사용 사례 중 하나는 StableHLO 인터프리터가 TOSA rescale 작업이 포함된 프로그램을 평가할 수 있도록 하는 것입니다. 세부정보
양자화된 프로그램 평가
StableHLO 참조 인터프리터는 양자화된 연산이 포함된 프로그램을 효율적으로 실행할 수 있습니다. 이를 위해 먼저 정수 연산만 사용하는 동등한 표현으로 프로그램을 낮춥니다. 이 하위 단계 프로세스에는 해석 전에 프로그램을 변환하는 일련의 컴파일러 패스가 포함됩니다.
기본적으로 인터프리터는 stablehlo-legalize-quant-to-math 패스를 활용하여 양자화된 작업을 해당 정수 산술 구현으로 변환합니다. 이 패스에서는 스케일 곱셈/나눗셈과 0점 추가를 처리하기 위한 CHLO 브로드캐스트 작업을 도입합니다. StableHLO 인터프리터와의 호환성을 보장하기 위해 이러한 CHLO 작업은 StableHLO 작업으로 합법화됩니다. 이렇게 하면 일련의 정규화 패스를 사용하여 이후에 정규화되고 최적화되는 모양 관련 작업이 도입됩니다.
이 하위 변환 프로세스에 포함된 전체 패스 시퀀스는 다음과 같습니다.
stablehlo-legalize-quant-to-math
chlo-legalize-to-stablehlo
canonicalize
shape-legalize-to-stablehlo
stablehlo-canonicalize-dynamism
양자화된 테스트 사례
StableHLO는 양자화된 작업의 정확성과 동작을 검증하기 위한 포괄적인 양자화 테스트 사례 모음을 제공합니다. 이러한 테스트 사례는 양자화된 시나리오에서 다양한 StableHLO 작업을 다루는 단위 테스트 역할을 합니다.
양자화된 테스트 사례의 일반적인 예는 다음과 같습니다.
func.func @main() -> tensor<11xf32> {
%operand_0 = stablehlo.constant dense<...> : tensor<11xf32>
%operand_1 = stablehlo.constant dense<...> : tensor<11xf32>
%golden = stablehlo.constant dense<...> : tensor<11xf32>
%0 = stablehlo.uniform_quantize %operand_0 : (tensor<11xf32>) -> tensor<11x!quant.uniform<i8:f32, 0.3>>
%1 = stablehlo.uniform_quantize %operand_1 : (tensor<11xf32>) -> tensor<11x!quant.uniform<i8:f32, 0.3>>
%2 = stablehlo.add %1, %0 : tensor<11x!quant.uniform<i8:f32, 0.3>>
%result = stablehlo.uniform_dequantize %2 : (tensor<11x!quant.uniform<i8:f32, 0.3>>) -> tensor<11xf32>
%4 = stablehlo.custom_call @check.eq(%golden, %result) : (tensor<11xf32>, tensor<11xf32>) -> tensor<i1>
return %3 : tensor<11xf32>
}
다음이 포함됩니다.
- 입력 데이터: 작업의 대표적인 입력 값입니다.
- 골든 출력: 입력 데이터에 적용될 때 작업의 예상 출력으로, StableHLO 참조 인터프리터 및 HLO 평가기를 준수합니다.
이러한 테스트 사례는 다음 용도로 유용합니다.
- StableHLO 양자화 검증: StableHLO 작업의 양자화 동작이 예상 결과와 일치하는지 확인합니다.
- 교차 검증: StableHLO 양자화 동작을 다른 구현 또는 프레임워크와 비교합니다.
- 디버깅 및 개발: 새로운 양자화 기능 또는 최적화의 개발 및 디버깅 지원