Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
159 commits
Select commit Hold shift + click to select a range
cafb609
DOA Policy first implementation
sarapapi Mar 24, 2026
4f9dbd1
Improve Phi4-Multimodal DOA description
sarapapi Mar 24, 2026
99282e2
Rename DOA Phi config
sarapapi Mar 24, 2026
9dd7668
Rename DOA Phi config
sarapapi Mar 24, 2026
f841ce2
Correct audio subsampling factor
sarapapi Mar 24, 2026
73fed6b
Fix load_model to class method
sarapapi Mar 24, 2026
c456013
Fix lang init
sarapapi Mar 24, 2026
54752a9
Fix newer transformers compatibility
sarapapi Mar 24, 2026
48ab026
Debug
sarapapi Mar 24, 2026
03091ac
Remove end of sentence
sarapapi Mar 24, 2026
aa990ee
Disable eos
sarapapi Mar 24, 2026
6dc2e4d
Revert
sarapapi Mar 24, 2026
042e682
Try different EOS
sarapapi Mar 24, 2026
2dcfdcd
Debug
sarapapi Mar 24, 2026
46ad7f8
Debug
sarapapi Mar 24, 2026
bc37b8d
Debug
sarapapi Mar 24, 2026
b8a5e33
Partial fix
sarapapi Mar 24, 2026
aa41e41
Increase stability
sarapapi Mar 24, 2026
5d08e7d
Add cross attention normalization
sarapapi Mar 24, 2026
d9def94
revert speech chunk
sarapapi Mar 24, 2026
87ee050
debug
sarapapi Mar 24, 2026
69eb48f
debug
sarapapi Mar 24, 2026
e6f936f
debug
sarapapi Mar 24, 2026
616fcaa
reduce hallucinations
sarapapi Mar 24, 2026
c629a76
reduce hallucinations
sarapapi Mar 24, 2026
af083b7
Try fix
sarapapi Mar 24, 2026
54d137f
Debug
sarapapi Mar 24, 2026
4d889e3
Remove unnecessary parameters
sarapapi Mar 24, 2026
8fc0ee4
Fix stripping with alternative tokenizer and add debug
sarapapi Mar 24, 2026
6a40aed
Choose a simple prompt for Phi4Multimodal
sarapapi Mar 24, 2026
b215ba3
More stable outputs
sarapapi Mar 24, 2026
2c88831
Remove debugs
sarapapi Mar 27, 2026
a4bc581
Add hf_model_name to config of DOA Phi
sarapapi Apr 3, 2026
031482e
Add trust_remote True to bypass manually consent during eval
sarapapi Apr 3, 2026
c065466
Revert the punctuation stripping
sarapapi Apr 3, 2026
0b95426
Improve DOA descriptions and remove unnecessary functions
sarapapi Apr 3, 2026
6347599
Remove unnecessary import
sarapapi Apr 3, 2026
5876552
Update language maps
sarapapi Apr 8, 2026
e3e41c2
Update qwen2.5omni implementation
sarapapi Apr 8, 2026
1f7f80b
Correct trust_remote_code typo in detokenizers
sarapapi Apr 9, 2026
9a4314b
Update config
sarapapi Apr 9, 2026
5e8c6e3
Update Qwen name
sarapapi Apr 9, 2026
bdd3253
Update Qwen code
sarapapi Apr 9, 2026
cef90d6
Update Qwen code
sarapapi Apr 9, 2026
4010d6e
Disable flash attention for testing
sarapapi Apr 9, 2026
4ff9dae
Revert to standard system prompt
sarapapi Apr 9, 2026
faf060a
Add average across layers
sarapapi Apr 9, 2026
1f7c34f
Update config
sarapapi Apr 9, 2026
53e3338
Add Phi4Multimodal configs
sarapapi Apr 9, 2026
a7b6982
Add Phi4Multimodal configs
sarapapi Apr 9, 2026
f3d6713
Fix detokenizer for Qwen2.5-Omni
sarapapi Apr 9, 2026
d9e0ac5
Discourage Qwen2.5 Omni to repeat
sarapapi Apr 9, 2026
4705733
Adjust repetition
sarapapi Apr 9, 2026
3dae1a5
Add history param
sarapapi Apr 9, 2026
b384d24
Add deterministic params
sarapapi Apr 10, 2026
cf799b1
Revert partially deterministic params for Qwen2.5Omni
sarapapi Apr 12, 2026
414bf32
Revert partially deterministic params for Phi4Multimodal
sarapapi Apr 12, 2026
012b5ca
Disable strip
sarapapi Apr 13, 2026
743233b
Correct prefix handling
sarapapi Apr 13, 2026
d1a32d5
Add summary policy
sarapapi Apr 14, 2026
6fdde36
Revert to original implementation of the prefix for Qwen
sarapapi Apr 14, 2026
69ddeef
Try the fix
sarapapi Apr 15, 2026
f964e47
Revert "Try the fix"
sarapapi Apr 15, 2026
f117590
Add Qwen2.5omni 7b config
sarapapi Apr 16, 2026
b9830a9
reduce audio max len
sarapapi Apr 16, 2026
fbb5517
Move summary
sarapapi Apr 16, 2026
e44980a
Try change for summary
sarapapi May 5, 2026
dfcd53e
Try change for summary
sarapapi May 5, 2026
3989154
Revert
sarapapi May 5, 2026
5a82371
Try fix
sarapapi May 5, 2026
abefe05
Revert "Try fix"
sarapapi May 5, 2026
73eda2a
Switch from summary to reference memory
sarapapi May 6, 2026
5dcddbc
Revert to simple implementation
sarapapi May 7, 2026
acbc5e1
Add head analysis
sarapapi May 8, 2026
67dfd73
Try different prompt
sarapapi May 15, 2026
0506a9b
Try different sys prompt
sarapapi May 15, 2026
d8133a9
debug
sarapapi May 15, 2026
9448e0d
debug
sarapapi May 15, 2026
9904d4b
debug
sarapapi May 15, 2026
7e976f7
debug
sarapapi May 15, 2026
41cb279
debug
sarapapi May 15, 2026
b04d775
debug
sarapapi May 16, 2026
fb91d6e
debug
sarapapi May 16, 2026
5d68d6a
debug
sarapapi May 16, 2026
8ff9bd1
Revert "debug"
sarapapi May 17, 2026
ed17179
Revert "debug"
sarapapi May 17, 2026
421a2f8
Revert "debug"
sarapapi May 17, 2026
6f3f6f4
Revert "debug"
sarapapi May 17, 2026
b94cb83
Revert "debug"
sarapapi May 17, 2026
4a7414b
Revert "debug"
sarapapi May 17, 2026
deec3a8
Revert "debug"
sarapapi May 17, 2026
525f20b
Revert "debug"
sarapapi May 17, 2026
bb047fb
debug
sarapapi May 17, 2026
8247ecc
Revert "debug"
sarapapi May 17, 2026
fc40392
debug
sarapapi May 17, 2026
c150348
Revert "Try different sys prompt"
sarapapi May 17, 2026
f6ff53d
revert
sarapapi May 17, 2026
a81af66
Try new Qwen3Omni
sarapapi May 18, 2026
0aefbf9
Try new Qwen3Omni
sarapapi May 18, 2026
f1772d8
Try new Qwen3Omni
sarapapi May 18, 2026
1658514
Try new Qwen3Omni
sarapapi May 18, 2026
d5d1807
Try new Qwen3Omni
sarapapi May 18, 2026
13bd2e3
Try new Qwen3Omni
sarapapi May 18, 2026
c5981e6
Try new Qwen3Omni
sarapapi May 18, 2026
c4297e2
Trim max input length of Qwen3Omni
sarapapi May 18, 2026
c798537
Add Gemma4
sarapapi May 18, 2026
52c8b59
Add Gemma4 global layers for the average
sarapapi May 20, 2026
c0dcf25
Add Qwen2Audio
sarapapi May 20, 2026
44d8e1e
Fix wrong path
sarapapi May 20, 2026
80b9bd3
Fix Qwen2Audio inference
sarapapi May 20, 2026
3ba31fe
Fix Qwen2Audio inference
sarapapi May 20, 2026
2e2b62d
Fix Qwen2Audio inference
sarapapi May 21, 2026
96128c3
seed
sarapapi May 21, 2026
9a2755f
Revert "Fix Qwen2Audio inference"
sarapapi May 21, 2026
eefe133
Revert "Fix Qwen2Audio inference"
sarapapi May 21, 2026
f71fed9
Fix Qwen2Audio
sarapapi May 21, 2026
b5eabf5
Remove Gemma4 as it performs very bad
sarapapi May 21, 2026
5a437db
Revert "seed"
sarapapi May 21, 2026
a9dcd6b
Add UltraVox
sarapapi May 21, 2026
af80da4
Add UltraVox
sarapapi May 21, 2026
d89741c
Add UltraVox
sarapapi May 21, 2026
6c1cead
Comment attn implementation
sarapapi May 23, 2026
db80ada
Revert "Comment attn implementation"
sarapapi May 23, 2026
41ba86f
Change Qwen2Audio prompt
sarapapi May 23, 2026
d5020a0
Add Voxtral
sarapapi May 23, 2026
e89a3f5
Add Voxtral
sarapapi May 23, 2026
a709c74
Add Voxtral
sarapapi May 24, 2026
ffcf1c4
Fix tokenizer
sarapapi May 24, 2026
c0f4995
Fix voxtral tokenizer
sarapapi May 24, 2026
7b34fe5
Fix voxtral tokenizer
sarapapi May 24, 2026
a2d00da
Fix voxtral tokenizer
sarapapi May 24, 2026
5386881
Fix voxtral tokenizer
sarapapi May 24, 2026
278786f
Fix voxtral prompt
sarapapi May 24, 2026
d124275
Clean for release
sarapapi May 28, 2026
c6ab757
Revert voxtral detokenizer
sarapapi May 28, 2026
35e5809
Fix Phi4-Multimodal linting
sarapapi May 28, 2026
d908dd8
Fix Qwen3-Omni linting and remove useless comments
sarapapi May 28, 2026
5fa2b29
Clean from useless comments
sarapapi May 28, 2026
e40fa38
Fix uts
sarapapi May 28, 2026
25e024b
Update simulstream/server/speech_processors/qwenomni_doa.py
sarapapi Jun 9, 2026
d2a556a
Update simulstream/server/speech_processors/phi4multimodal_doa.py
sarapapi Jun 9, 2026
babf61d
Merge branch 'main' into doa_policy
sarapapi Jun 9, 2026
426af02
Partially address comments
sarapapi Jun 9, 2026
cd5ecc4
Address comment about pycountry
sarapapi Jun 11, 2026
26e06ae
Fix linting
sarapapi Jun 11, 2026
76ba013
refactor code to avoid duplicated code
mgaido91 Jun 12, 2026
dae38d8
Fix logging
sarapapi Jun 18, 2026
a7ac4d4
Partially revert the change
sarapapi Jun 18, 2026
1fad0d7
Fix the description to go new line after 100 chars
sarapapi Jun 18, 2026
909d36d
Address comments
sarapapi Jun 18, 2026
987637b
Fix Lint
sarapapi Jun 18, 2026
39d6d7b
Remove unused import
sarapapi Jun 18, 2026
fcafb30
Address comment
sarapapi Jul 3, 2026
ca8678a
Address comment
sarapapi Jul 8, 2026
a933ab2
Remove comment from yaml
sarapapi Jul 8, 2026
4671fe2
Add default parameter for the bow_prefix
sarapapi Jul 8, 2026
4e62547
Merge branch 'main' into doa_policy
sarapapi Jul 8, 2026
52bafd2
fix bow_prefix leftovers
sarapapi Jul 8, 2026
80fe712
Address comment
sarapapi Jul 8, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
164 changes: 164 additions & 0 deletions examples/doa/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
# Decoder-Only Attention (DOA) Policy

The [**Decoder-Only Attention (DOA)** policy](https://arxiv.org/abs/2605.31432) extends the
[encoder-decoder **StreamAtt** policy](https://aclanthology.org/2024.acl-long.202/) to SpeechLLMs
that have no cross-attention mechanism. Instead of relying on encoder-decoder cross-attention, DOA
builds a *proxy* cross-attention matrix by extracting the self-attention weights between the audio
tokens and the text tokens from the decoder layers. The resulting matrix is then used by the
[AlignAtt policy](https://www.isca-archive.org/interspeech_2023/papi23_interspeech.html) to decide
which generated tokens can be safely emitted at each step.

## Supported models

| Class | HuggingFace model |
|---|---|
| `simulstream.server.speech_processors.phi4multimodal_doa.Phi4MultimodalDOA` | `microsoft/Phi-4-multimodal-instruct` |
| `simulstream.server.speech_processors.qwenomni_doa.Qwen3OmniDOA` | `Qwen/Qwen3-Omni-30B-A3B-Instruct` |

## Configuration

A DOA config file is a YAML file passed via `--speech-processor-config`. Below is a full annotated
example, elements between `{}` brackets should be replaced as mentioned below:

```yaml
type: "{MODEL_CLASS}"
text_history:
type: "simulstream.server.speech_processors.base_streamatt.{TEXT_HISTORY}"
audio_history_max_duration: 180
text_history_max_len: 128
speech_chunk_size: 1 # seconds of audio fed to the model at each step
max_new_tokens: 32 # max tokens generated per chunk
hf_model_name: "{MODEL_NAME}"
detokenizer_type: "hf"
word_level_postprocess: {WORD_POSTPROCESS}
bow_prefix: "{BOW_MARKER}"
prompt: "{PROMPT}"

# --- DOA parameters ---
attn_layer: {ATTN_LAYER}
attn_head: {ATTN_HEAD}
average_attn_over_layers: {ATTN_AVG}
cutoff_frame_num: {CUTOFF_FRAME}
```

Parameters to be replaced:
- `{MODEL_CLASS}` from the [supported models Class](#supported-models)
(e.g., `simulstream.server.speech_processors.phi4multimodal_doa.Phi4MultimodalDOA`)
- `{TEXT_HISTORY}` among:
- `FixedWordsTextHistory`: Retains the last *N* complete words. Recommended for space-separated
languages (English, Italian, …). In this case, the number of `history_words` should be added to
the config, for instance:
```yaml
text_history:
type: "simulstream.server.speech_processors.base_streamatt.FixedWordsTextHistory"
history_words: 10
```
- `FixedCharsTextHistory`: Retains the last *N* characters. Recommended for character-level
languages (Chinese, Japanese) where `FixedWordsTextHistory` is ineffective because spaces are
sparse. n this case, the number of `history_chars` should be added to the config, for instance:
```yaml
text_history:
type: "simulstream.server.speech_processors.base_streamatt.FixedWordsTextHistory"
history_chars: 20
```
- `PunctuationTextHistory`: Retains the text from the last strong punctuation mark (`.`, `!`,
`?`, `:`, `;`, `。`). Works for both space-separated and character-level languages.
- `{MODEL_NAME}` from the [supported models HuggingFace model name](#supported-models) (e.g.,
`microsoft/Phi-4-multimodal-instruct`)
- `{WORD_POSTPROCESS}`: When `true`, the output is trimmed to complete words before emission.
Set to `false` for character-level languages (Chinese, Japanese).
- `{BOW_MARKER}`: The beginning-of-word (BOW) marker used by the model's tokenizer (e.g.,
Phi-4-multimodal and Qwen3-Omni use a plain space `" "`).
- `{PROMPT}`: User prompt. The default is `"Translate the audio to {tgt_lang}:"`. It can be
overridden with the `prompt` key in the yaml. The placeholders `{src_lang}` and `{tgt_lang}` are
filled in automatically from the language codes passed at inference time.
- `{ATTN_LAYER}`: Decoder layer to extract self-attention from (int, 0-indexed).
- `{ATTN_HEAD}`: Attention head to extract self-attention from (int, 0-indexed). `null` averages
over all heads.
- `{ATTN_AVG}`: If `true` (default), average the selected per-layer attention view across all
layers; `attn_layer` is used only when this is `false`.
- `{CUTOFF_FRAME}`: Cutoff frame of the AlignAtt policy. Tokens whose attention peak falls in the
last *N* audio frames are withheld. Higher values add more latency but reduce the risk of cutting
correct tokens.

## Configurations of DOA's paper

The configurations used to report the final results in Figure 3 are reported below:

### Phi4-Multimodal
```yaml
type: "simulstream.server.speech_processors.phi4multimodal_doa.Phi4MultimodalDOA"
text_history:
type: "simulstream.server.speech_processors.base_streamatt.PunctuationTextHistory"
audio_history_max_duration: 180
text_history_max_len: 128
speech_chunk_size: 1
detokenizer_type: "hf"
hf_model_name: "microsoft/Phi-4-multimodal-instruct"
word_level_postprocess: True
max_new_tokens: 32
bow_prefix: " "
attn_layer: 0
attn_head: null
average_attn_over_layers: True
cutoff_frame_num: __FRAME__
```

### Qwen3-Omni
```yaml
type: "simulstream.server.speech_processors.qwenomni_doa.Qwen3OmniDOA"
text_history:
type: "simulstream.server.speech_processors.base_streamatt.PunctuationTextHistory"
audio_history_max_duration: 60
text_history_max_len: 128
speech_chunk_size: 1
detokenizer_type: "hf"
hf_model_name: "Qwen/Qwen3-Omni-30B-A3B-Instruct"
word_level_postprocess: True
max_new_tokens: 32
bow_prefix: " "
prompt: "You are a professional {src_lang}-to-{tgt_lang} translator. Your goal is to accurately \
convey the meaning and nuances of the original {src_lang} speech while adhering to {tgt_lang} \
grammar, vocabulary, and cultural sensitivities. Use precise terminology and a tone appropriate \
for academic or instructional materials. Produce only the {tgt_lang} translation, without any \
additional explanations or commentary. Please translate the provided {src_lang} speech into \
{tgt_lang}:"
attn_layer: 0
attn_head: null
average_attn_over_layers: True
cutoff_frame_num: __FRAME__
```
To run the inference, `__FRAME__` should be replaced with `sed`:
```bash
simulstream_inference --speech-processor-config <(sed "s/__FRAME__/${FRAME}/g" ${CONFIG_YAML}) \
--wav-list-file ${AUDIOPATH_LIST} \
--tgt-lang $TGTLANG --src-lang en \
--metrics-log-file ${OUTLOG}
```
where `${FRAME}` is `5`, `10`, or `15` following the paper, `${CONFIG_YAML}` is the path to the
aforementioned configuration yaml file, `${AUDIOPATH_LIST}` is the list of test audio files path,
and `${OUTLOG}` is the path to the jsonl output log file.

## Adding a new model

To support a new SpeechLLM, subclass `DecoderOnlyAttention`
(`simulstream.server.speech_processors.base_doa.DecoderOnlyAttention`) and implement:

- `load_model(config)` — load the model and processor.
- `build_prompt()` — return the text prompt string.
- `build_processor_inputs(waveform)` — build processor inputs from the rolling audio history.
- `_do_generate(inputs)` — run generation and return `(new_tokens, attentions)`.
- `_find_audio_positions(input_ids)` — return the positions of audio tokens in the input sequence.

## Citation
If you use DOA in your work, please cite:

```bibtex
@article{papi-2026-doa,
title = {{DOA}: Training-Free Decoder-Only Attention Policy for Long-Form
Simultaneous Translation with {SpeechLLMs}},
author = {Papi, Sara and Bentivogli, Luisa},
journal = {arXiv preprint arXiv:2605.31432},
year = {2026},
}
```
3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ dependencies = [
"pyyaml>6.0",
"websockets",
"torch",
"librosa"
"librosa",
"pycountry"
]
dynamic = ["version"]

Expand Down
Loading
Loading