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}