반정밀도 부동소수점수

컴퓨팅에서 **반정밀도**, **반정도** 또는 **하프 프리시전**(half precision, **FP16** 또는 **float16**)은 주기억장치에서 16비트(현대 컴퓨터에서는 2바이트)를 차지하는 이진 부동소수점 컴퓨터 숫자 형식이다. 이는 더 높은 정밀도가 필수적이지 않은 응용 프로그램, 특히 영상 처리 및 신경망에서 부동소수점 값을 저장하는 데 사용된다. 거의 모든 현대적인 사용은 IEEE 754-2008 표준을 따르며, 여기서 16비트 밑이 2인 형식은 **binary16**으로 참조되며, 지수는 5비트를 사용한다. 이는 ±65,504 범위의 값을 표현할 수 있으며, 1보다 큰 최소값은 1 + 1/1024이다. 컴퓨터에 따라 반정밀도는 배정밀도보다 한 자릿수 이상 빠를 수 있다. 예를 들어, 한 클라우드 공급자에서는 반정밀도가 550 PFLOPS인 반면, 배정밀도는 37 PFLOPS이다.access-date=2019-10-06
# 역사
몇 가지 이전의 16비트 부동소수점 형식이 존재했다. 여기에는 1982년 히타치 HD61810 DSP (4비트 지수 및 12비트 가수)의 형식,access-date=2017-07-14 1991년 토마스 J. 스콧(Thomas J. Scott)의 WIF (5비트 지수, 10비트 가수),doi-access=free 그리고 1995년 3dfx 부두 그래픽스 프로세서 (히타치와 동일)가 포함된다.access-date=2017-07-14 ILM은 넓은 동적 범위를 처리할 수 있지만, 단정밀도 또는 배정밀도 부동소수점의 하드 드라이브 및 메모리 비용이 없는 이미지 형식을 찾고 있었다.url-status=dead 존 에어리(John Airey)가 이끄는 SGI(실리콘 그래픽스)의 하드웨어 가속 프로그래밍 가능 셰이딩 그룹은 1997년 '발리' 디자인 노력의 일환으로 s10e5 데이터 유형을 사용했다. 이는 SIGGRAPH 2000 논문access-date=2017-07-14(섹션 4.3 참조)에 설명되어 있으며, 미국 특허 7518615access-date=2017-07-14에 추가로 문서화되어 있다. 이는 오픈 소스 OpenEXR 이미지 형식에서의 사용으로 대중화되었다. 엔비디아와 마이크로소프트는 2002년 초에 출시된 Cg 언어에서 **half** 자료형을 정의하고, 2002년 말에 출시된 GeForce FX에서 하드웨어로 구현했다.access-date=17 August 2016 그러나 16비트 부동소수점 가속 하드웨어 지원은 엔비디아가 나중에 중단했다가 2015년 테그라 X1 모바일 GPU에 다시 도입했다. 2012년의 F16C 확장 기능은 x86 프로세서가 머신 명령을 사용하여 반정밀도 부동소수점을 단정밀도 부동소수점으로 변환하고 그 반대로 변환할 수 있도록 한다.
# IEEE 754 반정밀도 이진 부동소수점 형식: binary16
IEEE 754 표준isbn=978-1-5044-5924-2은 **binary16**이 다음 형식을 갖도록 지정한다. * 부호 비트: 1비트 * 지수 너비: 5비트 * 가수 정밀도: 11비트 (10비트 명시적으로 저장) 형식은 다음과 같이 배치된다. 파일:IEEE 754r Half Floating Point 지수 필드가 모두 0으로 저장되지 않는 한, 형식은 값 1의 암묵적인 선행 비트를 갖는 것으로 가정한다. 따라서 메모리 형식에는 가수의 10비트만 나타나지만 총 정밀도는 11비트이다. IEEE 754 용어로는 10비트 가수를 갖지만, 11비트 가수의 정밀도(log10(211) ≈ 3.311 십진수 자릿수, 또는 4자릿수 ± 5 최하위 자릿수 단위보다 약간 적음)를 갖는다.
## 지수 인코딩
반정밀도 이진 부동소수점 지수는 오프셋 이진 표현을 사용하여 인코딩되며, 0 오프셋은 15이다. 이는 IEEE 754 표준에서 지수 바이어스(exponent bias)로도 알려져 있다. * Emin = 000012 − 011112 = −14 * Emax = 111102 − 011112 = 15 * 지수 바이어스 = 011112 = 15 따라서 오프셋 이진 표현에 의해 정의된 대로, 실제 지수를 얻기 위해서는 저장된 지수에서 오프셋 15를 빼야 한다. 저장된 지수 000002와 111112는 특별히 해석된다. {|class="wikitable" |- ! 지수 !! 가수 = 0 !! 가수 ≠ 0 !! 방정식 |- | 000002 || 0, −0 || 비정규수 || (−1)부호 비트 × 2−14 × 0.가수 비트2 |- | 000012, ..., 111102 ||colspan=2| 정규화된 값 || (−1)부호 비트 × 2지수−15 × 1.가수 비트2 |- | 111112 || ±무한 || NaN (Quiet, Signaling) || |} 최소 엄격 양수(비정규) 값은 2−24 ≈ 5.96 × 10−8이다. 최소 양수 정규 값은 2−14 ≈ 6.10 × 10−5이다. 최대 표현 가능한 값은 (2−2−10) × 215 = 65504이다.
## 반정밀도 예시
이 예시는 부동소수점 값의 비트 표현으로 주어진다. 여기에는 부호 비트, (바이어스된) 지수, 그리고 가수가 포함된다. {|class="wikitable" |- ! 이진 !! 헥스 !! 값 !! 비고 |- | 0 00000 0000000000 || 0000 || 0 || |- | 0 00000 0000000001 || 0001 || 1024 ) ≈ 0.000000059604645 || 가장 작은 양수 비정규수 |- | 0 00000 1111111111 || 03ff || 1024 ) ≈ 0.000060975552 || 가장 큰 비정규수 |- | 0 00001 0000000000 || 0400 || 1024 ) ≈ 0.00006103515625 || 가장 작은 양수 정규수 |- | 0 01101 0101010101 || 3555 || 1024 ) ≈ 0.33325195 || 1/3에 가장 가까운 값 |- | 0 01110 1111111111 || 3bff || 1024 ) ≈ 0.99951172 || 1보다 작은 가장 큰 수 |- | 0 01111 0000000000 || 3c00 || 1024 ) = 1 || 1 |- | 0 01111 0000000001 || 3c01 || 1024 ) ≈ 1.00097656 || 1보다 큰 가장 작은 수 |- | 0 11110 1111111111 || 7bff || 1024 ) = 65504 || 가장 큰 정규수 |- | 0 11111 0000000000 || 7c00 || ∞ || 무한대 |- | 1 00000 0000000000 || 8000 || −0 |- | 1 10000 0000000000 || c000 || 1024 ) = −2 |- | 1 11111 0000000000 || fc00 || −∞ || 음의 무한대 |} 기본적으로 1/3은 배정밀도와 마찬가지로 반올림되어 내림한다. 이는 가수에 홀수 비트가 있기 때문이다. 반올림 지점 너머의 비트는 0101...이며, 이는 최하위 자릿수 단위의 1/2 미만이다.
## 정밀도 제한
{|class="wikitable" |- | 0 || 2−13 || 2−24 |- | 2−13 || 2−12 || 2−23 |- | 2−12 || 2−11 || 2−22 |- | 2−11 || 2−10 || 2−21 |- | 2−10 || 2−9 || 2−20 |- | 2−9 || 2−8 || 2−19 |- | 2−8 || 2−7 || 2−18 |- | 2−7 || 2−6 || 2−17 |- | 2−6 || 2−5 || 2−16 |- | 2−5 || 2−4 || 2−15 |- | 2−4 || 8 || 2−14 |- | 8 || 4 || 2−13 |- | 4 || 2 || 2−12 |- | 2 || 1 || 2−11 |- | 1 || 2 || 2−10 |- | 2 || 4 || 2−9 |- | 4 || 8 || 2−8 |- | 8 || 16 || 2−7 |- | 16 || 32 || 2−6 |- | 32 || 64 || 2−5 |- | 64 || 128 || 2−4 |- | 128 || 256 || 8 |- | 256 || 512 || 4 |- | 512 || 1024 || 2 |- | 1024 || 2048 || 1 |- | 2048 || 4096 || 2 |- | 4096 || 8192 || 4 |- | 8192 || 16384 || 8 |- | 16384 || 32768 || 16 |- | 32768 || 65520 || 32 |- | 65520 || ∞ || ∞ |} 65520 이상의 숫자는 무한대로 반올림한다. 이는 짝수로 반올림하는 경우이며, 다른 반올림 전략은 이 임계값을 변경할 수 있다.
# ARM 대체 반정밀도
ARM 아키텍처 프로세서는 (부동소수점 제어 레지스터 비트를 통해) "대체 반정밀도" 형식을 지원한다. 이 형식은 지수 값 31 (111112)에 대한 특별한 경우를 없앤다.access-date=2015-05-05 이는 IEEE 형식과 거의 동일하지만, 무한대나 NaN에 대한 인코딩은 없다. 대신, 지수 31은 65536에서 131008 범위의 정규화된 숫자를 인코딩한다.
# 반정밀도의 사용
반정밀도는 MATLAB, OpenEXR, JPEG XR, GIMP, OpenGL, 벌컨 (API),access-date=2023-08-05 Cg, Direct3D, D3DX를 포함한 여러 컴퓨터 그래픽스 환경에서 픽셀을 저장하는 데 사용된다. 8비트 또는 16비트 정수에 비해 증가된 동적 범위는 이미지의 하이라이트와 그림자에서 더 많은 디테일을 보존할 수 있게 하고, 감마 보정을 피할 수 있다는 장점이 있다. 32비트 단정밀도 부동소수점에 비해 절반의 저장 공간과 대역폭을 필요로 한다는 장점이 있다(정밀도 및 범위 손실을 대가로). 반정밀도는 메시 양자화에 유용할 수 있다. 메시 데이터는 일반적으로 정점에 32비트 단정밀도 부동소수점을 사용하여 저장되지만, 일부 상황에서는 정밀도를 16비트 반정밀도로 줄이는 것이 허용되며, 이는 정밀도 손실을 대가로 저장 공간을 절반으로 줄일 수 있다. 메시 양자화는 요구 사항에 따라 8비트 또는 16비트 고정 정밀도로도 수행할 수 있다.access-date=2023-07-02 기계 학습 또는 신경망을 위한 하드웨어 및 소프트웨어는 반정밀도를 사용하는 경향이 있다. 이러한 응용 프로그램은 일반적으로 많은 계산을 수행하지만 높은 수준의 정밀도를 요구하지 않는다. 하드웨어가 16비트 반정밀도 부동소수점을 지원하지 않는 경우가 많기 때문에, 신경망은 종종 16비트로 잘린 단정밀도 부동소수점 형식인 bfloat16 형식을 사용한다. 하드웨어에 반정밀도 연산을 위한 명령어가 있다면, 종종 단정밀도 또는 배정밀도보다 빠르다. 시스템에 단일 명령어 내에서 여러 부동소수점을 처리할 수 있는 SIMD 명령어가 있다면, 반정밀도는 동시에 두 배 많은 숫자를 처리함으로써 두 배 빠르게 작동할 수 있다.quote=Nvidia recently introduced native half precision floating point support (FP16) into their Pascal GPUs. This was mainly motivated by the possibility that this will speed up data intensive and error tolerant applications in GPUs.
# 프로그래밍 언어별 지원
Zig는 `f16` 유형으로 반정밀도를 지원한다.access-date=7 January 2024 닷넷 5는 `System.Half` 표준 라이브러리 유형으로 반정밀도 부동소수점을 도입했다.language=en-uslanguage=en-US 2024년 1월, 어떤 닷넷 언어(C#, F#, Visual Basic, C++/CLI, C++/CX)도 해당 유형에 대한 리터럴(예: C#에서 `1.0f`는 `System.Single` 유형을, `1.0m`는 `System.Decimal` 유형을 가짐) 또는 키워드를 가지고 있지 않다.language=en-uslanguage=en-uslanguage=en-us 스위프트는 Swift 5.3에서 `Float16` 유형으로 반정밀도 부동소수점을 도입했다.access-date=13 May 2024 OpenCL도 IEEE 754-2008 반정밀도 저장 형식에서 half 데이터 유형으로 반정밀도 부동소수점을 지원한다.access-date=31 May 2024 2024년, 러스트는 현재 IEEE 반정밀도 16비트 부동소수점을 위한 새로운 `f16` 유형 추가 작업을 진행 중이다.access-date=2024-07-05 줄리아는 `Float16` 유형으로 반정밀도 부동소수점을 지원한다.website=docs.julialang.org C++는 C++23부터 `std::float16_t` 유형으로 반정밀도를 도입했다.website=www.open-std.org GCC는 이미 이를 지원한다.website=gcc.gnu.org
# 하드웨어 지원
ARM 아키텍처의 여러 버전은 반정밀도에 대한 지원을 포함한다.access-date=13 May 2022 x86 명령어 집합에서 반정밀도 부동소수점 변환에 대한 지원은 F16C 명령어 집합 확장에 명시되어 있으며, 이는 2009년 AMD에 의해 처음 도입되었고 2012년까지 AMD와 인텔 CPU에 상당히 널리 채택되었다. 이는 인텔 Sapphire Rapids 프로세서에 구현된 AVX-512_FP16 명령어 집합 확장으로 더욱 확장되었다.access-date=13 May 2022 RISC-V에서는 `Zfh` 및 `Zfhmin` 확장이 16비트 반정밀도 부동소수점에 대한 하드웨어 지원을 제공한다. `Zfhmin` 확장은 `Zfh`에 대한 최소 대안이다.access-date=2023-07-02 Power ISA에서는 VSX와 아직 승인되지 않은 SVP64 확장이 PowerISA v3.1B 이상에서 16비트 반정밀도 부동소수점에 대한 하드웨어 지원을 제공한다.access-date=2023-07-02access-date=2023-07-02 IBM Z의 반정밀도 지원은 IBM이 Telum과 함께 도입한 신경망 처리 보조 기능의 일부이다. IBM은 반정밀도 부동소수점 데이터를 NNP-데이터-유형 1 (16비트)로 지칭한다.
# 더 읽어보기
* Khronos Vulkan 부호 있는 16비트 부동소수점 형식