Upload 8 files
Browse files- LICENSE.md +36 -0
- README.md +57 -0
- adapter_config.json +51 -0
- adapter_model.safetensors +3 -0
- chat_template.jinja +184 -0
- tokenizer.json +0 -0
- tokenizer_config.json +15 -0
- training_args.bin +3 -0
LICENSE.md
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# JOA Model License, version 1.0
|
| 2 |
+
|
| 3 |
+
**Status: in effect from 24 October 2026.** This licence governs the model weights published in this repository.
|
| 4 |
+
|
| 5 |
+
Licensor: Loukas Tzekos, trading as Job Opportunities API (JOA), sole proprietorship, Didaskalisis Papathanasiou Vas. 79, 54629 Thessaloniki, Greece, VAT EL117613696. Legal matters: luca@tzekos.eu.
|
| 6 |
+
|
| 7 |
+
"The Model" means the weights and adapters of JOA Small (and of JOA Small, JOA Advance and JOA Deep generally) as released by the Licensor, and any files released with them. "Derivative" means any model or adapter made from the Model, for example by fine-tuning, merging, quantising or distillation.
|
| 8 |
+
|
| 9 |
+
## 1. What you may do
|
| 10 |
+
|
| 11 |
+
You may use, copy, modify, fine-tune, merge, quantise, distribute and sell the Model and Derivatives, and use them in any product or service, including commercial and hosted services. The licence is free of charge, worldwide, non-exclusive and lasts as long as the rights it covers.
|
| 12 |
+
|
| 13 |
+
## 2. Conditions
|
| 14 |
+
|
| 15 |
+
These conditions apply when you distribute the Model or a Derivative, or make a product or service that uses them available to anyone outside your own organisation (including through an app, website or hosted API). Purely internal use has no conditions beyond sections 2.4 and 3.
|
| 16 |
+
|
| 17 |
+
1. **Keep the base model's licence.** The Model is built on a base model licensed under the Apache License, Version 2.0. Include that licence and any copyright and NOTICE text of the base model, and state that the weights were modified. Nothing in this licence limits the rights you have in the base model itself, obtained from its publisher, under its own licence.
|
| 18 |
+
2. **Give visible credit.** Display the line "Built with JOA Small by Job Opportunities API" with a link to https://jobopportunitiesapi.org, where users of your product or service can see it: in its documentation, its about page or its user interface. If you publish a Derivative, put the same line and link in its model card or README.
|
| 19 |
+
3. **Pass this licence on.** Include a copy of this licence with every copy of the Model or a Derivative you distribute. You may license your own changes on your own terms, but these conditions continue to apply to the parts that come from the Model.
|
| 20 |
+
4. **No implied endorsement.** You may say that your work is based on JOA Small. Do not name or present it in a way that suggests Job Opportunities API, IBM, Alibaba Cloud or the Qwen team made, endorse or support it. This licence grants no trademark rights.
|
| 21 |
+
|
| 22 |
+
## 3. Outputs
|
| 23 |
+
|
| 24 |
+
What you generate with the Model is yours. This licence puts no conditions on outputs.
|
| 25 |
+
|
| 26 |
+
## 4. Ending and restoring the licence
|
| 27 |
+
|
| 28 |
+
If you break a condition, your rights under this licence end automatically. They come back if you fix the breach within 30 days of becoming aware of it.
|
| 29 |
+
|
| 30 |
+
## 5. No warranty
|
| 31 |
+
|
| 32 |
+
The Model is provided "as is", without warranty of any kind. To the extent permitted by law, the Licensor is not liable for any damage arising from its use.
|
| 33 |
+
|
| 34 |
+
## 6. Law
|
| 35 |
+
|
| 36 |
+
This licence is governed by Greek law. This does not remove any rights consumers have under the law of their own country.
|
README.md
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
license: other
|
| 3 |
+
license_name: joa-model-license
|
| 4 |
+
license_link: LICENSE.md
|
| 5 |
+
base_model: ibm-granite/granite-4.2-3b
|
| 6 |
+
base_model_relation: adapter
|
| 7 |
+
pipeline_tag: text-generation
|
| 8 |
+
tags:
|
| 9 |
+
- information-extraction
|
| 10 |
+
- job-postings
|
| 11 |
+
- lora
|
| 12 |
+
---
|
| 13 |
+
|
| 14 |
+
# JOA Small v2: job-posting extraction model
|
| 15 |
+
|
| 16 |
+
*Disclosure: Job Opportunities API (JOA, jobopportunitiesapi.org) is an independent data business that sells API access to job-posting data. AI helped run the experiments, check the numbers and draft this text; Loukas (Luca) Tzekos is editorially responsible. Contact: hello@jobopportunitiesapi.org.*
|
| 17 |
+
|
| 18 |
+
**Status (24 October 2026): weights released.** This is a second-pass retrain of JOA Small, trained 10 to 18 October 2026 on the same recipe as the first release. The model was trained and evaluated, and the evaluation below is unchanged from 6 October 2026. The weights are in this repository under the JOA Model License (LICENSE.md): any use, including commercial, with visible credit and a link.
|
| 19 |
+
|
| 20 |
+
## What it does
|
| 21 |
+
|
| 22 |
+
JOA Small reads the text of one job posting and returns 11 structured fields as JSON: title, company, location, salary currency, minimum, maximum and period, seniority, remote type, posted date, and whether the poster is a staffing agency. It leaves a field empty when the posting does not state it. It answers directly, without a long reasoning trace.
|
| 23 |
+
|
| 24 |
+
## How it was made
|
| 25 |
+
|
| 26 |
+
- **Base model:** [ibm-granite/granite-4.2-3b](https://huggingface.co/ibm-granite/granite-4.2-3b) by IBM, licensed Apache 2.0.
|
| 27 |
+
- **Method:** LoRA adapter (rank 16), one epoch, 80,000 training examples.
|
| 28 |
+
- **Training data:** fields extracted by Qwen/Qwen3.5-27B (Apache 2.0) from job postings collected by Job Opportunities API (JOA), kept only when grounded in the posting text (for example, a title or salary that actually appears in it). The 250 arena listings and the 250 verification listings were excluded.
|
| 29 |
+
- **Compute:** This work used the EuroHPC supercomputer Discoverer+ in Bulgaria, made available by the EuroHPC Joint Undertaking through an AI Factories Playground access allocation (project EHPC-AIF-2026PG01-1124).
|
| 30 |
+
|
| 31 |
+
## Results
|
| 32 |
+
|
| 33 |
+
**These weights have not been re-graded on the extraction arena.**
|
| 34 |
+
|
| 35 |
+
The v1 release of this model was graded on 250 real job listings against two judge models, and those numbers are published on the v1 card. They are claims about the v1 weights only. Until we run the arena again on this variant, its quality is genuinely unknown, and we will not put a number on it that we have not measured.
|
| 36 |
+
|
| 37 |
+
If you need a model with a published score today, use the v1 release. If you want to help us grade this one, the arena is open: https://huggingface.co/datasets/JobOpportunitiesAPI/joa-extraction-arena
|
| 38 |
+
|
| 39 |
+
## Licence
|
| 40 |
+
|
| 41 |
+
The weights are licensed under the **JOA Model License** (LICENSE.md in this repository):
|
| 42 |
+
|
| 43 |
+
- You may use, modify, fine-tune, redistribute and sell JOA Small, including in commercial and hosted products.
|
| 44 |
+
- If you distribute it, or make a product or service that uses it available to others, show "Built with JOA Small v2 by Job Opportunities API" with a link to https://jobopportunitiesapi.org in your documentation, about page or user interface, and in the model card of any derivative.
|
| 45 |
+
- Keep the base model's Apache 2.0 licence and notices.
|
| 46 |
+
- Do not imply endorsement.
|
| 47 |
+
|
| 48 |
+
## Attribution
|
| 49 |
+
|
| 50 |
+
JOA Small v2 is a fine-tune of ibm-granite/granite-4.2-3b by IBM, used under the Apache License 2.0. It is not made, endorsed or supported by IBM. Built by Job Opportunities API (JOA), https://jobopportunitiesapi.org.
|
| 51 |
+
|
| 52 |
+
## Contact
|
| 53 |
+
|
| 54 |
+
- General: hello@jobopportunitiesapi.org
|
| 55 |
+
- Legal matters: luca@tzekos.eu
|
| 56 |
+
- Phone: +30 2311 113 603
|
| 57 |
+
- Job Opportunities API (JOA) is a sole proprietorship of Loukas Tzekos, Didaskalisis Papathanasiou Vas. 79, 54629 Thessaloniki, Greece. VAT EL117613696.
|
adapter_config.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"alora_invocation_tokens": null,
|
| 3 |
+
"alpha_pattern": {},
|
| 4 |
+
"arrow_config": null,
|
| 5 |
+
"auto_mapping": null,
|
| 6 |
+
"base_model_name_or_path": "/valhalla/projects/ehpc-aif-2026pg01-1124/models/arena/ibm-granite__granite-4.2-3b",
|
| 7 |
+
"bias": "none",
|
| 8 |
+
"corda_config": null,
|
| 9 |
+
"ensure_weight_tying": false,
|
| 10 |
+
"eva_config": null,
|
| 11 |
+
"exclude_modules": null,
|
| 12 |
+
"fan_in_fan_out": false,
|
| 13 |
+
"inference_mode": true,
|
| 14 |
+
"init_lora_weights": true,
|
| 15 |
+
"kasa_config": null,
|
| 16 |
+
"layer_replication": null,
|
| 17 |
+
"layers_pattern": null,
|
| 18 |
+
"layers_to_transform": null,
|
| 19 |
+
"loftq_config": {},
|
| 20 |
+
"lora_alpha": 32,
|
| 21 |
+
"lora_bias": false,
|
| 22 |
+
"lora_dropout": 0.05,
|
| 23 |
+
"lora_ga_config": null,
|
| 24 |
+
"megatron_config": null,
|
| 25 |
+
"megatron_core": "megatron.core",
|
| 26 |
+
"modules_to_save": null,
|
| 27 |
+
"monteclora_config": null,
|
| 28 |
+
"peft_type": "LORA",
|
| 29 |
+
"peft_version": "0.21.0",
|
| 30 |
+
"qalora_group_size": 16,
|
| 31 |
+
"r": 16,
|
| 32 |
+
"rank_pattern": {},
|
| 33 |
+
"revision": null,
|
| 34 |
+
"target_modules": [
|
| 35 |
+
"up_proj",
|
| 36 |
+
"o_proj",
|
| 37 |
+
"v_proj",
|
| 38 |
+
"down_proj",
|
| 39 |
+
"gate_proj",
|
| 40 |
+
"k_proj",
|
| 41 |
+
"q_proj"
|
| 42 |
+
],
|
| 43 |
+
"target_parameters": null,
|
| 44 |
+
"task_type": "CAUSAL_LM",
|
| 45 |
+
"trainable_token_indices": null,
|
| 46 |
+
"use_bdlora": null,
|
| 47 |
+
"use_dora": false,
|
| 48 |
+
"use_qalora": false,
|
| 49 |
+
"use_rslora": false,
|
| 50 |
+
"velora_config": null
|
| 51 |
+
}
|
adapter_model.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:f28fdde412e9c808cdd82118cfbbc8805603e86ce61098f05e846421d4dbb1f7
|
| 3 |
+
size 124593064
|
chat_template.jinja
ADDED
|
@@ -0,0 +1,184 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{%- macro tool_to_json(tool) -%}
|
| 2 |
+
{%- set ns_tool = namespace(first=true) -%}
|
| 3 |
+
{{- '{' -}}
|
| 4 |
+
{%- for k, v in tool.items() -%}
|
| 5 |
+
{%- if k != 'defer_loading' and k != 'strict' -%}
|
| 6 |
+
{%- if not ns_tool.first -%}{{- ', ' -}}{%- endif -%}
|
| 7 |
+
{%- set ns_tool.first = false -%}
|
| 8 |
+
{{- '"' ~ k ~ '": ' ~ (v | tojson(ensure_ascii=False)) -}}
|
| 9 |
+
{%- endif -%}
|
| 10 |
+
{%- endfor -%}
|
| 11 |
+
{{- '}' -}}
|
| 12 |
+
{%- endmacro -%}
|
| 13 |
+
{%- set enable_thinking = enable_thinking if enable_thinking is defined else True %}
|
| 14 |
+
{%- set low_effort = low_effort if low_effort is defined else False %}
|
| 15 |
+
{%- if reasoning_effort is defined and reasoning_effort is not none %}
|
| 16 |
+
{%- set low_effort = reasoning_effort == "low" %}
|
| 17 |
+
{%- endif %}
|
| 18 |
+
{%- set truncate_history_thinking = truncate_history_thinking if truncate_history_thinking is defined else True %}
|
| 19 |
+
|
| 20 |
+
{%- set ns = namespace(last_user_idx = -1) %}
|
| 21 |
+
{%- set loop_messages = messages %}
|
| 22 |
+
{%- for m in loop_messages %}
|
| 23 |
+
{%- if m["role"] == "user" %}
|
| 24 |
+
{%- set ns.last_user_idx = loop.index0 %}
|
| 25 |
+
{%- endif %}
|
| 26 |
+
{%- endfor %}
|
| 27 |
+
|
| 28 |
+
{%- if messages[0]["role"] == "system" %}
|
| 29 |
+
{%- set system_message = messages[0]["content"] %}
|
| 30 |
+
{%- set loop_messages = messages[1:] %}
|
| 31 |
+
{%- else %}
|
| 32 |
+
{%- set system_message = "" %}
|
| 33 |
+
{%- set loop_messages = messages %}
|
| 34 |
+
{%- endif %}
|
| 35 |
+
{%- if not tools is defined %}
|
| 36 |
+
{%- set tools = [] %}
|
| 37 |
+
{%- endif %}
|
| 38 |
+
{# Recompute last_user_idx relative to loop_messages after handling system #}
|
| 39 |
+
{%- set ns = namespace(last_user_idx = -1) %}
|
| 40 |
+
{%- for m in loop_messages %}
|
| 41 |
+
{%- if m["role"] == "user" %}
|
| 42 |
+
{%- set ns.last_user_idx = loop.index0 %}
|
| 43 |
+
{%- endif %}
|
| 44 |
+
{%- endfor %}
|
| 45 |
+
{%- if system_message is defined %}
|
| 46 |
+
{{- "<|im_start|>system\n" + system_message }}
|
| 47 |
+
{%- else %}
|
| 48 |
+
{%- if tools is iterable and tools | length > 0 %}
|
| 49 |
+
{{- "<|im_start|>system\n" }}
|
| 50 |
+
{%- endif %}
|
| 51 |
+
{%- endif %}
|
| 52 |
+
{%- if tools is iterable and tools | length > 0 %}
|
| 53 |
+
{%- if system_message is defined and system_message | length > 0 %}
|
| 54 |
+
{{- "\n\n" }}
|
| 55 |
+
{%- endif %}
|
| 56 |
+
{{- "# Tools\n\nYou have access to the following functions:\n\n" }}
|
| 57 |
+
{{- "<tools>" }}
|
| 58 |
+
{%- for tool in tools %}
|
| 59 |
+
{%- if tool.function is defined %}
|
| 60 |
+
{%- set tool = tool.function %}
|
| 61 |
+
{%- endif %}
|
| 62 |
+
{%- if tool.defer_loading is not defined or not tool.defer_loading %}
|
| 63 |
+
{{- '\n' ~ tool_to_json(tool) }}
|
| 64 |
+
{%- endif %}
|
| 65 |
+
{%- endfor %}
|
| 66 |
+
{{- "\n</tools>" }}
|
| 67 |
+
|
| 68 |
+
{{- '\n\nIf you choose to call a function ONLY reply in the following format with NO suffix:\n\n<tool_call>\n<function=example_function_name>\n<parameter=example_parameter_1>\nvalue_1\n</parameter>\n<parameter=example_parameter_2>\nThis is the value for the second parameter\nthat can span\nmultiple lines\n</parameter>\n</function>\n</tool_call>\n\n<IMPORTANT>\nReminder:\n- Function calls MUST follow the specified format: an inner <function=...></function> block must be nested within <tool_call></tool_call> XML tags\n- Required parameters MUST be specified\n- You may provide optional reasoning for your function call in natural language BEFORE the function call, but NOT after\n- If there is no function call available, answer the question like normal with your current knowledge and do not tell the user about function calls\n</IMPORTANT>' }}
|
| 69 |
+
{%- endif %}
|
| 70 |
+
|
| 71 |
+
|
| 72 |
+
{%- if system_message is defined %}
|
| 73 |
+
{{- '<|im_end|>\n' }}
|
| 74 |
+
{%- else %}
|
| 75 |
+
{%- if tools is iterable and tools | length > 0 %}
|
| 76 |
+
{{- '<|im_end|>\n' }}
|
| 77 |
+
{%- endif %}
|
| 78 |
+
{%- endif %}
|
| 79 |
+
|
| 80 |
+
{%- for message in loop_messages %}
|
| 81 |
+
{%- if message.role == "assistant" %}
|
| 82 |
+
{# Add reasoning content in to content field for unified processing below. #}
|
| 83 |
+
{%- if message.reasoning_content is defined and message.reasoning_content is string and message.reasoning_content | trim | length > 0 %}
|
| 84 |
+
{%- set content = "<think>\n" ~ message.reasoning_content ~ "\n</think>\n" ~ (message.content | default('', true)) %}
|
| 85 |
+
{%- else %}
|
| 86 |
+
{%- set content = message.content | default('', true) %}
|
| 87 |
+
{%- if content is string -%}
|
| 88 |
+
{# Allow downstream logic to to take care of broken thought, only handle coherent reasoning here. #}
|
| 89 |
+
{%- if '<think>' not in content and '</think>' not in content -%}
|
| 90 |
+
{%- set content = "<think></think>" ~ content -%}
|
| 91 |
+
{%- endif -%}
|
| 92 |
+
{%- else -%}
|
| 93 |
+
{%- set content = content -%}
|
| 94 |
+
{%- endif -%}
|
| 95 |
+
{%- endif %}
|
| 96 |
+
{%- if message.tool_calls is defined and message.tool_calls is iterable and message.tool_calls | length > 0 %}
|
| 97 |
+
{# Assistant message has tool calls. #}
|
| 98 |
+
{{- '<|im_start|>assistant\n' }}
|
| 99 |
+
{%- set include_content = not (truncate_history_thinking and loop.index0 < ns.last_user_idx) %}
|
| 100 |
+
{%- if content is string and content | trim | length > 0 %}
|
| 101 |
+
{%- if include_content %}
|
| 102 |
+
{{- (content | trim) ~ '\n' -}}
|
| 103 |
+
{%- else %}
|
| 104 |
+
{%- set c = (content | string) %}
|
| 105 |
+
{%- if '</think>' in c %}
|
| 106 |
+
{# Keep only content after the last closing think. Also generation prompt causes this. #}
|
| 107 |
+
{%- set c = c.split('</think>')[-1] %}
|
| 108 |
+
{%- elif '<think>' in c %}
|
| 109 |
+
{# If <think> was opened but never closed, drop the trailing think segment #}
|
| 110 |
+
{%- set c = c.split('<think>')[0] %}
|
| 111 |
+
{%- endif %}
|
| 112 |
+
{%- set c = "<think></think>" ~ c | trim %}
|
| 113 |
+
{%- if c | length > 0 %}
|
| 114 |
+
{{- c ~ '\n' -}}
|
| 115 |
+
{%- endif %}
|
| 116 |
+
{%- endif %}
|
| 117 |
+
{%- else %}
|
| 118 |
+
{{- "<think></think>" -}}
|
| 119 |
+
{%- endif %}
|
| 120 |
+
{%- for tool_call in message.tool_calls %}
|
| 121 |
+
{%- if tool_call.function is defined %}
|
| 122 |
+
{%- set tool_call = tool_call.function %}
|
| 123 |
+
{%- endif %}
|
| 124 |
+
{{- '<tool_call>\n<function=' ~ tool_call.name ~ '>\n' -}}
|
| 125 |
+
{%- if tool_call.arguments is defined %}
|
| 126 |
+
{%- for args_name, args_value in tool_call.arguments|items %}
|
| 127 |
+
{{- '<parameter=' ~ args_name ~ '>\n' -}}
|
| 128 |
+
{%- set args_value = args_value | tojson | safe if args_value is mapping or (args_value is sequence and args_value is not string) else args_value | string %}
|
| 129 |
+
{{- args_value ~ '\n</parameter>\n' -}}
|
| 130 |
+
{%- endfor %}
|
| 131 |
+
{%- endif %}
|
| 132 |
+
{{- '</function>\n</tool_call>\n' -}}
|
| 133 |
+
{%- endfor %}
|
| 134 |
+
{{- '<|im_end|>\n' }}
|
| 135 |
+
{%- else %}
|
| 136 |
+
{# Assistant message doesn't have tool calls. #}
|
| 137 |
+
{%- if not (truncate_history_thinking and loop.index0 < ns.last_user_idx) %}
|
| 138 |
+
{{- '<|im_start|>assistant\n' ~ (content | default('', true) | string | trim) ~ '<|im_end|>\n' }}
|
| 139 |
+
{%- else %}
|
| 140 |
+
{%- set c = (content | default('', true) | string) %}
|
| 141 |
+
{%- if '<think>' in c and '</think>' in c %}
|
| 142 |
+
{%- set c = "<think></think>" ~ c.split('</think>')[-1] %}
|
| 143 |
+
{%- endif %}
|
| 144 |
+
{%- set c = c | trim %}
|
| 145 |
+
{%- if c | length > 0 %}
|
| 146 |
+
{{- '<|im_start|>assistant\n' ~ c ~ '<|im_end|>\n' }}
|
| 147 |
+
{%- else %}
|
| 148 |
+
{{- '<|im_start|>assistant\n<|im_end|>\n' }}
|
| 149 |
+
{%- endif %}
|
| 150 |
+
{%- endif %}
|
| 151 |
+
{%- endif %}
|
| 152 |
+
{%- elif message.role == "user" or message.role == "system" %}
|
| 153 |
+
{{- '<|im_start|>' + message.role + '\n' }}
|
| 154 |
+
{%- set content = message.content | string %}
|
| 155 |
+
{%- if message.role == "user" and loop.index0 == ns.last_user_idx and low_effort %}
|
| 156 |
+
{{- content + '\n\n{reasoning effort: low}' }}
|
| 157 |
+
{%- else %}
|
| 158 |
+
{{- content }}
|
| 159 |
+
{%- endif %}
|
| 160 |
+
{{- '<|im_end|>\n' }}
|
| 161 |
+
{%- elif message.role == "tool" %}
|
| 162 |
+
{%- if loop.previtem and loop.previtem.role != "tool" %}
|
| 163 |
+
{{- '<|im_start|>user\n' }}
|
| 164 |
+
{%- endif %}
|
| 165 |
+
{{- '<tool_response>\n' }}
|
| 166 |
+
{{- message.content }}
|
| 167 |
+
{{- '\n</tool_response>\n' }}
|
| 168 |
+
{%- if not loop.last and loop.nextitem.role != "tool" %}
|
| 169 |
+
{{- '<|im_end|>\n' }}
|
| 170 |
+
{%- elif loop.last %}
|
| 171 |
+
{{- '<|im_end|>\n' }}
|
| 172 |
+
{%- endif %}
|
| 173 |
+
{%- else %}
|
| 174 |
+
{{- '<|im_start|>' + message.role + '\n' + message.content + '<|im_end|>\n' }}
|
| 175 |
+
{%- endif %}
|
| 176 |
+
{%- endfor %}
|
| 177 |
+
|
| 178 |
+
{%- if add_generation_prompt %}
|
| 179 |
+
{%- if enable_thinking %}
|
| 180 |
+
{{- '<|im_start|>assistant\n<think>\n' }}
|
| 181 |
+
{%- else %}
|
| 182 |
+
{{- '<|im_start|>assistant\n<think></think>' }}
|
| 183 |
+
{%- endif %}
|
| 184 |
+
{%- endif %}
|
tokenizer.json
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
tokenizer_config.json
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"add_prefix_space": false,
|
| 3 |
+
"backend": "tokenizers",
|
| 4 |
+
"bos_token": "<s>",
|
| 5 |
+
"clean_up_tokenization_spaces": false,
|
| 6 |
+
"eos_token": "<|im_end|>",
|
| 7 |
+
"errors": "replace",
|
| 8 |
+
"is_local": true,
|
| 9 |
+
"local_files_only": true,
|
| 10 |
+
"model_max_length": 1000000000000000019884624838656,
|
| 11 |
+
"pad_token": "<|im_end|>",
|
| 12 |
+
"padding_side": "left",
|
| 13 |
+
"tokenizer_class": "TokenizersBackend",
|
| 14 |
+
"unk_token": "<unk>"
|
| 15 |
+
}
|
training_args.bin
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:49688a841f6f647d1c2ec858d34f9daefa37607c01d2aedff385b6ef84b77980
|
| 3 |
+
size 5265
|