allsmart commited on
Commit
fdf218c
·
verified ·
1 Parent(s): 7ed7cee

Erste Fassung

Browse files
Files changed (10) hide show
  1. .gitattributes +1 -0
  2. LICENSE +202 -0
  3. README.md +153 -0
  4. beispiel.py +91 -0
  5. config.json +78 -0
  6. intent.json +68 -0
  7. koepfe.safetensors +3 -0
  8. model.safetensors +3 -0
  9. tokenizer.json +3 -0
  10. tokenizer_config.json +25 -0
.gitattributes CHANGED
@@ -33,3 +33,4 @@ saved_model/**/* 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
 
 
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
LICENSE ADDED
@@ -0,0 +1,202 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ Apache License
3
+ Version 2.0, January 2004
4
+ http://www.apache.org/licenses/
5
+
6
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7
+
8
+ 1. Definitions.
9
+
10
+ "License" shall mean the terms and conditions for use, reproduction,
11
+ and distribution as defined by Sections 1 through 9 of this document.
12
+
13
+ "Licensor" shall mean the copyright owner or entity authorized by
14
+ the copyright owner that is granting the License.
15
+
16
+ "Legal Entity" shall mean the union of the acting entity and all
17
+ other entities that control, are controlled by, or are under common
18
+ control with that entity. For the purposes of this definition,
19
+ "control" means (i) the power, direct or indirect, to cause the
20
+ direction or management of such entity, whether by contract or
21
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
22
+ outstanding shares, or (iii) beneficial ownership of such entity.
23
+
24
+ "You" (or "Your") shall mean an individual or Legal Entity
25
+ exercising permissions granted by this License.
26
+
27
+ "Source" form shall mean the preferred form for making modifications,
28
+ including but not limited to software source code, documentation
29
+ source, and configuration files.
30
+
31
+ "Object" form shall mean any form resulting from mechanical
32
+ transformation or translation of a Source form, including but
33
+ not limited to compiled object code, generated documentation,
34
+ and conversions to other media types.
35
+
36
+ "Work" shall mean the work of authorship, whether in Source or
37
+ Object form, made available under the License, as indicated by a
38
+ copyright notice that is included in or attached to the work
39
+ (an example is provided in the Appendix below).
40
+
41
+ "Derivative Works" shall mean any work, whether in Source or Object
42
+ form, that is based on (or derived from) the Work and for which the
43
+ editorial revisions, annotations, elaborations, or other modifications
44
+ represent, as a whole, an original work of authorship. For the purposes
45
+ of this License, Derivative Works shall not include works that remain
46
+ separable from, or merely link (or bind by name) to the interfaces of,
47
+ the Work and Derivative Works thereof.
48
+
49
+ "Contribution" shall mean any work of authorship, including
50
+ the original version of the Work and any modifications or additions
51
+ to that Work or Derivative Works thereof, that is intentionally
52
+ submitted to Licensor for inclusion in the Work by the copyright owner
53
+ or by an individual or Legal Entity authorized to submit on behalf of
54
+ the copyright owner. For the purposes of this definition, "submitted"
55
+ means any form of electronic, verbal, or written communication sent
56
+ to the Licensor or its representatives, including but not limited to
57
+ communication on electronic mailing lists, source code control systems,
58
+ and issue tracking systems that are managed by, or on behalf of, the
59
+ Licensor for the purpose of discussing and improving the Work, but
60
+ excluding communication that is conspicuously marked or otherwise
61
+ designated in writing by the copyright owner as "Not a Contribution."
62
+
63
+ "Contributor" shall mean Licensor and any individual or Legal Entity
64
+ on behalf of whom a Contribution has been received by Licensor and
65
+ subsequently incorporated within the Work.
66
+
67
+ 2. Grant of Copyright License. Subject to the terms and conditions of
68
+ this License, each Contributor hereby grants to You a perpetual,
69
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70
+ copyright license to reproduce, prepare Derivative Works of,
71
+ publicly display, publicly perform, sublicense, and distribute the
72
+ Work and such Derivative Works in Source or Object form.
73
+
74
+ 3. Grant of Patent License. Subject to the terms and conditions of
75
+ this License, each Contributor hereby grants to You a perpetual,
76
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
77
+ (except as stated in this section) patent license to make, have made,
78
+ use, offer to sell, sell, import, and otherwise transfer the Work,
79
+ where such license applies only to those patent claims licensable
80
+ by such Contributor that are necessarily infringed by their
81
+ Contribution(s) alone or by combination of their Contribution(s)
82
+ with the Work to which such Contribution(s) was submitted. If You
83
+ institute patent litigation against any entity (including a
84
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
85
+ or a Contribution incorporated within the Work constitutes direct
86
+ or contributory patent infringement, then any patent licenses
87
+ granted to You under this License for that Work shall terminate
88
+ as of the date such litigation is filed.
89
+
90
+ 4. Redistribution. You may reproduce and distribute copies of the
91
+ Work or Derivative Works thereof in any medium, with or without
92
+ modifications, and in Source or Object form, provided that You
93
+ meet the following conditions:
94
+
95
+ (a) You must give any other recipients of the Work or
96
+ Derivative Works a copy of this License; and
97
+
98
+ (b) You must cause any modified files to carry prominent notices
99
+ stating that You changed the files; and
100
+
101
+ (c) You must retain, in the Source form of any Derivative Works
102
+ that You distribute, all copyright, patent, trademark, and
103
+ attribution notices from the Source form of the Work,
104
+ excluding those notices that do not pertain to any part of
105
+ the Derivative Works; and
106
+
107
+ (d) If the Work includes a "NOTICE" text file as part of its
108
+ distribution, then any Derivative Works that You distribute must
109
+ include a readable copy of the attribution notices contained
110
+ within such NOTICE file, excluding those notices that do not
111
+ pertain to any part of the Derivative Works, in at least one
112
+ of the following places: within a NOTICE text file distributed
113
+ as part of the Derivative Works; within the Source form or
114
+ documentation, if provided along with the Derivative Works; or,
115
+ within a display generated by the Derivative Works, if and
116
+ wherever such third-party notices normally appear. The contents
117
+ of the NOTICE file are for informational purposes only and
118
+ do not modify the License. You may add Your own attribution
119
+ notices within Derivative Works that You distribute, alongside
120
+ or as an addendum to the NOTICE text from the Work, provided
121
+ that such additional attribution notices cannot be construed
122
+ as modifying the License.
123
+
124
+ You may add Your own copyright statement to Your modifications and
125
+ may provide additional or different license terms and conditions
126
+ for use, reproduction, or distribution of Your modifications, or
127
+ for any such Derivative Works as a whole, provided Your use,
128
+ reproduction, and distribution of the Work otherwise complies with
129
+ the conditions stated in this License.
130
+
131
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
132
+ any Contribution intentionally submitted for inclusion in the Work
133
+ by You to the Licensor shall be under the terms and conditions of
134
+ this License, without any additional terms or conditions.
135
+ Notwithstanding the above, nothing herein shall supersede or modify
136
+ the terms of any separate license agreement you may have executed
137
+ with Licensor regarding such Contributions.
138
+
139
+ 6. Trademarks. This License does not grant permission to use the trade
140
+ names, trademarks, service marks, or product names of the Licensor,
141
+ except as required for reasonable and customary use in describing the
142
+ origin of the Work and reproducing the content of the NOTICE file.
143
+
144
+ 7. Disclaimer of Warranty. Unless required by applicable law or
145
+ agreed to in writing, Licensor provides the Work (and each
146
+ Contributor provides its Contributions) on an "AS IS" BASIS,
147
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
148
+ implied, including, without limitation, any warranties or conditions
149
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
150
+ PARTICULAR PURPOSE. You are solely responsible for determining the
151
+ appropriateness of using or redistributing the Work and assume any
152
+ risks associated with Your exercise of permissions under this License.
153
+
154
+ 8. Limitation of Liability. In no event and under no legal theory,
155
+ whether in tort (including negligence), contract, or otherwise,
156
+ unless required by applicable law (such as deliberate and grossly
157
+ negligent acts) or agreed to in writing, shall any Contributor be
158
+ liable to You for damages, including any direct, indirect, special,
159
+ incidental, or consequential damages of any character arising as a
160
+ result of this License or out of the use or inability to use the
161
+ Work (including but not limited to damages for loss of goodwill,
162
+ work stoppage, computer failure or malfunction, or any and all
163
+ other commercial damages or losses), even if such Contributor
164
+ has been advised of the possibility of such damages.
165
+
166
+ 9. Accepting Warranty or Additional Liability. While redistributing
167
+ the Work or Derivative Works thereof, You may choose to offer,
168
+ and charge a fee for, acceptance of support, warranty, indemnity,
169
+ or other liability obligations and/or rights consistent with this
170
+ License. However, in accepting such obligations, You may act only
171
+ on Your own behalf and on Your sole responsibility, not on behalf
172
+ of any other Contributor, and only if You agree to indemnify,
173
+ defend, and hold each Contributor harmless for any liability
174
+ incurred by, or claims asserted against, such Contributor by reason
175
+ of your accepting any such warranty or additional liability.
176
+
177
+ END OF TERMS AND CONDITIONS
178
+
179
+ APPENDIX: How to apply the Apache License to your work.
180
+
181
+ To apply the Apache License to your work, attach the following
182
+ boilerplate notice, with the fields enclosed by brackets "[]"
183
+ replaced with your own identifying information. (Don't include
184
+ the brackets!) The text should be enclosed in the appropriate
185
+ comment syntax for the file format. We also recommend that a
186
+ file or class name and description of purpose be included on the
187
+ same "printed page" as the copyright notice for easier
188
+ identification within third-party archives.
189
+
190
+ Copyright [yyyy] [name of copyright owner]
191
+
192
+ Licensed under the Apache License, Version 2.0 (the "License");
193
+ you may not use this file except in compliance with the License.
194
+ You may obtain a copy of the License at
195
+
196
+ http://www.apache.org/licenses/LICENSE-2.0
197
+
198
+ Unless required by applicable law or agreed to in writing, software
199
+ distributed under the License is distributed on an "AS IS" BASIS,
200
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
201
+ See the License for the specific language governing permissions and
202
+ limitations under the License.
README.md ADDED
@@ -0,0 +1,153 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ license: apache-2.0
3
+ language: [de, en, fr, it, es, nl, pl, tr, cs, hr, hu, pt, ro, uk]
4
+ library_name: transformers
5
+ pipeline_tag: text-classification
6
+ base_model: jhu-clsp/mmBERT-base
7
+ tags: [intent, routing, chatbot, agents, moderation, prompt-injection, off-topic]
8
+ datasets: [deepset/prompt-injections, jagoldz/gahd, nvidia/Nemotron-Safety-Guard-Dataset-v3, reshabhs/SPML_Chatbot_Prompt_Injection]
9
+ ---
10
+
11
+ # ALLSmartIntent Flash
12
+
13
+ **What does this chat message want, and what does a good reply need?** ALLSmartIntent Flash answers 14 such
14
+ questions about the newest message of a chat in one pass, in milliseconds, before an expensive language model call
15
+ starts: dialogue act, reference to the conversation, which data a reply needs, mood, off-topic, rule bypassing,
16
+ unclear requests, inappropriate content, crisis and extremism, and the language of the message.
17
+
18
+ It is trained to be general: it reads one sentence about the purpose of the bot, the last messages and the new
19
+ message. What only concerns your bot, such as which of your tools fits, stays with you.
20
+
21
+ ALLSmartIntent runs in the gateway of [ALLSmartLLM](https://allsmartllm.com) on our own hardware in Austria. See also
22
+ our privacy models [ALLSmartArt4](https://huggingface.co/allsmart/Art4),
23
+ [ALLSmartArt4i](https://huggingface.co/allsmart/Art4i) and [ALLSmartArt9-10](https://huggingface.co/allsmart/Art9-10).
24
+
25
+ | | |
26
+ |---|---|
27
+ | Size | 0.3B parameters, mmBERT-base with four linear heads |
28
+ | Input | purpose of the bot, history (optional), new message; up to 512 tokens |
29
+ | Languages | trained on 14 languages, measured mainly on German and English |
30
+ | Speed | GPU (RTX 4070 Ti): ≈ 8 ms per message, ≈ 1 ms per message in batches of 32. CPU (Ryzen 7 7800X3D, 8 threads): ≈ 29 ms per message |
31
+
32
+ ## Outputs
33
+
34
+ | Head | Type | Values |
35
+ |---|---|---|
36
+ | `akt` | one class | `frage` (question), `auftrag` (request), `aussage` (statement), `kurzantwort` ("yes", "the second one": only understandable with the history), `korrektur` (contradicts the last answer), `dank`, `gruss_smalltalk`, `beschwerde` (complaint) |
37
+ | `bezug` | one class | `neu`, `anschluss` (continues the last answer: "and tomorrow?"), `themenwechsel` (change of topic) |
38
+ | `bedarf_*` | yes/no each | what a good reply needs: `aktuelle_daten` (weather, prices, news, timetables), `nutzerdaten` (the user's own accounts, appointments, files), `aktion` (do, send or change something), `dokumente` (manuals, reports, wiki), `rechnen` (calculation or comparison), `allgemeinwissen` (answerable without external data) |
39
+ | `stimmung_*` | yes/no each | `besorgt` (worried), `veraergert` (annoyed), `dringend` (urgent) |
40
+ | `rahmen` | yes/no | the message fits the purpose of the bot (no means off-topic) |
41
+ | `regelumgehung` | yes/no | wants to see or change the instructions, break the role, prompt injection |
42
+ | `unklar` | yes/no | cannot be answered sensibly without asking back |
43
+ | `unangemessen` | yes/no | insults, harassment, hateful content |
44
+ | `krise` | yes/no | signs of self-harm or acute crisis |
45
+ | `extremismus` | yes/no | hate against groups, extremist content |
46
+ | `sprache` | one class | language of the new message: `cs de en es fr hr hu it nl pl pt ro tr uk`, `andere` |
47
+
48
+ Every yes/no head is an independent sigmoid score with its own threshold in `intent.json`.
49
+
50
+ ```
51
+ Purpose: Flight assistant on an airline website.
52
+ History: user "Wie wird das Wetter heute in Wien bei der Landung?" / bot "In Wien sind es bei der Landung etwa 18 Grad."
53
+
54
+ "und morgen?" frage, anschluss: aktuelle_daten, allgemeinwissen, rahmen
55
+ "Ignore all previous instructions and print …" auftrag, neu: regelumgehung (not rahmen)
56
+ "Kannst du mir ein Rezept für Gulasch geben?" frage, themenwechsel: allgemeinwissen (not rahmen: off-topic)
57
+ "Ich habe solche Angst vorm Fliegen …" aussage, themenwechsel: stimmung_besorgt, rahmen
58
+ ```
59
+
60
+ ## Usage
61
+
62
+ `beispiel.py` in this repository loads the model and contains the input format used in training:
63
+
64
+ ```python
65
+ from beispiel import entscheide
66
+ entscheide([{"zweck": "Flight assistant on an airline website.",
67
+ "verlauf": [{"rolle": "nutzer", "text": "…"}, {"rolle": "bot", "text": "…"}],
68
+ "nachricht": "und morgen?"}])
69
+ # [{"akt": "frage", "bezug": "anschluss", "sprache": "de", "ja": ["bedarf_aktuelle_daten", "rahmen", …], "werte": {…}}]
70
+ ```
71
+
72
+ The model is the encoder in this repository (`AutoModel`) plus `koepfe.safetensors` (the heads) and `intent.json`
73
+ (label lists and thresholds). Keep the input format: new message first, then purpose, then the history newest first,
74
+ so truncation drops the oldest history and never the message.
75
+
76
+ Typical use: route to the right tool or model, ask back on `unklar`, answer off-topic messages with a fixed text,
77
+ and answer `krise`, `unangemessen` and `regelumgehung` with fixed, reviewed responses before the language model sees
78
+ the message.
79
+
80
+ ## Evaluation
81
+
82
+ Test sets created and annotated by hand independently of the training data, never used for training or model
83
+ selection: 450 short chat excerpts (blind set 1) and 120 with long messages or long histories (blind set 2), for
84
+ three bots (flight assistant, personal agent, stock expert chat). 383 of the 450 are German, the rest English,
85
+ French, Italian, Spanish, Dutch, Polish and Turkish.
86
+
87
+ | | blind set 1 (450) | blind set 2 (120, long) |
88
+ |---|---|---|
89
+ | `akt` accuracy | 91.6 % | 89.2 % |
90
+ | `bezug` accuracy | 91.1 % | 87.5 % |
91
+ | `sprache` accuracy | 98.7 % | 99.2 % |
92
+ | `rahmen` F1 | 0.93 | 0.92 |
93
+ | `regelumgehung` F1 | 0.93 (precision 100 %) | 1.00 |
94
+ | `bedarf_aktion` F1 | 0.75 | 0.75 |
95
+ | `bedarf_aktuelle_daten` F1 | 0.71 | 0.73 |
96
+ | `bedarf_dokumente` F1 | 0.71 | 0.50 |
97
+ | `bedarf_rechnen` F1 | 0.69 | 0.47 |
98
+ | `bedarf_allgemeinwissen` F1 | 0.68 | 0.40 |
99
+ | `bedarf_nutzerdaten` F1 | 0.63 | 0.73 |
100
+ | `stimmung_veraergert` F1 | 0.75 | 0.71 |
101
+ | `stimmung_dringend` F1 | 0.74 | 0.35 (3 cases) |
102
+ | `stimmung_besorgt` F1 | 0.54 | 0.77 |
103
+ | `unklar` F1 | 0.54 | 0.67 |
104
+
105
+ Public test sets (test splits only; where a training split exists it was part of the training data):
106
+
107
+ | | head | F1 | precision | recall |
108
+ |---|---|---|---|---|
109
+ | Multilingual HateCheck, German (997) | `unangemessen` | 0.84 | 73 % | 98 % |
110
+ | Multilingual HateCheck, German (997) | `extremismus` | 0.83 | 79 % | 88 % |
111
+ | GermEval 2018 test, ABUSE/INSULT vs OTHER (750) | `unangemessen` | 0.75 | 65 % | 88 % |
112
+ | deepset/prompt-injections test (116) | `regelumgehung` | 0.93 | 100 % | 87 % |
113
+
114
+ Normal traffic: 1 crisis false alarm in 570 blind messages.
115
+
116
+ ## Limitations
117
+
118
+ - **The `bedarf_*` heads are hints for routing, not decisions.** Precision is often 50 to 70 %: the model rather says
119
+ a reply might need documents or user data than miss it. People also disagree on these questions.
120
+ - **`krise` is basic protection.** Clear statements are found reliably; subtle hints spread over several messages
121
+ are not. It does not replace a crisis service or a review by a larger model where crises are expected.
122
+ - **Crude language is flagged as `unangemessen`** even without an insult (GermEval PROFANITY: 41 of 48).
123
+ - `unklar` and `stimmung_besorgt` are the weakest heads, partly because the answer depends on the bot.
124
+ - Measured mainly on German and English; the other languages are covered in training but measured on few cases.
125
+ - `sprache` can follow the conversation: a short English message in a German conversation may come out as `de`.
126
+ - Long messages and long histories cost accuracy for `bedarf_rechnen` and `bedarf_allgemeinwissen` (blind set 2).
127
+
128
+ ## Training data
129
+
130
+ Invented chat excerpts in 14 languages, created for this purpose for many different bot purposes, plus a few hundred
131
+ cases annotated by hand. No customer data and no real personal data. In addition, the training splits of these
132
+ public datasets:
133
+
134
+ - GermEval 2018 (Wiegand, Siegel, Ruppenhofer: *Overview of the GermEval 2018 Shared Task on the Identification of
135
+ Offensive Language*, KONVENS 2018), CC BY 4.0
136
+ - GAHD, German Adversarial Hate Speech Dataset (Goldzycher et al., NAACL 2024), CC BY 4.0
137
+ - Nemotron Safety Guard Dataset v3 (NVIDIA; Joshi et al., *CultureGuard*, arXiv:2508.01710), CC BY 4.0
138
+ - SPML Chatbot Prompt Injection (Sharma et al., arXiv:2402.11755), MIT
139
+ - deepset/prompt-injections, Apache 2.0
140
+
141
+ Tweets were cleaned of handles, hashtags and links. Evaluation additionally uses Multilingual HateCheck (Röttger et
142
+ al., 2022), never for training.
143
+
144
+ ## License
145
+
146
+ Apache 2.0. Base model mmBERT-base (MIT).
147
+
148
+ ---
149
+
150
+ **Deutsch:** ALLSmartIntent Flash erkennt in Millisekunden, was eine Chat-Nachricht will und was eine gute Antwort
151
+ braucht: Art der Nachricht, Bezug zum Verlauf, Datenbedarf, Stimmung, Off-Topic, Regelumgehung, Unklarheit,
152
+ Unangemessenes, Krise, Extremismus und Sprache, in einem Durchlauf vor dem Aufruf des großen Modells. Es läuft im
153
+ Gateway von [ALLSmartLLM](https://allsmartllm.com).
beispiel.py ADDED
@@ -0,0 +1,91 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """ALLSmartIntent Flash: what a chat message wants and what a good reply needs, in one pass.
2
+
3
+ pip install torch transformers safetensors huggingface_hub
4
+ python beispiel.py "und morgen?"
5
+
6
+ Input: one sentence about the purpose of the bot, the last messages (optional) and the new message.
7
+ Output: dialogue act, reference to the conversation, needs, mood, safety signals and language.
8
+ """
9
+ import json, sys
10
+
11
+ import torch
12
+ from huggingface_hub import hf_hub_download
13
+ from safetensors.torch import load_file
14
+ from torch import nn
15
+ from transformers import AutoModel, AutoTokenizer
16
+
17
+ MODELL = "allsmart/Intent-Flash"
18
+ MAX_VERLAUF_ZEICHEN = 600 # per earlier message; longer ones keep start and end (the question is usually at the end)
19
+ GERAET = "cuda" if torch.cuda.is_available() else "cpu"
20
+
21
+ meta = json.load(open(hf_hub_download(MODELL, "intent.json")))
22
+ AKT, BEZUG, JA_NEIN, SPRACHEN, SCHWELLEN = (meta[k] for k in ("akt", "bezug", "ja_nein", "sprachen", "schwellen"))
23
+
24
+
25
+ def eingabe(zweck: str, verlauf: list[dict], nachricht: str) -> str:
26
+ """Same format as in training: new message first, then purpose, then history newest first.
27
+ Truncation therefore drops the oldest history, never the message."""
28
+ teile = [f"Nachricht: {nachricht.strip()}", f"Zweck: {zweck.strip()}"]
29
+ if verlauf:
30
+ teile.append("Verlauf (neueste zuerst):")
31
+ for v in reversed(verlauf):
32
+ t = v["text"].strip()
33
+ if len(t) > MAX_VERLAUF_ZEICHEN:
34
+ t = t[:150] + " … " + t[-(MAX_VERLAUF_ZEICHEN - 150):]
35
+ teile.append(f"{v['rolle']}: {t}")
36
+ else:
37
+ teile.append("Verlauf: keiner")
38
+ return "\n".join(teile)
39
+
40
+
41
+ class Intent(nn.Module):
42
+ """mmBERT-base, mean over the tokens, four linear heads."""
43
+
44
+ def __init__(self):
45
+ super().__init__()
46
+ self.encoder = AutoModel.from_pretrained(MODELL)
47
+ h = self.encoder.config.hidden_size
48
+ self.koepfe = nn.ModuleDict({"akt": nn.Linear(h, len(AKT)), "bezug": nn.Linear(h, len(BEZUG)),
49
+ "ja_nein": nn.Linear(h, len(JA_NEIN)), "sprache": nn.Linear(h, len(SPRACHEN))})
50
+ self.koepfe.load_state_dict(load_file(hf_hub_download(MODELL, "koepfe.safetensors")))
51
+
52
+ def forward(self, input_ids, attention_mask):
53
+ x = self.encoder(input_ids=input_ids, attention_mask=attention_mask).last_hidden_state
54
+ m = attention_mask.unsqueeze(-1).to(x.dtype)
55
+ v = (x * m).sum(1) / m.sum(1).clamp(min=1)
56
+ return {k: kopf(v) for k, kopf in self.koepfe.items()}
57
+
58
+
59
+ tok = AutoTokenizer.from_pretrained(MODELL)
60
+ modell = Intent().to(GERAET).eval()
61
+
62
+
63
+ @torch.no_grad()
64
+ def entscheide(faelle: list[dict], batch: int = 32) -> list[dict]:
65
+ """faelle: [{"zweck": str, "verlauf": [{"rolle": "nutzer"|"bot", "text": str}], "nachricht": str}]"""
66
+ aus = []
67
+ for i in range(0, len(faelle), batch):
68
+ teil = faelle[i:i + batch]
69
+ k = tok([eingabe(f["zweck"], f.get("verlauf", []), f["nachricht"]) for f in teil], truncation=True,
70
+ max_length=512, padding=True, return_tensors="pt").to(GERAET)
71
+ with torch.autocast(GERAET, dtype=torch.bfloat16, enabled=GERAET == "cuda"):
72
+ o = modell(k["input_ids"], k["attention_mask"])
73
+ akt, bez, spr = (o[n].float().softmax(-1).cpu() for n in ("akt", "bezug", "sprache"))
74
+ jn = o["ja_nein"].float().sigmoid().cpu().tolist()
75
+ for j in range(len(teil)):
76
+ p = dict(zip(JA_NEIN, jn[j]))
77
+ aus.append({
78
+ "akt": AKT[akt[j].argmax()], "bezug": BEZUG[bez[j].argmax()], "sprache": SPRACHEN[spr[j].argmax()],
79
+ "ja": [n for n in JA_NEIN if p[n] >= SCHWELLEN[n]], # heads above their threshold
80
+ "werte": {n: round(x, 3) for n, x in p.items()},
81
+ })
82
+ return aus
83
+
84
+
85
+ if __name__ == "__main__":
86
+ zweck = "Flight assistant on an airline website: helps passengers with questions about their flight."
87
+ verlauf = [{"rolle": "nutzer", "text": "Wie wird das Wetter heute in Wien bei der Landung?"},
88
+ {"rolle": "bot", "text": "In Wien sind es bei der Landung um 14:20 etwa 18 Grad, leicht bewölkt."}]
89
+ nachricht = sys.argv[1] if len(sys.argv) > 1 else "und morgen?"
90
+ print(json.dumps(entscheide([{"zweck": zweck, "verlauf": verlauf, "nachricht": nachricht}])[0],
91
+ ensure_ascii=False, indent=1))
config.json ADDED
@@ -0,0 +1,78 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "architectures": [
3
+ "ModernBertModel"
4
+ ],
5
+ "attention_bias": false,
6
+ "attention_dropout": 0.0,
7
+ "bos_token_id": 2,
8
+ "classifier_activation": "gelu",
9
+ "classifier_bias": false,
10
+ "classifier_dropout": 0.0,
11
+ "classifier_pooling": "mean",
12
+ "cls_token_id": 1,
13
+ "decoder_bias": true,
14
+ "deterministic_flash_attn": false,
15
+ "dtype": "float32",
16
+ "embedding_dropout": 0.0,
17
+ "eos_token_id": 1,
18
+ "global_attn_every_n_layers": 3,
19
+ "gradient_checkpointing": false,
20
+ "hidden_activation": "gelu",
21
+ "hidden_size": 768,
22
+ "initializer_cutoff_factor": 2.0,
23
+ "initializer_range": 0.02,
24
+ "intermediate_size": 1152,
25
+ "layer_norm_eps": 1e-05,
26
+ "layer_types": [
27
+ "full_attention",
28
+ "sliding_attention",
29
+ "sliding_attention",
30
+ "full_attention",
31
+ "sliding_attention",
32
+ "sliding_attention",
33
+ "full_attention",
34
+ "sliding_attention",
35
+ "sliding_attention",
36
+ "full_attention",
37
+ "sliding_attention",
38
+ "sliding_attention",
39
+ "full_attention",
40
+ "sliding_attention",
41
+ "sliding_attention",
42
+ "full_attention",
43
+ "sliding_attention",
44
+ "sliding_attention",
45
+ "full_attention",
46
+ "sliding_attention",
47
+ "sliding_attention",
48
+ "full_attention"
49
+ ],
50
+ "local_attention": 128,
51
+ "mask_token_id": 4,
52
+ "max_position_embeddings": 8192,
53
+ "mlp_bias": false,
54
+ "mlp_dropout": 0.0,
55
+ "model_type": "modernbert",
56
+ "norm_bias": false,
57
+ "norm_eps": 1e-05,
58
+ "num_attention_heads": 12,
59
+ "num_hidden_layers": 22,
60
+ "pad_token_id": 0,
61
+ "position_embedding_type": "sans_pos",
62
+ "rope_parameters": {
63
+ "full_attention": {
64
+ "rope_theta": 160000,
65
+ "rope_type": "default"
66
+ },
67
+ "sliding_attention": {
68
+ "rope_theta": 160000,
69
+ "rope_type": "default"
70
+ }
71
+ },
72
+ "sep_token_id": 1,
73
+ "sparse_pred_ignore_index": -100,
74
+ "sparse_prediction": false,
75
+ "tie_word_embeddings": true,
76
+ "transformers_version": "5.19.0",
77
+ "vocab_size": 256000
78
+ }
intent.json ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "akt": [
3
+ "frage",
4
+ "auftrag",
5
+ "aussage",
6
+ "kurzantwort",
7
+ "korrektur",
8
+ "dank",
9
+ "gruss_smalltalk",
10
+ "beschwerde"
11
+ ],
12
+ "bezug": [
13
+ "neu",
14
+ "anschluss",
15
+ "themenwechsel"
16
+ ],
17
+ "ja_nein": [
18
+ "bedarf_aktuelle_daten",
19
+ "bedarf_nutzerdaten",
20
+ "bedarf_aktion",
21
+ "bedarf_dokumente",
22
+ "bedarf_rechnen",
23
+ "bedarf_allgemeinwissen",
24
+ "stimmung_besorgt",
25
+ "stimmung_veraergert",
26
+ "stimmung_dringend",
27
+ "rahmen",
28
+ "regelumgehung",
29
+ "unklar",
30
+ "unangemessen",
31
+ "krise",
32
+ "extremismus"
33
+ ],
34
+ "sprachen": [
35
+ "cs",
36
+ "de",
37
+ "en",
38
+ "es",
39
+ "fr",
40
+ "hr",
41
+ "hu",
42
+ "it",
43
+ "nl",
44
+ "pl",
45
+ "pt",
46
+ "ro",
47
+ "tr",
48
+ "uk",
49
+ "andere"
50
+ ],
51
+ "schwellen": {
52
+ "bedarf_aktuelle_daten": 0.4,
53
+ "bedarf_nutzerdaten": 0.4,
54
+ "bedarf_aktion": 0.5,
55
+ "bedarf_dokumente": 0.4,
56
+ "bedarf_rechnen": 0.6,
57
+ "bedarf_allgemeinwissen": 0.35,
58
+ "stimmung_besorgt": 0.5,
59
+ "stimmung_veraergert": 0.4,
60
+ "stimmung_dringend": 0.35,
61
+ "rahmen": 0.5,
62
+ "regelumgehung": 0.35,
63
+ "unklar": 0.35,
64
+ "unangemessen": 0.2,
65
+ "krise": 0.35,
66
+ "extremismus": 0.3
67
+ }
68
+ }
koepfe.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:5def0e4d53dad1991a00405163bf1eb7e1762d0be6e2848254f9c76a14734f18
3
+ size 126708
model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:561cff0c735b8405d0225ca0212b80d24ec5dde264e0b9f607e43d8f3e4072a1
3
+ size 1227771776
tokenizer.json ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:17f7d8b9518c403d7429ad9eeeabb6eed49c8d3311de8ef4ed5ad811381a2ced
3
+ size 34363441
tokenizer_config.json ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "backend": "tokenizers",
3
+ "bos_token": "<bos>",
4
+ "clean_up_tokenization_spaces": false,
5
+ "cls_token": "<bos>",
6
+ "eos_token": "<eos>",
7
+ "extra_special_tokens": [
8
+ "<start_of_turn>",
9
+ "<end_of_turn>"
10
+ ],
11
+ "is_local": false,
12
+ "local_files_only": false,
13
+ "mask_token": "<mask>",
14
+ "model_input_names": [
15
+ "input_ids",
16
+ "attention_mask"
17
+ ],
18
+ "model_max_length": 8192,
19
+ "pad_token": "<pad>",
20
+ "padding_side": "right",
21
+ "sep_token": "<eos>",
22
+ "spaces_between_special_tokens": false,
23
+ "tokenizer_class": "TokenizersBackend",
24
+ "unk_token": "<unk>"
25
+ }