aleph_alpha_api/explanation.rs
1use super::completion::{BoundingBox, Hosting, Prompt};
2use crate::impl_builder_methods;
3use serde::{Deserialize, Serialize};
4
5#[derive(Serialize, Debug, Default)]
6#[serde(rename_all = "snake_case")]
7pub enum Postprocessing {
8 /// Apply no postprocessing.
9 #[default]
10 None,
11 /// Return the absolute value of each value.
12 Absolute,
13 /// Square each value
14 Square,
15}
16
17#[derive(Serialize, Debug, Default)]
18#[serde(rename_all = "snake_case")]
19pub enum PromptGranularityType {
20 #[default]
21 Token,
22 Word,
23 Sentence,
24 Paragraph,
25 Custom,
26}
27
28#[derive(Serialize, Debug)]
29pub struct PromptGranularity {
30 /// At which granularity should the target be explained in terms of the prompt.
31 /// If you choose, for example, "sentence" then we report the importance score of each
32 /// sentence in the prompt towards generating the target output.
33 ///
34 /// If you do not choose a granularity then we will try to find the granularity that
35 /// brings you closest to around 30 explanations. For large documents, this would likely
36 /// be sentences. For short prompts this might be individual words or even tokens.
37 ///
38 /// If you choose a custom granularity then you must provide a custom delimiter. We then
39 /// split your prompt by that delimiter. This might be helpful if you are using few-shot
40 /// prompts that contain stop sequences.
41 ///
42 /// For image prompt items, the granularities determine into how many tiles we divide
43 /// the image for the explanation.
44 /// "token" -> 12x12
45 /// "word" -> 6x6
46 /// "sentence" -> 3x3
47 /// "paragraph" -> 1
48 #[serde(rename = "type")]
49 granularity_type: PromptGranularityType,
50
51 /// A delimiter string to split the prompt on if "custom" granularity is chosen.
52 delimiter: String,
53}
54
55impl Default for PromptGranularity {
56 fn default() -> Self {
57 Self {
58 granularity_type: PromptGranularityType::default(),
59 delimiter: String::new(),
60 }
61 }
62}
63
64/// How many explanations should be returned in the output.
65#[derive(Serialize, Debug)]
66#[serde(rename_all = "snake_case")]
67pub enum TargetGranularity {
68 /// Return one explanation for the entire target. Helpful in many cases to determine which parts of the prompt contribute overall to the given completion.
69 Complete,
70
71 /// Return one explanation for each token in the target.
72 Token,
73}
74
75#[derive(Serialize, Debug, Default)]
76#[serde(rename_all = "snake_case")]
77pub enum ControlTokenOverlap {
78 #[default]
79 Partial,
80 Complete,
81}
82
83#[derive(Serialize, Debug, Default)]
84pub struct ExplanationRequest {
85 /// Name of the model to use.
86 pub model: String,
87
88 /// Determines in which datacenters the request may be processed.
89 /// You can either set the parameter to "aleph-alpha" or omit it (defaulting to None).
90 ///
91 /// Not setting this value, or setting it to None, gives us maximal flexibility in processing your request in our
92 /// own datacenters and on servers hosted with other providers. Choose this option for maximal availability.
93 ///
94 /// Setting it to "aleph-alpha" allows us to only process the request in our own datacenters.
95 /// Choose this option for maximal data privacy.
96 #[serde(skip_serializing_if = "Option::is_none")]
97 pub hosting: Option<Hosting>,
98
99 pub prompt: Prompt,
100
101 /// The completion string to be explained based on model probabilities.
102 #[serde(skip_serializing_if = "Option::is_none")]
103 pub target: Option<String>,
104
105 /// Factor to apply to the given token in the attention matrix.
106 ///
107 /// - 0 <= factor < 1 => Suppress the given token
108 /// - factor == 1 => identity operation, no change to attention
109 /// - factor > 1 => Amplify the given token
110 #[serde(skip_serializing_if = "Option::is_none")]
111 pub control_factor: Option<f64>,
112
113 /// If set to `null`, attention control parameters only apply to those tokens that have explicitly been set in the request.
114 /// If set to a non-null value, we apply the control parameters to similar tokens as well.
115 /// Controls that have been applied to one token will then be applied to all other tokens that have at least the similarity score defined by this parameter.
116 /// The similarity score is the cosine similarity of token embeddings.
117 #[serde(skip_serializing_if = "Option::is_none")]
118 pub contextual_control_threshold: Option<f64>,
119
120 /// `true`: apply controls on prompt items by adding the `log(control_factor)` to attention scores.
121 /// `false`: apply controls on prompt items by `(attention_scores - -attention_scores.min(-1)) * control_factor`
122 #[serde(skip_serializing_if = "Option::is_none")]
123 pub control_log_additive: Option<bool>,
124
125 /// Optionally apply postprocessing to the difference in cross entropy scores for each token.
126 /// "none": Apply no postprocessing.
127 /// "absolute": Return the absolute value of each value.
128 /// "square": Square each value
129 #[serde(skip_serializing_if = "Option::is_none")]
130 pub postprocessing: Option<Postprocessing>,
131
132 /// Return normalized scores. Minimum score becomes 0 and maximum score becomes 1. Applied after any postprocessing
133 #[serde(skip_serializing_if = "Option::is_none")]
134 pub normalize: Option<bool>,
135
136 /// At which granularity should the target be explained in terms of the prompt.
137 /// If you choose, for example, "sentence" then we report the importance score of each
138 /// sentence in the prompt towards generating the target output.
139 ///
140 /// If you do not choose a granularity then we will try to find the granularity that
141 /// brings you closest to around 30 explanations. For large documents, this would likely
142 /// be sentences. For short prompts this might be individual words or even tokens.
143 ///
144 /// If you choose a custom granularity then you must provide a custom delimiter. We then
145 /// split your prompt by that delimiter. This might be helpful if you are using few-shot
146 /// prompts that contain stop sequences.
147 ///
148 /// For image prompt items, the granularities determine into how many tiles we divide
149 /// the image for the explanation.
150 /// Token -> 12x12
151 /// Word -> 6x6
152 /// Sentence -> 3x3
153 /// Paragraph -> 1
154 pub prompt_granularity: Option<PromptGranularity>,
155
156 /// How many explanations should be returned in the output.
157 ///
158 /// Complete -> Return one explanation for the entire target. Helpful in many cases to determine which parts of the prompt contribute overall to the given completion.
159 /// Token -> Return one explanation for each token in the target.
160 #[serde(skip_serializing_if = "Option::is_none")]
161 pub target_granularity: Option<TargetGranularity>,
162
163 /// What to do if a control partially overlaps with a text or image token.
164 ///
165 /// If set to "partial", the factor will be adjusted proportionally with the amount
166 /// of the token it overlaps. So a factor of 2.0 of a control that only covers 2 of
167 /// 4 token characters, would be adjusted to 1.5. (It always moves closer to 1, since
168 /// 1 is an identity operation for control factors.)
169 ///
170 /// If set to "complete", the full factor will be applied as long as the control
171 /// overlaps with the token at all.
172 #[serde(skip_serializing_if = "Option::is_none")]
173 pub control_token_overlap: Option<ControlTokenOverlap>,
174}
175
176impl_builder_methods!(
177 ExplanationRequest,
178 hosting: Hosting,
179 target: String,
180 control_factor: f64,
181 contextual_control_threshold: f64,
182 control_log_additive: bool,
183 postprocessing: Postprocessing,
184 normalize: bool,
185 prompt_granularity: PromptGranularity,
186 target_granularity: TargetGranularity,
187 control_token_overlap: ControlTokenOverlap
188);
189
190#[derive(Deserialize, Debug)]
191pub struct ScoredSegment {
192 pub start: i32,
193 pub length: i32,
194 pub score: f32,
195}
196
197#[derive(Deserialize, Debug)]
198pub struct ScoredRect {
199 pub rect: BoundingBox,
200 pub score: f32,
201}
202
203#[derive(Deserialize, Debug)]
204#[serde(tag = "type", rename_all = "snake_case")]
205pub enum ItemImportance {
206 /// Explains the importance of a request prompt item of type "token_ids".
207 /// Will contain one floating point importance value for each token in the same order as in
208 /// the original prompt.
209 TokenIds { scores: Vec<f32> },
210
211 /// Explains the importance of text in the target string that came before the currently to-be-explained target token. The amount of items in the "scores" array depends on the granularity setting.
212 /// Each score object contains an inclusive start character and a length of the substring plus a floating point score value.
213 Target { scores: Vec<ScoredSegment> },
214
215 /// Explains the importance of a text prompt item.
216 /// The amount of items in the "scores" array depends on the granularity setting.
217 /// Each score object contains an inclusive start character and a length of the substring plus a floating point score value.
218 Text { scores: Vec<ScoredSegment> },
219
220 /// Explains the importance of an image prompt item.
221 /// The amount of items in the "scores" array depends on the granularity setting.
222 /// Each score object contains the top-left corner of a rectangular area in the image prompt.
223 /// The coordinates are all between 0 and 1 in terms of the total image size
224 Image { scores: Vec<ScoredRect> },
225}
226
227#[derive(Deserialize, Debug)]
228pub struct ExplanationItem {
229 /// The string representation of the target token which is being explained
230 pub target: String,
231
232 /// Contains one item for each prompt item (in order), and the last item refers to the target.
233 pub items: Vec<ItemImportance>,
234}
235
236/// The top-level response data structure that will be returned from an explanation request.
237#[derive(Deserialize, Debug)]
238pub struct ExplanationResponse {
239 pub model_version: String,
240
241 /// This array will contain one explanation object for each token in the target string.
242 pub explanations: Vec<ExplanationItem>,
243}