Image-Text-to-Text
Transformers
Safetensors
Norwegian
Norwegian Bokmål
Norwegian Nynorsk
gemma3
conversational
instruct
borealis
norwegian
norwegian-bokmal
norwegian-nynorsk
open
text-generation-inference
🇪🇺 Region: EU
Instructions to use NbAiLab/borealis-open-4b with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use NbAiLab/borealis-open-4b with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("image-text-to-text", model="NbAiLab/borealis-open-4b") messages = [ { "role": "user", "content": [ {"type": "image", "url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/p-blog/candy.JPG"}, {"type": "text", "text": "What animal is on the candy?"} ] }, ] pipe(text=messages)# Load model directly from transformers import AutoProcessor, AutoModelForImageTextToText processor = AutoProcessor.from_pretrained("NbAiLab/borealis-open-4b") model = AutoModelForImageTextToText.from_pretrained("NbAiLab/borealis-open-4b") messages = [ { "role": "user", "content": [ {"type": "image", "url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/p-blog/candy.JPG"}, {"type": "text", "text": "What animal is on the candy?"} ] }, ] inputs = processor.apply_chat_template( messages, add_generation_prompt=True, tokenize=True, return_dict=True, return_tensors="pt", ).to(model.device) outputs = model.generate(**inputs, max_new_tokens=40) print(processor.decode(outputs[0][inputs["input_ids"].shape[-1]:])) - Notebooks
- Google Colab
- Kaggle
- Local Apps
- vLLM
How to use NbAiLab/borealis-open-4b with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "NbAiLab/borealis-open-4b" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "NbAiLab/borealis-open-4b", "messages": [ { "role": "user", "content": [ { "type": "text", "text": "Describe this image in one sentence." }, { "type": "image_url", "image_url": { "url": "https://cdn.britannica.com/61/93061-050-99147DCE/Statue-of-Liberty-Island-New-York-Bay.jpg" } } ] } ] }'Use Docker
docker model run hf.co/NbAiLab/borealis-open-4b
- SGLang
How to use NbAiLab/borealis-open-4b with SGLang:
Install from pip and serve model
# Install SGLang from pip: pip install sglang # Start the SGLang server: python3 -m sglang.launch_server \ --model-path "NbAiLab/borealis-open-4b" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "NbAiLab/borealis-open-4b", "messages": [ { "role": "user", "content": [ { "type": "text", "text": "Describe this image in one sentence." }, { "type": "image_url", "image_url": { "url": "https://cdn.britannica.com/61/93061-050-99147DCE/Statue-of-Liberty-Island-New-York-Bay.jpg" } } ] } ] }'Use Docker images
docker run --gpus all \ --shm-size 32g \ -p 30000:30000 \ -v ~/.cache/huggingface:/root/.cache/huggingface \ --env "HF_TOKEN=<secret>" \ --ipc=host \ lmsysorg/sglang:latest \ python3 -m sglang.launch_server \ --model-path "NbAiLab/borealis-open-4b" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "NbAiLab/borealis-open-4b", "messages": [ { "role": "user", "content": [ { "type": "text", "text": "Describe this image in one sentence." }, { "type": "image_url", "image_url": { "url": "https://cdn.britannica.com/61/93061-050-99147DCE/Statue-of-Liberty-Island-New-York-Bay.jpg" } } ] } ] }' - Docker Model Runner
How to use NbAiLab/borealis-open-4b with Docker Model Runner:
docker model run hf.co/NbAiLab/borealis-open-4b
Commit ·
406007e
0
Parent(s):
Squash Borealis release history
Browse files- .gitattributes +40 -0
- LICENSE_FAQ.pdf +3 -0
- Model_Documentation_Form.pdf +3 -0
- README.md +251 -0
- borealis.png +3 -0
- borealis_evals_202605.png +3 -0
- chat_template.jinja +47 -0
- config.json +108 -0
- generation_config.json +14 -0
- model.safetensors +3 -0
- preprocessor_config.json +29 -0
- processor_config.json +4 -0
- signing/SHA256SUMS +10 -0
- signing/SHA256SUMS.sig +3 -0
- signing/ca-chain.pem +72 -0
- signing/cert.pem +39 -0
- signing/verify.sh +98 -0
- special_tokens_map.json +33 -0
- tokenizer.json +3 -0
- tokenizer.model +3 -0
- tokenizer_config.json +27 -0
.gitattributes
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
*.7z filter=lfs diff=lfs merge=lfs -text
|
| 2 |
+
*.arrow filter=lfs diff=lfs merge=lfs -text
|
| 3 |
+
*.bin filter=lfs diff=lfs merge=lfs -text
|
| 4 |
+
*.bz2 filter=lfs diff=lfs merge=lfs -text
|
| 5 |
+
*.ckpt filter=lfs diff=lfs merge=lfs -text
|
| 6 |
+
*.ftz filter=lfs diff=lfs merge=lfs -text
|
| 7 |
+
*.gz filter=lfs diff=lfs merge=lfs -text
|
| 8 |
+
*.h5 filter=lfs diff=lfs merge=lfs -text
|
| 9 |
+
*.joblib filter=lfs diff=lfs merge=lfs -text
|
| 10 |
+
*.lfs.* filter=lfs diff=lfs merge=lfs -text
|
| 11 |
+
*.mlmodel filter=lfs diff=lfs merge=lfs -text
|
| 12 |
+
*.model filter=lfs diff=lfs merge=lfs -text
|
| 13 |
+
*.msgpack filter=lfs diff=lfs merge=lfs -text
|
| 14 |
+
*.npy filter=lfs diff=lfs merge=lfs -text
|
| 15 |
+
*.npz filter=lfs diff=lfs merge=lfs -text
|
| 16 |
+
*.onnx filter=lfs diff=lfs merge=lfs -text
|
| 17 |
+
*.ot filter=lfs diff=lfs merge=lfs -text
|
| 18 |
+
*.parquet filter=lfs diff=lfs merge=lfs -text
|
| 19 |
+
*.pb filter=lfs diff=lfs merge=lfs -text
|
| 20 |
+
*.pickle filter=lfs diff=lfs merge=lfs -text
|
| 21 |
+
*.pkl filter=lfs diff=lfs merge=lfs -text
|
| 22 |
+
*.pt filter=lfs diff=lfs merge=lfs -text
|
| 23 |
+
*.pth filter=lfs diff=lfs merge=lfs -text
|
| 24 |
+
*.rar filter=lfs diff=lfs merge=lfs -text
|
| 25 |
+
*.safetensors filter=lfs diff=lfs merge=lfs -text
|
| 26 |
+
saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
| 27 |
+
*.tar.* filter=lfs diff=lfs merge=lfs -text
|
| 28 |
+
*.tar filter=lfs diff=lfs merge=lfs -text
|
| 29 |
+
*.tflite filter=lfs diff=lfs merge=lfs -text
|
| 30 |
+
*.tgz filter=lfs diff=lfs merge=lfs -text
|
| 31 |
+
*.wasm filter=lfs diff=lfs merge=lfs -text
|
| 32 |
+
*.xz filter=lfs diff=lfs merge=lfs -text
|
| 33 |
+
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
+
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
+
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
| 36 |
+
tokenizer.json filter=lfs diff=lfs merge=lfs -text
|
| 37 |
+
LICENSE_FAQ.pdf filter=lfs diff=lfs merge=lfs -text
|
| 38 |
+
borealis.png filter=lfs diff=lfs merge=lfs -text
|
| 39 |
+
borealis_evals_202605.png filter=lfs diff=lfs merge=lfs -text
|
| 40 |
+
Model_Documentation_Form.pdf filter=lfs diff=lfs merge=lfs -text
|
LICENSE_FAQ.pdf
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:b4a87118b0b0c1e2d5a06b27bb4b56517d4d62b2b74860f77b8ac2d601224840
|
| 3 |
+
size 140945
|
Model_Documentation_Form.pdf
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:7c1e200d8e7ca5378478d327d4a5e6f9352951992ac580252d47174343252164
|
| 3 |
+
size 333373
|
README.md
ADDED
|
@@ -0,0 +1,251 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
license: gemma
|
| 3 |
+
datasets:
|
| 4 |
+
- NbAiLab/aurora-sft-open
|
| 5 |
+
language:
|
| 6 |
+
- 'no'
|
| 7 |
+
- nb
|
| 8 |
+
- nn
|
| 9 |
+
base_model:
|
| 10 |
+
- google/gemma-3-4b-it
|
| 11 |
+
pipeline_tag: image-text-to-text
|
| 12 |
+
library_name: transformers
|
| 13 |
+
tags:
|
| 14 |
+
- conversational
|
| 15 |
+
- instruct
|
| 16 |
+
- borealis
|
| 17 |
+
- gemma3
|
| 18 |
+
- norwegian
|
| 19 |
+
- norwegian-bokmal
|
| 20 |
+
- norwegian-nynorsk
|
| 21 |
+
- open
|
| 22 |
+
---
|
| 23 |
+
|
| 24 |
+

|
| 25 |
+
|
| 26 |
+
# Borealis Open 4B
|
| 27 |
+
|
| 28 |
+
## Model Summary
|
| 29 |
+
|
| 30 |
+
**NbAiLab/borealis-open-4b** is a **4B-parameter** instruction-tuned **open release** model in the Borealis family from the National Library of Norway (Nasjonalbiblioteket, NB).
|
| 31 |
+
|
| 32 |
+
This is the first Borealis release to incorporate data made available under the agreement between rights-holder organizations in Norway and the Norwegian government. To date, only a limited subset of the material has been used, specifically to teach the model how to generate news article titles and ingress texts. Models with the suffix `-open`, do not include any material from the agreement.
|
| 33 |
+
|
| 34 |
+
All Borealis released models are based on the **Gemma 3** family. This model is based on [google/gemma-3-4b-it](https://huggingface.co/google/gemma-3-4b-it), and fine-tuned for Norwegian-centric instruction following.
|
| 35 |
+
|
| 36 |
+
### Sizes
|
| 37 |
+
|
| 38 |
+
| Size | Full release | Open release |
|
| 39 |
+
|---:|---|---|
|
| 40 |
+
| 27B | [NbAiLab/borealis-27b](https://huggingface.co/NbAiLab/borealis-27b) | [NbAiLab/borealis-open-27b](https://huggingface.co/NbAiLab/borealis-open-27b) |
|
| 41 |
+
| 12B | [NbAiLab/borealis-12b](https://huggingface.co/NbAiLab/borealis-12b) | [NbAiLab/borealis-open-12b](https://huggingface.co/NbAiLab/borealis-open-12b) |
|
| 42 |
+
| 4B | [NbAiLab/borealis-4b](https://huggingface.co/NbAiLab/borealis-4b) | [NbAiLab/borealis-open-4b](https://huggingface.co/NbAiLab/borealis-open-4b) |
|
| 43 |
+
| 1B | [NbAiLab/borealis-1b](https://huggingface.co/NbAiLab/borealis-1b) | [NbAiLab/borealis-open-1b](https://huggingface.co/NbAiLab/borealis-open-1b) |
|
| 44 |
+
| 270M | [NbAiLab/borealis-270m](https://huggingface.co/NbAiLab/borealis-270m) | [NbAiLab/borealis-open-270m](https://huggingface.co/NbAiLab/borealis-open-270m) |
|
| 45 |
+
|
| 46 |
+
## Training Data
|
| 47 |
+
|
| 48 |
+
Supervised fine-tuning (SFT) uses instruction data prepared by the National Library of Norway for Norwegian-centric assistant behavior, writing, summarization, question answering, and related tasks.
|
| 49 |
+
|
| 50 |
+
The SFT dataset for this model is [NbAiLab/aurora-sft-open](https://huggingface.co/datasets/NbAiLab/aurora-sft-open). [NbAiLab/aurora-sft-open](https://huggingface.co/datasets/NbAiLab/aurora-sft-open) is the open version of the SFT dataset. The only difference between [NbAiLab/aurora-sft-open](https://huggingface.co/datasets/NbAiLab/aurora-sft-open) and [NbAiLab/aurora-sft](https://huggingface.co/datasets/NbAiLab/aurora-sft) is the addition of 10k tasks derived from copyright-protected newspapers material.
|
| 51 |
+
|
| 52 |
+
## Evaluation
|
| 53 |
+
|
| 54 |
+
<figure>
|
| 55 |
+
<img src="./borealis_evals_202605.png" alt="Borealis evaluation results">
|
| 56 |
+
<figcaption>Borealis evaluation results on selected tasks (best score among {0-5}-shot).</figcaption>
|
| 57 |
+
</figure>
|
| 58 |
+
|
| 59 |
+
We evaluate Borealis with NorEval, MMLU-English, and nb-gpt-bench, our own evaluation suite, which will be published and described in an upcoming paper. The full Borealis models include around 10k newspaper-derived tasks from the abovementioned agreement and show a slight performance increase in some key metrics compared with the open variants. We hope to further increase the difference by incorporating proper pre-training on the newspaper material.
|
| 60 |
+
|
| 61 |
+
## Safety and Alignment
|
| 62 |
+
|
| 63 |
+
The Borealis family of models are aligned for safety using prompt baking and weighted merging of SFT and aligned models. The goal of this process is to balance model quality, usefulness, and safer behavior.
|
| 64 |
+
|
| 65 |
+
As with all generative models, outputs can still be incorrect, biased, harmful, or inappropriate. Do not use the model for safety-critical or high-stakes applications without additional evaluation and safeguards.
|
| 66 |
+
|
| 67 |
+
### Prompt Baking
|
| 68 |
+
|
| 69 |
+
To align the Borealis models, we employ *prompt baking*, a procedure that distills the behavior induced by a system prompt directly into the model weights using [`bakery`](https://github.com/marksverdhei/bakery). Specifically, we train a LoRA adapter to minimize the KL-divergence between two model distributions: Borealis conditioned on the system prompt, and the same base model augmented with the LoRA adapter but evaluated without the system prompt in context. This objective encourages the adapter to reproduce the behavioral effects of the prompt without requiring the prompt to be present at inference time.
|
| 70 |
+
|
| 71 |
+
To reduce degradation on downstream tasks and preserve general model utility, we merge the resulting prompt adapter into the base model using a scaling factor of `0.25`, which we found to provide the best empirical trade-off.
|
| 72 |
+
|
| 73 |
+
## Intended Use
|
| 74 |
+
|
| 75 |
+
- Norwegian-centric assistant-style tasks, including drafting, summarization, Q&A, and light reasoning (this is not a reasoning model).
|
| 76 |
+
- Assessment and improvement of Norwegian writing style and quality.
|
| 77 |
+
- Evaluation of behavior and language coverage for Norwegian, Bokmål, and Nynorsk.
|
| 78 |
+
|
| 79 |
+
## Usage
|
| 80 |
+
|
| 81 |
+
This repository contains the Transformers/safetensors version of the model. The
|
| 82 |
+
examples below use `NbAiLab/borealis-open-4b` as the model id; replace it with
|
| 83 |
+
another Borealis repo id if needed.
|
| 84 |
+
|
| 85 |
+
### Transformers
|
| 86 |
+
|
| 87 |
+
Use the Gemma 3 multimodal interface. For text-only prompts, omit image
|
| 88 |
+
content and keep only the text item in the message content list.
|
| 89 |
+
|
| 90 |
+
```python
|
| 91 |
+
import torch
|
| 92 |
+
from transformers import AutoProcessor, Gemma3ForConditionalGeneration
|
| 93 |
+
|
| 94 |
+
model_id = "NbAiLab/borealis-open-4b"
|
| 95 |
+
|
| 96 |
+
processor = AutoProcessor.from_pretrained(model_id)
|
| 97 |
+
model = Gemma3ForConditionalGeneration.from_pretrained(
|
| 98 |
+
model_id,
|
| 99 |
+
device_map="auto",
|
| 100 |
+
torch_dtype=torch.bfloat16,
|
| 101 |
+
)
|
| 102 |
+
|
| 103 |
+
messages = [
|
| 104 |
+
{
|
| 105 |
+
"role": "user",
|
| 106 |
+
"content": [
|
| 107 |
+
{"type": "text", "text": "Forklar kort hva du ser på bildet."},
|
| 108 |
+
{"type": "image", "url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/cats.png"},
|
| 109 |
+
],
|
| 110 |
+
}
|
| 111 |
+
]
|
| 112 |
+
|
| 113 |
+
inputs = processor.apply_chat_template(
|
| 114 |
+
messages,
|
| 115 |
+
add_generation_prompt=True,
|
| 116 |
+
tokenize=True,
|
| 117 |
+
return_dict=True,
|
| 118 |
+
return_tensors="pt",
|
| 119 |
+
).to(model.device)
|
| 120 |
+
|
| 121 |
+
outputs = model.generate(**inputs, max_new_tokens=256)
|
| 122 |
+
new_tokens = outputs[0, inputs["input_ids"].shape[-1]:]
|
| 123 |
+
print(processor.decode(new_tokens, skip_special_tokens=True))
|
| 124 |
+
```
|
| 125 |
+
|
| 126 |
+
### vLLM
|
| 127 |
+
|
| 128 |
+
Serve the model with vLLM's OpenAI-compatible server:
|
| 129 |
+
|
| 130 |
+
```bash
|
| 131 |
+
vllm serve NbAiLab/borealis-open-4b --served-model-name borealis-open-4b
|
| 132 |
+
```
|
| 133 |
+
|
| 134 |
+
Then call the local chat completions endpoint:
|
| 135 |
+
|
| 136 |
+
```bash
|
| 137 |
+
curl http://localhost:8000/v1/chat/completions \
|
| 138 |
+
-H "Content-Type: application/json" \
|
| 139 |
+
-d '{
|
| 140 |
+
"model": "borealis-open-4b",
|
| 141 |
+
"messages": [
|
| 142 |
+
{
|
| 143 |
+
"role": "user",
|
| 144 |
+
"content": "Skriv tre korte punkter om norsk språkteknologi."
|
| 145 |
+
}
|
| 146 |
+
],
|
| 147 |
+
"max_tokens": 256
|
| 148 |
+
}'
|
| 149 |
+
```
|
| 150 |
+
|
| 151 |
+
Large models may require tensor parallelism or reduced memory settings depending
|
| 152 |
+
on the available GPU memory.
|
| 153 |
+
|
| 154 |
+
### llama.cpp
|
| 155 |
+
|
| 156 |
+
llama.cpp uses GGUF files, not the safetensors files in this repository. When
|
| 157 |
+
the planned GGUF companion repository is available, you can run it directly from
|
| 158 |
+
the Hub:
|
| 159 |
+
|
| 160 |
+
```bash
|
| 161 |
+
llama-server -hf NbAiLab/borealis-open-4b-gguf --port 8080
|
| 162 |
+
```
|
| 163 |
+
|
| 164 |
+
Or download a GGUF file and run it locally:
|
| 165 |
+
|
| 166 |
+
```bash
|
| 167 |
+
llama-cli -m borealis-open-4b.gguf \
|
| 168 |
+
-p "Skriv et kort sammendrag av hva Nasjonalbiblioteket gjør." \
|
| 169 |
+
-n 256
|
| 170 |
+
```
|
| 171 |
+
|
| 172 |
+
### Ollama
|
| 173 |
+
|
| 174 |
+
Ollama also requires a GGUF model. Once the GGUF companion repository is
|
| 175 |
+
available, you can run it from Hugging Face:
|
| 176 |
+
|
| 177 |
+
```bash
|
| 178 |
+
ollama run hf.co/NbAiLab/borealis-open-4b-gguf
|
| 179 |
+
```
|
| 180 |
+
|
| 181 |
+
For a local GGUF file, create a minimal `Modelfile`:
|
| 182 |
+
|
| 183 |
+
```text
|
| 184 |
+
FROM ./borealis-open-4b.gguf
|
| 185 |
+
```
|
| 186 |
+
|
| 187 |
+
Then create and run the local Ollama model:
|
| 188 |
+
|
| 189 |
+
```bash
|
| 190 |
+
ollama create borealis-open-4b -f Modelfile
|
| 191 |
+
ollama run borealis-open-4b "Skriv tre korte punkter om norsk språkteknologi."
|
| 192 |
+
```
|
| 193 |
+
|
| 194 |
+
## Limitations
|
| 195 |
+
|
| 196 |
+
- The model may hallucinate or produce incorrect information.
|
| 197 |
+
- Safety alignment reduces but does not eliminate harmful or inappropriate outputs.
|
| 198 |
+
- Performance outside Norwegian and English use cases has not been fully characterized.
|
| 199 |
+
|
| 200 |
+
## EU AI Act
|
| 201 |
+
|
| 202 |
+
The model is a fine-tune of Gemma 3. Using Gemma 3 27B as a conservative upper-bound reference, the original Gemma 3 27B training compute is estimated at approximately 2.1-2.3 x 10^24 FLOPs, based on the disclosed 14T training-token budget and the 27B parameter scale. The fine-tuning run used approximately 3.4 x 10^20 FLOPs, or about 0.015% of the estimated original training compute. This is substantially below the European Commission's indicative one-third threshold for treating a downstream modification as a significant modification that would make the modifier the provider of the modified General Purpose AI (GPAI) model.
|
| 203 |
+
|
| 204 |
+
On that basis, the fine-tuning activity is preliminarily assessed as not constituting a substantial modification for the purpose of becoming the provider of a new modified GPAI model under the compute-based criterion. However, the resulting model remains derived from a generative general-purpose AI model and may still be subject to downstream AI-system obligations under the EU AI Act.
|
| 205 |
+
|
| 206 |
+
For additional model-level documentation, see the [Model Documentation Form](./Model_Documentation_Form.pdf).
|
| 207 |
+
|
| 208 |
+
## License
|
| 209 |
+
|
| 210 |
+
The license of this model is an adaptation of the Apache 2.0 license with additional use-based restrictions. In particular, users of the model are required to refrain from intentionally using the model to recreate data the model has been trained on. The license also requires users not to use the model or its output to provide end-user services whose primary purpose is to give access to licensed press publications in the training data.
|
| 211 |
+
|
| 212 |
+
For more information, see the [LICENSE](./LICENSE) and the [License FAQ](./LICENSE_FAQ.pdf).
|
| 213 |
+
|
| 214 |
+
## Authenticity
|
| 215 |
+
|
| 216 |
+
This model release is signed by the National Library of Norway. The signed manifest in `signing/SHA256SUMS` covers the model-runtime artifacts, including model weights, configuration, tokenizer files, and chat template.
|
| 217 |
+
|
| 218 |
+
To verify model authenticity and file integrity after downloading the repository, run:
|
| 219 |
+
|
| 220 |
+
```bash
|
| 221 |
+
bash signing/verify.sh
|
| 222 |
+
```
|
| 223 |
+
|
| 224 |
+
For more verification instructions, see [ai.nb.no/verify](https://ai.nb.no/verify).
|
| 225 |
+
|
| 226 |
+
## Weights
|
| 227 |
+
|
| 228 |
+
This repository contains the Transformers (safetensors) release of **NbAiLab/borealis-open-4b**.
|
| 229 |
+
|
| 230 |
+
Companion formats:
|
| 231 |
+
- GGUF: [NbAiLab/borealis-open-4b-gguf](https://huggingface.co/NbAiLab/borealis-open-4b-gguf)
|
| 232 |
+
- MLX: [NbAiLab/borealis-open-4b-mlx](https://huggingface.co/NbAiLab/borealis-open-4b-mlx)
|
| 233 |
+
- MLX 8-bit: [NbAiLab/borealis-open-4b-mlx-8bits](https://huggingface.co/NbAiLab/borealis-open-4b-mlx-8bits)
|
| 234 |
+
|
| 235 |
+
## Citation and Contributors
|
| 236 |
+
|
| 237 |
+
The Borealis family of models is a joint effort of multiple teams at the National Library of Norway. Led by Javier de la Rosa ([@versae](https://huggingface.co/versae)), key contributors include (in alphabetical order) Rolv-Arild Braaten, Magnus Breder Birkenes, Lucas Charpentier, Pawel Cyrta, Tita Enstad, Markus Sverdvik Heiervang, Arne Martinus Lindstad, Marthe Løken Midtgaard, Marie Roald, Marie Røsok, Thea Tollersrud, and Angelina Zanardi. Olaus Ingskog Bergstrøm contributed with legal advice. And Yngvil Beyer, Svein Arne Brygfjeld, and Wilfred Østgulen helped with strategic oversight.
|
| 238 |
+
|
| 239 |
+
A tecnical report will be released soon.
|
| 240 |
+
|
| 241 |
+
## Acknowledgements
|
| 242 |
+
|
| 243 |
+
Thanks to the Gemma team at Google for releasing Gemma 3, and to everyone contributing to the Norwegian language technology ecosystem.
|
| 244 |
+
|
| 245 |
+
## Disclaimer
|
| 246 |
+
|
| 247 |
+
The models published in this repository are intended for a generalist purpose and are available to third parties. These models may have bias and/or any other undesirable distortions. When third parties, deploy or provide systems and/or services to other parties using any of these models (or using systems based on these models) or become users of the models, they should note that it is their responsibility to mitigate the risks arising from their use and, in any event, to comply with applicable regulations, including regulations regarding the use of artificial intelligence. In no event shall the owner of the models (The National Library of Norway) be liable for any results arising from the use made by third parties of these models.
|
| 248 |
+
|
| 249 |
+
## Contact
|
| 250 |
+
|
| 251 |
+
For feedback, technical concerns, or collaboration inquiries, please contact <a rel="noopener nofollow" href="mailto:ailab@nb.no">ailab@nb.no</a>.
|
borealis.png
ADDED
|
Git LFS Details
|
borealis_evals_202605.png
ADDED
|
Git LFS Details
|
chat_template.jinja
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{{ bos_token }}
|
| 2 |
+
{%- if messages[0]['role'] == 'system' -%}
|
| 3 |
+
{%- if messages[0]['content'] is string -%}
|
| 4 |
+
{%- set first_user_prefix = messages[0]['content'] + '
|
| 5 |
+
|
| 6 |
+
' -%}
|
| 7 |
+
{%- else -%}
|
| 8 |
+
{%- set first_user_prefix = messages[0]['content'][0]['text'] + '
|
| 9 |
+
|
| 10 |
+
' -%}
|
| 11 |
+
{%- endif -%}
|
| 12 |
+
{%- set loop_messages = messages[1:] -%}
|
| 13 |
+
{%- else -%}
|
| 14 |
+
{%- set first_user_prefix = "" -%}
|
| 15 |
+
{%- set loop_messages = messages -%}
|
| 16 |
+
{%- endif -%}
|
| 17 |
+
{%- for message in loop_messages -%}
|
| 18 |
+
{%- if (message['role'] == 'user') != (loop.index0 % 2 == 0) -%}
|
| 19 |
+
{{ raise_exception("Conversation roles must alternate user/assistant/user/assistant/...") }}
|
| 20 |
+
{%- endif -%}
|
| 21 |
+
{%- if (message['role'] == 'assistant') -%}
|
| 22 |
+
{%- set role = "model" -%}
|
| 23 |
+
{%- else -%}
|
| 24 |
+
{%- set role = message['role'] -%}
|
| 25 |
+
{%- endif -%}
|
| 26 |
+
{{ '<start_of_turn>' + role + '
|
| 27 |
+
' + (first_user_prefix if loop.first else "") }}
|
| 28 |
+
{%- if message['content'] is string -%}
|
| 29 |
+
{{ message['content'] | trim }}
|
| 30 |
+
{%- elif message['content'] is iterable -%}
|
| 31 |
+
{%- for item in message['content'] -%}
|
| 32 |
+
{%- if item['type'] == 'image' -%}
|
| 33 |
+
{{ '<start_of_image>' }}
|
| 34 |
+
{%- elif item['type'] == 'text' -%}
|
| 35 |
+
{{ item['text'] | trim }}
|
| 36 |
+
{%- endif -%}
|
| 37 |
+
{%- endfor -%}
|
| 38 |
+
{%- else -%}
|
| 39 |
+
{{ raise_exception("Invalid content type") }}
|
| 40 |
+
{%- endif -%}
|
| 41 |
+
{{ '<end_of_turn>
|
| 42 |
+
' }}
|
| 43 |
+
{%- endfor -%}
|
| 44 |
+
{%- if add_generation_prompt -%}
|
| 45 |
+
{{'<start_of_turn>model
|
| 46 |
+
'}}
|
| 47 |
+
{%- endif -%}
|
config.json
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"architectures": [
|
| 3 |
+
"Gemma3ForConditionalGeneration"
|
| 4 |
+
],
|
| 5 |
+
"boi_token_index": 255999,
|
| 6 |
+
"bos_token_id": 2,
|
| 7 |
+
"dtype": "bfloat16",
|
| 8 |
+
"eoi_token_index": 256000,
|
| 9 |
+
"eos_token_id": 106,
|
| 10 |
+
"hidden_size": 2560,
|
| 11 |
+
"image_token_index": 262144,
|
| 12 |
+
"initializer_range": 0.02,
|
| 13 |
+
"mm_tokens_per_image": 256,
|
| 14 |
+
"model_type": "gemma3",
|
| 15 |
+
"pad_token_id": 0,
|
| 16 |
+
"text_config": {
|
| 17 |
+
"_sliding_window_pattern": 6,
|
| 18 |
+
"attention_bias": false,
|
| 19 |
+
"attention_dropout": 0.0,
|
| 20 |
+
"attn_logit_softcapping": null,
|
| 21 |
+
"bos_token_id": 2,
|
| 22 |
+
"dtype": "bfloat16",
|
| 23 |
+
"eos_token_id": 1,
|
| 24 |
+
"final_logit_softcapping": null,
|
| 25 |
+
"head_dim": 256,
|
| 26 |
+
"hidden_activation": "gelu_pytorch_tanh",
|
| 27 |
+
"hidden_size": 2560,
|
| 28 |
+
"initializer_range": 0.02,
|
| 29 |
+
"intermediate_size": 10240,
|
| 30 |
+
"layer_types": [
|
| 31 |
+
"sliding_attention",
|
| 32 |
+
"sliding_attention",
|
| 33 |
+
"sliding_attention",
|
| 34 |
+
"sliding_attention",
|
| 35 |
+
"sliding_attention",
|
| 36 |
+
"full_attention",
|
| 37 |
+
"sliding_attention",
|
| 38 |
+
"sliding_attention",
|
| 39 |
+
"sliding_attention",
|
| 40 |
+
"sliding_attention",
|
| 41 |
+
"sliding_attention",
|
| 42 |
+
"full_attention",
|
| 43 |
+
"sliding_attention",
|
| 44 |
+
"sliding_attention",
|
| 45 |
+
"sliding_attention",
|
| 46 |
+
"sliding_attention",
|
| 47 |
+
"sliding_attention",
|
| 48 |
+
"full_attention",
|
| 49 |
+
"sliding_attention",
|
| 50 |
+
"sliding_attention",
|
| 51 |
+
"sliding_attention",
|
| 52 |
+
"sliding_attention",
|
| 53 |
+
"sliding_attention",
|
| 54 |
+
"full_attention",
|
| 55 |
+
"sliding_attention",
|
| 56 |
+
"sliding_attention",
|
| 57 |
+
"sliding_attention",
|
| 58 |
+
"sliding_attention",
|
| 59 |
+
"sliding_attention",
|
| 60 |
+
"full_attention",
|
| 61 |
+
"sliding_attention",
|
| 62 |
+
"sliding_attention",
|
| 63 |
+
"sliding_attention",
|
| 64 |
+
"sliding_attention"
|
| 65 |
+
],
|
| 66 |
+
"max_position_embeddings": 131072,
|
| 67 |
+
"model_type": "gemma3_text",
|
| 68 |
+
"num_attention_heads": 8,
|
| 69 |
+
"num_hidden_layers": 34,
|
| 70 |
+
"num_key_value_heads": 4,
|
| 71 |
+
"pad_token_id": 0,
|
| 72 |
+
"query_pre_attn_scalar": 256,
|
| 73 |
+
"rms_norm_eps": 1e-06,
|
| 74 |
+
"rope_parameters": {
|
| 75 |
+
"full_attention": {
|
| 76 |
+
"factor": 8.0,
|
| 77 |
+
"rope_theta": 1000000.0,
|
| 78 |
+
"rope_type": "linear"
|
| 79 |
+
},
|
| 80 |
+
"sliding_attention": {
|
| 81 |
+
"rope_theta": 10000.0,
|
| 82 |
+
"rope_type": "default"
|
| 83 |
+
}
|
| 84 |
+
},
|
| 85 |
+
"sliding_window": 1024,
|
| 86 |
+
"tie_word_embeddings": true,
|
| 87 |
+
"use_bidirectional_attention": false,
|
| 88 |
+
"use_cache": false,
|
| 89 |
+
"vocab_size": 262208
|
| 90 |
+
},
|
| 91 |
+
"tie_word_embeddings": true,
|
| 92 |
+
"transformers_version": "5.8.0",
|
| 93 |
+
"vision_config": {
|
| 94 |
+
"attention_dropout": 0.0,
|
| 95 |
+
"dtype": "bfloat16",
|
| 96 |
+
"hidden_act": "gelu_pytorch_tanh",
|
| 97 |
+
"hidden_size": 1152,
|
| 98 |
+
"image_size": 896,
|
| 99 |
+
"intermediate_size": 4304,
|
| 100 |
+
"layer_norm_eps": 1e-06,
|
| 101 |
+
"model_type": "siglip_vision_model",
|
| 102 |
+
"num_attention_heads": 16,
|
| 103 |
+
"num_channels": 3,
|
| 104 |
+
"num_hidden_layers": 27,
|
| 105 |
+
"patch_size": 14,
|
| 106 |
+
"vision_use_head": false
|
| 107 |
+
}
|
| 108 |
+
}
|
generation_config.json
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"bos_token_id": 2,
|
| 3 |
+
"cache_implementation": "hybrid",
|
| 4 |
+
"do_sample": true,
|
| 5 |
+
"eos_token_id": [
|
| 6 |
+
106,
|
| 7 |
+
1,
|
| 8 |
+
106
|
| 9 |
+
],
|
| 10 |
+
"pad_token_id": 0,
|
| 11 |
+
"top_k": 64,
|
| 12 |
+
"top_p": 0.95,
|
| 13 |
+
"transformers_version": "5.8.0"
|
| 14 |
+
}
|
model.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:d461dd8bff15cab72c74c18d0e9ab85a6de60766424be9d1aaf4d5cab0b5a03b
|
| 3 |
+
size 8600278008
|
preprocessor_config.json
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"do_convert_rgb": null,
|
| 3 |
+
"do_normalize": true,
|
| 4 |
+
"do_pan_and_scan": null,
|
| 5 |
+
"do_rescale": true,
|
| 6 |
+
"do_resize": true,
|
| 7 |
+
"image_mean": [
|
| 8 |
+
0.5,
|
| 9 |
+
0.5,
|
| 10 |
+
0.5
|
| 11 |
+
],
|
| 12 |
+
"image_processor_type": "Gemma3ImageProcessor",
|
| 13 |
+
"image_seq_length": 256,
|
| 14 |
+
"image_std": [
|
| 15 |
+
0.5,
|
| 16 |
+
0.5,
|
| 17 |
+
0.5
|
| 18 |
+
],
|
| 19 |
+
"pan_and_scan_max_num_crops": null,
|
| 20 |
+
"pan_and_scan_min_crop_size": null,
|
| 21 |
+
"pan_and_scan_min_ratio_to_activate": null,
|
| 22 |
+
"processor_class": "Gemma3Processor",
|
| 23 |
+
"resample": 2,
|
| 24 |
+
"rescale_factor": 0.00392156862745098,
|
| 25 |
+
"size": {
|
| 26 |
+
"height": 896,
|
| 27 |
+
"width": 896
|
| 28 |
+
}
|
| 29 |
+
}
|
processor_config.json
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"image_seq_length": 256,
|
| 3 |
+
"processor_class": "Gemma3Processor"
|
| 4 |
+
}
|
signing/SHA256SUMS
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
7de1c58e208eda46e9c7f86397df37ec49883aeece39fb961e0a6b24088dd3c4 chat_template.jinja
|
| 2 |
+
91dc64d725cf72a4e044bd4f1ad47ae817341f1937b627cd65007b4880acef3e config.json
|
| 3 |
+
d658664f05444ad13f0b7f1298cea34e5b745583f0c720d74531c49549fa1fa1 generation_config.json
|
| 4 |
+
d461dd8bff15cab72c74c18d0e9ab85a6de60766424be9d1aaf4d5cab0b5a03b model.safetensors
|
| 5 |
+
f688d6bb20c5017601c4011de7ca656da8485b540b05013efdaf986c0fcc918d preprocessor_config.json
|
| 6 |
+
3ffd5f11778dc73e2b69b3c00535e4121e1badf7018136263cd17b5b34fbaa53 processor_config.json
|
| 7 |
+
2f7b0adf4fb469770bb1490e3e35df87b1dc578246c5e7e6fc76ecf33213a397 special_tokens_map.json
|
| 8 |
+
daab2354f8a74e70d70b4d1f804939b68a8c9624dd06cb7858e52dd8970e9726 tokenizer.json
|
| 9 |
+
1299c11d7cf632ef3b4e11937501358ada021bbdf7c47638d13c0ee982f2e79c tokenizer.model
|
| 10 |
+
d9aedd7a33a5aff2d3b8426eb18aed48e701213b0945564537ef6cd8844b9150 tokenizer_config.json
|
signing/SHA256SUMS.sig
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
J�f�ƞOXo.Bnܜ9KѺ�"B�j8�W�٦��
|
| 2 |
+
�:z����
|
| 3 |
+
��ԹX#�?�V�Cr�b����N�fi����r�0��sÀ�����?��)bQ�#�ɵ�m$"���#�C|�I�-y�|:�$�k��������_@����U��T�}���Hi�>�R#�Z����q*,�H~���?@*4���i�_�{�N*~gΩ��%+)L�*D����2oZ��L��R֡$"�0�-4�ؚ���?�2����,~%
|
signing/ca-chain.pem
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
-----BEGIN CERTIFICATE-----
|
| 2 |
+
MIIG1jCCBL6gAwIBAgIQSIcdqlEaPQ81vpaZKLkkvzANBgkqhkiG9w0BAQsFADB1
|
| 3 |
+
MQswCQYDVQQGEwJHUjE3MDUGA1UECgwuSGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl
|
| 4 |
+
c2VhcmNoIEluc3RpdHV0aW9ucyBDQTEtMCsGA1UEAwwkSEFSSUNBIENvZGUgU2ln
|
| 5 |
+
bmluZyBSU0EgUm9vdCBDQSAyMDIxMB4XDTIxMDMxOTA5MjEzNFoXDTM2MDMxNTA5
|
| 6 |
+
MjEzM1owaDELMAkGA1UEBhMCR1IxNzA1BgNVBAoMLkhlbGxlbmljIEFjYWRlbWlj
|
| 7 |
+
IGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ0ExIDAeBgNVBAMMF0hBUklDQSBD
|
| 8 |
+
b2RlIFNpZ25pbmcgUlNBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA
|
| 9 |
+
31Aluoq9mggXHg7TLFGOUTVDufEJjAKMhSYM4vh98DxFUPCE0soUcvj4AcbfOq0E
|
| 10 |
+
rXG93MW2o/8byyISWPDTu7CKSYzF2x67GEcjAlOvdQn5UZOvI2fw86727Q0GHZ77
|
| 11 |
+
+EfBRkLcLHPEGeVs4mkchtLydKjv42/Lsqu9/5AcYWro03lYf1q++LOmaJjSscvY
|
| 12 |
+
LdAPPnzm+Aa9FIZc3K3JeZ1dxNhT6fAheWeAO4JxnBT2k7Qa1oJqJ1u6t3RYiadj
|
| 13 |
+
shRVAwDq6/WVCW0hysPB9GuQEFkRKgkpQjcvZqG2yCMIVy9cCRQjIQWG9LSnLezv
|
| 14 |
+
wAan4sUIzzgoABiodCU7Gc6uJsshdjHUBiMxQzsbd5rKPZYPk+uiiXaN6V5LP079
|
| 15 |
+
9treRIh6h3h111HITXE2rQDEBsdKrandn4oUTUz3VZMO6XLQA6xpPAinx7ISDdkO
|
| 16 |
+
3VOkEYebMxDF/7lo1GSgrgPvFPRVNWhPxHdVrRkB8/ZKg90HyP0g339NkmDwhVqo
|
| 17 |
+
ZK4EiL5J3033w+U+HNowegNKxn8b1g/vB6ZHlVBGCugsO+77M6Z8/ouk755Jr8TI
|
| 18 |
+
gcyn/CKKadsb748oy/AvqmviFOM+ilORjZVWOFXy82QdjBDapfMOM6JqtSFUTvf5
|
| 19 |
+
OmVXDdIHMvosCWurRYXbVKgTNgOXVgJRAaquQBahtc0CAwEAAaOCAW0wggFpMBIG
|
| 20 |
+
A1UdEwEB/wQIMAYBAf8CAQAwHwYDVR0jBBgwFoAUtGQWSOj8WkszKYnrmUC5ILT2
|
| 21 |
+
YRowXAYIKwYBBQUHAQEEUDBOMEwGCCsGAQUFBzAChkBodHRwOi8vcmVwby5oYXJp
|
| 22 |
+
Y2EuZ3IvY2VydHMvSEFSSUNBLUNvZGVTaWduaW5nLVJvb3QtMjAyMS1SU0EuY2Vy
|
| 23 |
+
MEQGA1UdIAQ9MDswOQYEVR0gADAxMC8GCCsGAQUFBwIBFiNodHRwOi8vcmVwby5o
|
| 24 |
+
YXJpY2EuZ3IvZG9jdW1lbnRzL0NQUzATBgNVHSUEDDAKBggrBgEFBQcDAzBKBgNV
|
| 25 |
+
HR8EQzBBMD+gPaA7hjlodHRwOi8vY3JsLmhhcmljYS5nci9IQVJJQ0EtQ29kZVNp
|
| 26 |
+
Z25pbmctUm9vdC0yMDIxLVJTQS5jcmwwHQYDVR0OBBYEFKnsNRTrbmcFDsRtCQyg
|
| 27 |
+
cgYhtMouMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAhcU6MtmA
|
| 28 |
+
N9i3luIBF/JqB+CyCqlc9TFuu0d/Gi1PU86Mf6sqIqAObiDcM4J/uL2QWogUk5GZ
|
| 29 |
+
b1bNCRBrmhPv9C8rFsbeNKJYdDEWtslXQrnnd9vpAKkurG9imNW4RE/jsPV28T2I
|
| 30 |
+
iHWEYA0zGiP0qyAyEVvwSntEpFigaslhLFtVqf0uCGIvHRMfdD53WTXq37sInwcG
|
| 31 |
+
/W2C0zcno3PUK8qtCvF7cO1jujGxsLG/h0blm+M6b09doO1iSq3SAO4kwue+7AvB
|
| 32 |
+
97ppo4XKgcp1Kq6LGl4Rzac23KeMRkucwofNILRbIBwxdaeudozb6XIvgGeNPmFq
|
| 33 |
+
71HdLzBS0i9Tyxsf4VjlJj1vazncSFxz56RDNyendlYR39bZrQ6FMr6W5/vt1cwe
|
| 34 |
+
e7HlVnnQvdNMiFX/+uWH8kz29rP5q1NEQx8xjV7WnDqADnbTzGoUg9P3GR5Mv4m9
|
| 35 |
+
tSktUu6WqserABWf8e0L3ClvUKcnCeG/lyXbmQWxRIGrWAMmUSP1/BVajITUrEDW
|
| 36 |
+
qrrBmUlCoSpa0OZ7lfmlQ/QtaWvwrGRNgbLx7RgqlxsjeJtZUoBwC3nFNO6j80QB
|
| 37 |
+
CQEdsxUWKYZmXTnSuiG63O/wON+TmWrM7SbxqbiZRIGw90aHT2bK+8CfMgSdxl1k
|
| 38 |
+
JT844f3ByJb2qHA+z2lw0JqwVp07ORkrwwE=
|
| 39 |
+
-----END CERTIFICATE-----
|
| 40 |
+
-----BEGIN CERTIFICATE-----
|
| 41 |
+
MIIFtjCCA56gAwIBAgIQFcKuKk2ZmmOM07oTGXYI9TANBgkqhkiG9w0BAQsFADB1
|
| 42 |
+
MQswCQYDVQQGEwJHUjE3MDUGA1UECgwuSGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl
|
| 43 |
+
c2VhcmNoIEluc3RpdHV0aW9ucyBDQTEtMCsGA1UEAwwkSEFSSUNBIENvZGUgU2ln
|
| 44 |
+
bmluZyBSU0EgUm9vdCBDQSAyMDIxMB4XDTIxMDIxOTEwNTk1NFoXDTQ1MDIxMzEw
|
| 45 |
+
NTk1M1owdTELMAkGA1UEBhMCR1IxNzA1BgNVBAoMLkhlbGxlbmljIEFjYWRlbWlj
|
| 46 |
+
IGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ0ExLTArBgNVBAMMJEhBUklDQSBD
|
| 47 |
+
b2RlIFNpZ25pbmcgUlNBIFJvb3QgQ0EgMjAyMTCCAiIwDQYJKoZIhvcNAQEBBQAD
|
| 48 |
+
ggIPADCCAgoCggIBAIpq7qoKI1UMiwZC45VbVHhfxY4GLHw8Mb6vDamh7EogWAWd
|
| 49 |
+
4miyu+tffyozufJVnG+qpB7tEL6DKRE25p4/+m17UeHVd6W9y2kOOyIglAwxZUAN
|
| 50 |
+
Ca8QNXqb6nkIRKSLZ6krTcHn0Nen9rU6jdmjqXm4pGVcvPM+95+Z9rjDZWgtq4Mu
|
| 51 |
+
3YWZBKn10VzVUUIBuZ9BtUsisgD0y2cQ72nEEK36lAZ2UBJXgq7FFK08fbud8XPh
|
| 52 |
+
fPCucd5b9xLd94Dx3D7xYLrJGZdvdXSFTP05Q8NkbjSsE8EcZbZSQvFG6y/6XabP
|
| 53 |
+
Dkmd93R8eA0GOiwS++JLJuRviyGBM0I5E+hCq1tV1Bu7N7YSkffzfbzS/+yxw9Wg
|
| 54 |
+
zLIrx49dfkxSQkj7j/1akHMQ1alyVI1J2zhSqkZIDi/6ACzMcww2SyTOE2ympKSj
|
| 55 |
+
1nyb6TgLxiTbTaxnIUlbQTdk5mBrH+0qL2AZMB7YPJwZQ4ffwAr05MpgiHrWo7nk
|
| 56 |
+
JS554v7Byzy3989OWEz7w62rfarKiPsOOA0fnlw567gHxFAiTfiFf27sjPq2cU3e
|
| 57 |
+
fZZpxN0+Ht4mkAosTRWVqaI+3D0Od3yNQShPuINRvj63j5A6cDGJWvqTU/xgyY11
|
| 58 |
+
kO5aLx2EnwCp5sOGI6Ie3RLjoUZgG2e/UBUiknxKtIyPbpyVwizcOzogtryLAgMB
|
| 59 |
+
AAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFLRkFkjo/FpLMymJ65lA
|
| 60 |
+
uSC09mEaMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAK6xZi+Y5
|
| 61 |
+
RNz7rUqI4GT/q8Py0s5wLwPlb7LE9TbWU2uHqx2LmQfIMI5Hcv2huHXWF6EWvWRz
|
| 62 |
+
kTBXrX39BUCGk9FJlrIL1HxkE4vTIUk4u/vozD4x8a57TCrfggajjgWEnH9wzsC7
|
| 63 |
+
RRffXWUM5FBIB0SLpC9W2sZ69mCNpDjxnYcWMLLwX3pCVSBxz8zuALESR79CueSz
|
| 64 |
+
tR0ZhLmYbeBptBVBteJQSMcf6pq3eZHd1dVTGfyuGGxp261ZKJtkmKc8x1WO0TAA
|
| 65 |
+
z9QynmKxwyruNSLGu/B8u4O4AIn13BqX2TiaKVNhGaan9DtH/d1nlQ+OpGYsgpq3
|
| 66 |
+
LXHm3674+GjBuw/qUKBFl7calRJvyLO2BWjaah4ONYWErHQMirT0dZ8ir7BUu7ae
|
| 67 |
+
IvnZ69WKDcfc+JgxX576xpf0QRB104G2MV963YiFCK9wRwI3e+JK7F3y3SkSRMiK
|
| 68 |
+
qt3SVXgXda9xaQ13cEqwH39C28dx3FjWGL1QxblyBMdne3xTYMpJGBW8QHOuK6gr
|
| 69 |
+
rG8RRDnsgkh+Ecr71j+2wLm4BpN1vZMndxcNXKWe6sFbAC0MqDVgx+JvNRs9drXn
|
| 70 |
+
rd10I0+GskfvyC/QhXw5ljehKykCvT6Hz6j2HXUyzzjjc7HuEIG1KrGIBlEeWjpI
|
| 71 |
+
UfM2WWLfQmZZULdYvvV2QJoSFuYOqtdsoNU=
|
| 72 |
+
-----END CERTIFICATE-----
|
signing/cert.pem
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
-----BEGIN CERTIFICATE-----
|
| 2 |
+
MIIG6TCCBNGgAwIBAgIQRH6DOxTQI6Hp8NKCckMm7DANBgkqhkiG9w0BAQsFADBo
|
| 3 |
+
MQswCQYDVQQGEwJHUjE3MDUGA1UECgwuSGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl
|
| 4 |
+
c2VhcmNoIEluc3RpdHV0aW9ucyBDQTEgMB4GA1UEAwwXSEFSSUNBIENvZGUgU2ln
|
| 5 |
+
bmluZyBSU0EwHhcNMjYwNTA4MDc1NjU1WhcNMjcwNTA4MDc1NjU1WjBlMQswCQYD
|
| 6 |
+
VQQGEwJOTzENMAsGA1UEBwwET3NsbzEcMBoGA1UECgwTTmFzam9uYWxiaWJsaW90
|
| 7 |
+
ZWtldDELMAkGA1UECwwCSVQxHDAaBgNVBAMME05hc2pvbmFsYmlibGlvdGVrZXQw
|
| 8 |
+
ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCgChY1uSq4zwWzCCPkSMVo
|
| 9 |
+
+nCvBwBvGIuew3AHO1EVDc2wCr0HMI6U0KP9/DrPbtPUMFVRFT7RHn3GN8wY9GKb
|
| 10 |
+
tSBqeiFdHOBTesPqoi5QGutvGJfjFXcODk8LtUcPwfj11rV20rupjK5XOWlRURDd
|
| 11 |
+
rHjPgnWqOe2LuQqhhtD6l/k63cCi3pC4//qC3txaiOhYujTZpCaUi/9jMvPVao5Z
|
| 12 |
+
1YTfFzIR8F6oAYXACIdyI8raltCVtqh0Fav/gY4oj2WNUFyluPHEuaKkief65JRQ
|
| 13 |
+
NprwC/XpwdZiVTLlAivngJ+HS+HDqtT4R2SQNkwpouM5g/Vdz6Oxi9v5LO4yeF1Z
|
| 14 |
+
zXxk5SM7CIS8dw4RVJH2+H0cc6OQg4G2RUhaFlQQwuGrGT6zWGRmav2lr+sNmhfT
|
| 15 |
+
9tgD9RVzzxPb9/lyEY3z5t/Aq9DTDp980qtloj4Wn6LUPmUv42tCLOdFU6BESOmI
|
| 16 |
+
G1Wgvxr8qGomxUAIlGABDGwekmaqVRBqpGkxvWvoSHgez/rYophyxBAx+nAdYo+O
|
| 17 |
+
xhk9d1ipzVUihCkQ6GNogRPpQ2N5ga6id0ULX+iDieU6xVA4lD8xoCkL38I64TxS
|
| 18 |
+
/8ixkiC604DAAQvfoP3mqmyCYbXLDnmyGFQ9S8cxbVD+OV+EWTY+GwGyfZ7A1fZF
|
| 19 |
+
o5+5ey8X4EfW3HA5/8SULQIDAQABo4IBkDCCAYwwCQYDVR0TBAIwADAfBgNVHSME
|
| 20 |
+
GDAWgBSp7DUU625nBQ7EbQkMoHIGIbTKLjBxBggrBgEFBQcBAQRlMGMwPgYIKwYB
|
| 21 |
+
BQUHMAKGMmh0dHA6Ly9jcnQuaGFyaWNhLmdyL0hBUklDQS1Db2RlU2lnbmluZy1T
|
| 22 |
+
dWItUjEuY2VyMCEGCCsGAQUFBzABhhVodHRwOi8vb2NzcC5oYXJpY2EuZ3IwYgYD
|
| 23 |
+
VR0gBFswWTAIBgZngQwBBAEwCAYGBACPegECMEMGDSsGAQQBgc8RAQEDAQIwMjAw
|
| 24 |
+
BggrBgEFBQcCARYkaHR0cHM6Ly9yZXBvLmhhcmljYS5nci9kb2N1bWVudHMvQ1BT
|
| 25 |
+
MBMGA1UdJQQMMAoGCCsGAQUFBwMDMEMGA1UdHwQ8MDowOKA2oDSGMmh0dHA6Ly9j
|
| 26 |
+
cmwuaGFyaWNhLmdyL0hBUklDQS1Db2RlU2lnbmluZy1TdWItUjEuY3JsMB0GA1Ud
|
| 27 |
+
DgQWBBRkiwQILl9eSkYw+Nbx5KokmIBoUjAOBgNVHQ8BAf8EBAMCB4AwDQYJKoZI
|
| 28 |
+
hvcNAQELBQADggIBABE2vKd3Q6JMFSxZUXr/kH88h40CsVG5mZ0Hr3tgm9iITjzY
|
| 29 |
+
6ICVO2YPQXKn7Bt6hddsDWEVjQgYGArAxFV0rS9/Olr1YKdYOE/ANF7TGvbGCcVE
|
| 30 |
+
qNIisEuHqoah406LW6Om+nSlIzizpiKWPcm4RSL0LQrwNj/Z31aNAbQNKu97eI3x
|
| 31 |
+
uy6ZAU1xrRbRy5HNxbmXJGfy84wvogaGqHsWkYtbPL/uqzWJoj/yxLKl7YKiyfZ0
|
| 32 |
+
h604HpGlv8Xq6CjgMWTmHyGgxIIX+EBd3tvPpGHdswGvGhX8HFkBjH2uWAmFdYbI
|
| 33 |
+
DMTyqh4UzV3WLguaHWHsZ9QzFOcETXOFTwmH5NCckeGGaaPVxjuuAu9jqyenU84k
|
| 34 |
+
a8rZ1qmFJzUNbjrWXK9pjsLxY+ePMu0UW9dnNGppsPCh9Ac7gBzHHDj3pQMZvIWN
|
| 35 |
+
UKMmMw/a6hKV6VYnmYRJa3K0nEXObJv53vgEEF0H9WePUEcFAp9VKDeTGULWyT+b
|
| 36 |
+
6iaWQqgXlkWz3isiaJgmYnyqct//aXOo+HP4TRmM6Azpd3/IlTal9T400rzc2OkQ
|
| 37 |
+
V89AmB9F8G7ZuHduRA/TKhKL/xFq+rQs0G2S41IgqTRX0Ss6wgNv/pBDWr+3kYgV
|
| 38 |
+
4M7Vr6zpk7ZogqJKcXZpwnegxchSdjMn62WESKM636yJYdsZAikCs8T+sopK
|
| 39 |
+
-----END CERTIFICATE-----
|
signing/verify.sh
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/bin/bash
|
| 2 |
+
#
|
| 3 |
+
# Verify the integrity and authenticity of this model release.
|
| 4 |
+
#
|
| 5 |
+
# Usage: bash signing/verify.sh
|
| 6 |
+
#
|
| 7 |
+
# This script verifies:
|
| 8 |
+
# 1. The signing certificate is issued by a trusted CA
|
| 9 |
+
# 2. The SHA256SUMS manifest was signed by Nasjonalbiblioteket
|
| 10 |
+
# 3. All file checksums match the manifest
|
| 11 |
+
#
|
| 12 |
+
|
| 13 |
+
set -euo pipefail
|
| 14 |
+
|
| 15 |
+
RED='\033[0;31m'
|
| 16 |
+
GREEN='\033[0;32m'
|
| 17 |
+
NC='\033[0m'
|
| 18 |
+
|
| 19 |
+
pass() { echo -e "${GREEN}[PASS]${NC} $*"; }
|
| 20 |
+
fail() { echo -e "${RED}[FAIL]${NC} $*" >&2; }
|
| 21 |
+
|
| 22 |
+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
| 23 |
+
MODEL_DIR="$(dirname "$SCRIPT_DIR")"
|
| 24 |
+
SIGNING_DIR="$SCRIPT_DIR"
|
| 25 |
+
|
| 26 |
+
cd "$MODEL_DIR"
|
| 27 |
+
|
| 28 |
+
errors=0
|
| 29 |
+
|
| 30 |
+
# Check required files exist
|
| 31 |
+
for f in "$SIGNING_DIR/SHA256SUMS" "$SIGNING_DIR/SHA256SUMS.sig" \
|
| 32 |
+
"$SIGNING_DIR/cert.pem" "$SIGNING_DIR/ca-chain.pem"; do
|
| 33 |
+
if [[ ! -f "$f" ]]; then
|
| 34 |
+
fail "Missing file: $f"
|
| 35 |
+
errors=$((errors + 1))
|
| 36 |
+
fi
|
| 37 |
+
done
|
| 38 |
+
|
| 39 |
+
if [[ $errors -gt 0 ]]; then
|
| 40 |
+
echo ""
|
| 41 |
+
fail "Required signing files are missing. Cannot verify."
|
| 42 |
+
exit 1
|
| 43 |
+
fi
|
| 44 |
+
|
| 45 |
+
echo "=== Nasjonalbiblioteket Model Verification ==="
|
| 46 |
+
echo ""
|
| 47 |
+
|
| 48 |
+
# Show certificate info
|
| 49 |
+
echo "Certificate subject:"
|
| 50 |
+
openssl x509 -in "$SIGNING_DIR/cert.pem" -subject -noout 2>/dev/null | sed 's/^subject=/ /'
|
| 51 |
+
echo "Certificate issuer:"
|
| 52 |
+
openssl x509 -in "$SIGNING_DIR/cert.pem" -issuer -noout 2>/dev/null | sed 's/^issuer=/ /'
|
| 53 |
+
echo "Certificate fingerprint (SHA-256):"
|
| 54 |
+
openssl x509 -in "$SIGNING_DIR/cert.pem" -fingerprint -sha256 -noout 2>/dev/null | sed 's/^.*=/ /'
|
| 55 |
+
echo ""
|
| 56 |
+
|
| 57 |
+
# 1. Verify certificate chain
|
| 58 |
+
echo "--- Step 1: Verify certificate chain ---"
|
| 59 |
+
if openssl verify -CAfile "$SIGNING_DIR/ca-chain.pem" "$SIGNING_DIR/cert.pem" > /dev/null 2>&1; then
|
| 60 |
+
pass "Certificate chain is valid."
|
| 61 |
+
else
|
| 62 |
+
fail "Certificate chain verification failed!"
|
| 63 |
+
errors=$((errors + 1))
|
| 64 |
+
fi
|
| 65 |
+
|
| 66 |
+
# 2. Verify signature
|
| 67 |
+
echo "--- Step 2: Verify manifest signature ---"
|
| 68 |
+
PUBKEY=$(mktemp)
|
| 69 |
+
trap "rm -f '$PUBKEY'" EXIT
|
| 70 |
+
openssl x509 -in "$SIGNING_DIR/cert.pem" -pubkey -noout > "$PUBKEY" 2>/dev/null
|
| 71 |
+
|
| 72 |
+
if openssl dgst -sha256 -verify "$PUBKEY" \
|
| 73 |
+
-signature "$SIGNING_DIR/SHA256SUMS.sig" \
|
| 74 |
+
"$SIGNING_DIR/SHA256SUMS" > /dev/null 2>&1; then
|
| 75 |
+
pass "Manifest signature is valid."
|
| 76 |
+
else
|
| 77 |
+
fail "Manifest signature verification failed!"
|
| 78 |
+
errors=$((errors + 1))
|
| 79 |
+
fi
|
| 80 |
+
|
| 81 |
+
# 3. Verify file checksums
|
| 82 |
+
echo "--- Step 3: Verify file checksums ---"
|
| 83 |
+
if sha256sum -c "$SIGNING_DIR/SHA256SUMS" 2>/dev/null; then
|
| 84 |
+
pass "All file checksums match."
|
| 85 |
+
else
|
| 86 |
+
fail "One or more file checksums do not match!"
|
| 87 |
+
errors=$((errors + 1))
|
| 88 |
+
fi
|
| 89 |
+
|
| 90 |
+
# Summary
|
| 91 |
+
echo ""
|
| 92 |
+
if [[ $errors -eq 0 ]]; then
|
| 93 |
+
echo -e "${GREEN}✅ Verification successful. All files are authentic and unmodified.${NC}"
|
| 94 |
+
exit 0
|
| 95 |
+
else
|
| 96 |
+
echo -e "${RED}❌ Verification failed with $errors error(s).${NC}"
|
| 97 |
+
exit 1
|
| 98 |
+
fi
|
special_tokens_map.json
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"boi_token": "<start_of_image>",
|
| 3 |
+
"bos_token": {
|
| 4 |
+
"content": "<bos>",
|
| 5 |
+
"lstrip": false,
|
| 6 |
+
"normalized": false,
|
| 7 |
+
"rstrip": false,
|
| 8 |
+
"single_word": false
|
| 9 |
+
},
|
| 10 |
+
"eoi_token": "<end_of_image>",
|
| 11 |
+
"eos_token": {
|
| 12 |
+
"content": "<eos>",
|
| 13 |
+
"lstrip": false,
|
| 14 |
+
"normalized": false,
|
| 15 |
+
"rstrip": false,
|
| 16 |
+
"single_word": false
|
| 17 |
+
},
|
| 18 |
+
"image_token": "<image_soft_token>",
|
| 19 |
+
"pad_token": {
|
| 20 |
+
"content": "<pad>",
|
| 21 |
+
"lstrip": false,
|
| 22 |
+
"normalized": false,
|
| 23 |
+
"rstrip": false,
|
| 24 |
+
"single_word": false
|
| 25 |
+
},
|
| 26 |
+
"unk_token": {
|
| 27 |
+
"content": "<unk>",
|
| 28 |
+
"lstrip": false,
|
| 29 |
+
"normalized": false,
|
| 30 |
+
"rstrip": false,
|
| 31 |
+
"single_word": false
|
| 32 |
+
}
|
| 33 |
+
}
|
tokenizer.json
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:daab2354f8a74e70d70b4d1f804939b68a8c9624dd06cb7858e52dd8970e9726
|
| 3 |
+
size 33384567
|
tokenizer.model
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:1299c11d7cf632ef3b4e11937501358ada021bbdf7c47638d13c0ee982f2e79c
|
| 3 |
+
size 4689074
|
tokenizer_config.json
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"backend": "tokenizers",
|
| 3 |
+
"boi_token": "<start_of_image>",
|
| 4 |
+
"bos_token": "<bos>",
|
| 5 |
+
"clean_up_tokenization_spaces": false,
|
| 6 |
+
"eoi_token": "<end_of_image>",
|
| 7 |
+
"eos_token": "<end_of_turn>",
|
| 8 |
+
"image_token": "<image_soft_token>",
|
| 9 |
+
"is_local": false,
|
| 10 |
+
"local_files_only": false,
|
| 11 |
+
"mask_token": "<mask>",
|
| 12 |
+
"model_max_length": 1000000000000000019884624838656,
|
| 13 |
+
"model_specific_special_tokens": {
|
| 14 |
+
"boi_token": "<start_of_image>",
|
| 15 |
+
"eoi_token": "<end_of_image>",
|
| 16 |
+
"image_token": "<image_soft_token>"
|
| 17 |
+
},
|
| 18 |
+
"pad_token": "<pad>",
|
| 19 |
+
"padding_side": "right",
|
| 20 |
+
"processor_class": "Gemma3Processor",
|
| 21 |
+
"sp_model_kwargs": null,
|
| 22 |
+
"spaces_between_special_tokens": false,
|
| 23 |
+
"split_special_tokens": false,
|
| 24 |
+
"tokenizer_class": "GemmaTokenizer",
|
| 25 |
+
"unk_token": "<unk>",
|
| 26 |
+
"use_default_system_prompt": false
|
| 27 |
+
}
|