GGUF

kaeul·2024년 10월 17일
0

학습 후, cpp 아키텍쳐 기반 모델은 GGUF(GPT-Generated Unified Format) 포맷을 사용해서 변환된다. GGUF는 GGML의 단점을 보완한 추론동안 저장하는 모델에 대한 새로운 포맷으로 모델을 쉽게 load하고 save하기 위해 디자인된 binary format이다.

GGML

GPU compute & high precision vs CPU compute and low precision LLM 파라미터는 32 bit floating number인 반면, GGML은 16 bit floating point여서 LLM을 로드하고 run 하는데 메모리가 50% 줄어든다. GGML 라이브러리는 int 양자화를 지원한다.

GGUF

더 나은 tokenization, special token에 대한 지원, metadata 저장. Falcon, Bloom, Phi, Mistral과 같은 non-llama 아키텍쳐에 대해서도 지원.

GGML처럼 하나의 파일에 metadata, data, hyperparameters 모두 저장됩니다. 기존 GGML과의 차이점은 GGUF는 새로운 피쳐 추가도 가능하도록 디자인되었고, untyped value list보다 (metadata라고 불리는) 하이퍼파라미터에 대해 key-value 구조를 사용합니다.

inference할떄 파라미터 넣을 수 있게하는게 허깅페이스 모델과 다르다
gguf랑 hf랑 파라미터가 다르다

GGUF 파일 구조

GGUF Header
1. Magic number (4 bytes) to announce that this is a GGUF file,
2. Version (4 bytes) to specify the version of the format implemented,
3. Tensor count (8 bytes): the number of tensors in the file,
4. Metadata key-value pairs count (8 bytes): the number of metadata key-value pairs,

Metadata key-value pairs
텐서 정보
1. Name: name of the tensor, a standard GGUF string,
2. Dimension: number of dimensions in the tensor,
3. Type: very important information. This is the type of the tensor to determine the Quantization level of the Model.
4. Offset: position of the tensor data in the file
패딩
텐서 데이터: 원래 모델 파일 데이터와 유사하거나 같은 binary data지만 추론 최적화 혹은 양자화가 적용된.

GGUF에서 일반적인 텐서 타입
F32 (Single-precision floating-point): precision과 efficiency간의 균형을 제공하는 데이터 타입으로 널리 사용된다.
INT8 (8-bit signed integer): value에 8 bit 사용해서 메모리 효율
BF16 (Brain Floating-Point 16-bit)

block_count
find_hparam 으로 뭘 가져오는 건지?
bid?

def get_tensor_name_map
https://pastebin.com/5dhCEtkz
https://huggingface.co/docs/transformers/big_models

compiler
memory

def get_tensors(self) -> Iterator[tuple[str, Tensor]]:
    tensor_names_from_parts: set[str] = set()

    if len(self.part_names) > 1:
        self.tensor_names = set()
        index_name = "model.safetensors" if self.is_safetensors else "pytorch_model.bin"
        index_name += ".index.json"
        logger.info(f"gguf: loading model weight map from '{index_name}'")
        with open(self.dir_model / index_name, "r", encoding="utf-8") as f:
            index: dict[str, Any] = json.load(f)
            weight_map = index.get("weight_map")
            if weight_map is None or not isinstance(weight_map, dict):
                raise ValueError(f"Can't load 'weight_map' from {index_name!r}")
            self.tensor_names.update(weight_map.keys())
    else:
        self.tensor_names = tensor_names_from_parts

    for part_name in self.part_names:
        logger.info(f"gguf: loading model part '{part_name}'")
        ctx: ContextManager[Any]
        if self.is_safetensors:
            from safetensors import safe_open
            ctx = cast(ContextManager[Any], safe_open(self.dir_model / part_name, framework="pt", device="cpu"))
        else:
            ctx = contextlib.nullcontext(torch.load(str(self.dir_model / part_name), map_location="cpu", mmap=True, weights_only=True))

        with ctx as model_part:
            tensor_names_from_parts.update(model_part.keys())

            for name in model_part.keys():
                data = model_part.get_tensor(name) if self.is_safetensors else model_part[name]
                if self.lazy:
                    data = LazyTorchTensor.from_eager(data)
                yield name, data

    # only verify tensor name presence; it doesn't matter if they are not in the right files
    if len(sym_diff := tensor_names_from_parts.symmetric_difference(self.tensor_names)) > 0:
        raise ValueError(f"Mismatch between weight map and model parts for tensor names: {sym_diff}")

왜 삭제를 할까

def extra_f32_tensors(self, name: str, new_name: str, bid: int | None, n_dims: int) -> bool:
    del name, new_name, bid, n_dims  # unused

    return False

def extra_f16_tensors(self, name: str, new_name: str, bid: int | None, n_dims: int) -> bool:
    del name, new_name, bid, n_dims  # unused

    return False
    
    
    

def write_tensors(self):
텐서 이름을 읽는다는거?

https://github.com/ggerganov/llama.cpp/blob/master/convert-hf-to-gguf.py

profile
Deep learning

0개의 댓글