Site icon TechAIApp

Meta AI Releases Brain2Qwerty v2: A Non-Invasive MEG Brain-to-Text Pipeline Decoding Typed Sentences at 61% Word Accuracy


Meta AI just introduced Brain2Qwerty v2. It decodes natural sentences from non-invasive brain recordings in real time. The system reads magnetoencephalography (MEG) signals while a person types. It reconstructs what they typed, with no implant and no surgery. This is the follow-up to Brain2Qwerty v1, released in February 2025. Meta is also releasing the full training code for both versions. The pipeline combines a convolutional encoder, a transformer, and a character-level language model.

TL;DR

  • Brain2Qwerty v2 decodes typed sentences from non-invasive MEG signals, with no implant or surgery.
  • It reaches 61% average word accuracy (39% WER), up from 8% for prior non-invasive methods.
  • The best participant hit 78% word accuracy, with over half of sentences at one word error or less.
  • The pipeline pairs a convolutional encoder, transformer, and character-level language model, plus fine-tuned LLMs.
  • Accuracy scales log-linearly with data; training code for v1 and v2 is released under CC BY-NC 4.0.

What is Brain2Qwerty v2?

Brain2Qwerty v2 is a brain-to-text decoder. It maps raw brain activity to characters, then to words and sentences.

Meta trained it on approximately 22,000 sentences from nine volunteer participants. Each participant was recorded for 10 hours while actively typing.

Recordings come from a MEG device. MEG measures the magnetic fields produced by neuronal activity, sampled at high temporal resolution.

The model leverages character, word and sentence-level representations. That layered design lets it correct local errors using broader context.

Importantly, this is research, not a product. The decoder is not a consumer device, and it was tested on a small group of volunteers.

The data was collected with Spain’s BCBL (Basque Center on Cognition, Brain and Language). It belongs to that research center.

How the Decoding Pipeline Works

Earlier non-invasive systems relied on hand-crafted pipelines to detect neural events. Brain2Qwerty v2 replaces that step with end-to-end deep learning.

Per Meta’s repository, the model combines three components: a convolutional encoder, a transformer, and a character-level language model.

The convolutional encoder reads raw MEG signals. It learns features directly from the data instead of using engineered event detectors.

The transformer models longer-range structure across the signal. The character-level language model then constrains the output toward plausible text.

Meta research team describes three ways AI enables the result. Each maps to a concrete engineering decision teams will recognize.

  1. Deep learning replaces hand-crafted event detection.
  2. Large language models are fine-tuned to extract semantic representations.
  3. AI agents iteratively refined the decoding pipeline through automated code development. Final training configurations were still selected manually by devs

Fine-tuning large language models on neural data adds semantic context. That context bridges noisy brain recordings and coherent language output.

In practice, the language model rejects character sequences that form no real words. It pushes the decoder toward sentences a human would plausibly type.

Here is an illustrative sketch of the published architecture. It mirrors the described components and is not Meta’s exact training code.

import torch
import torch.nn as nn

class Brain2QwertySketch(nn.Module):
    """Illustrative: convolutional encoder -> transformer -> char-level head.
    Reflects the components Meta describes, not the official implementation."""
    def __init__(self, n_meg_channels=306, d_model=256, n_chars=40):
        super().__init__()
        # 1) Convolutional encoder over raw MEG channels x time
        self.encoder = nn.Sequential(
            nn.Conv1d(n_meg_channels, d_model, kernel_size=7, padding=3),
            nn.GELU(),
            nn.Conv1d(d_model, d_model, kernel_size=5, padding=2),
            nn.GELU(),
        )
        # 2) Transformer models temporal structure
        layer = nn.TransformerEncoderLayer(d_model, nhead=8, batch_first=True)
        self.transformer = nn.TransformerEncoder(layer, num_layers=6)
        # 3) Character-level head; a language model refines this downstream
        self.char_head = nn.Linear(d_model, n_chars)

    def forward(self, meg):           # meg: (batch, channels, time)
        x = self.encoder(meg)         # (batch, d_model, time)
        x = x.transpose(1, 2)         # (batch, time, d_model)
        x = self.transformer(x)       # contextualized features
        return self.char_head(x)      # (batch, time, n_chars)

To work with Meta’s real code, clone the repository and inspect both versions:

git clone https://github.com/facebookresearch/brain2qwerty
# brain2qwerty_v1/ and brain2qwerty_v2/ hold the training code

The Accuracy Numbers

Brain2Qwerty v2 achieves an average word accuracy rate of 61%. That corresponds to a word error rate (WER) of 39%.

For the best participant, the model reaches 78% word accuracy. For that participant, over half of sentences had one word error or less.

The prior baseline matters here. Meta reports that other non-invasive methods reached only 8% word accuracy.

Accuracy also improves log-linearly with data volume. More recording hours predictably raise accuracy in the reported range.

That scaling behavior is the key claim for builders. It suggests the gap with surgical implants could narrow through data alone.

Metric Brain2Qwerty v2 Prior non-invasive methods
Average word accuracy 61% 8%
Average word error rate (WER) 39%
Best participant word accuracy 78%
Recording method MEG, non-invasive Non-invasive
Scaling behavior Log-linear with data

These numbers come from volunteers in a controlled setting. They are not clinical results for patients with brain injuries.

v1 vs v2: What Changed

Brain2Qwerty v1 and v2 report different metrics, so compare them carefully. v1 was measured at character level, v2 at word level.

Aspect Brain2Qwerty v1 (Feb 2025) Brain2Qwerty v2 (Jun 2026)
Devices MEG and EEG MEG
Participants 35 healthy volunteers 9 volunteers
Data Typed sentences ~22,000 sentences, 10 hours each
Reported result Up to 80% of characters (MEG) 61% average word accuracy
Representation level Character-level Character, word and sentence-level
Real-time decoding Not emphasized Real-time sentence decoding

v1 also showed MEG decoding was at least twice better than the EEG system. EEG signals are noisier, which limits accuracy.

Use Cases With Examples

  • The primary motivation is restoring communication. Millions of people have brain lesions that prevent them from speaking or moving.
  • Invasive methods like stereotactic electroencephalography and electrocorticography already feed a neuroprosthesis to an AI decoder. But they require neurosurgery and are hard to scale.
  • A non-invasive decoder could widen access. A patient could potentially type sentences without an implant, using only external recordings.
  • For researchers, the released code supports reproducible neuroscience. A lab could retrain the pipeline on its own MEG dataset.
  • For AI engineers, the project is a template for biosignal decoding. The convolutional-encoder-plus-transformer pattern transfers to other biosignal tasks.
  • For data scientists, the log-linear scaling result is a planning tool. It frames how much new recording data may lift accuracy.

Interactive Explainer


// —- accuracy model (maps device + data hours -> target word accuracy) —-
// MEG v2 at 10h ~ 0.61 avg; log-linear in data; EEG far lower (prior methods ~0.08).
function targetAccuracy(){
var h=+dataEl.value, frac=Math.log(h)/Math.log(10); // 0..1 across 1..10h
if(device===’meg’){
var lo=0.18, hi=0.61; // 1h floor -> 10h reported avg
return lo+(hi-lo)*frac;
}else{
var elo=0.05, ehi=0.22; // EEG stays low; ~prior non-invasive band
return elo+(ehi-elo)*frac;
}
}

// —- helpers: corrupt characters, then “LM snap” to words —-
function corruptChars(s,charErr){
var keys=”abcdefghijklmnopqrstuvwxyz”;
return s.split(”).map(function(ch){
if(ch===’ ‘)return ‘ ‘;
if(Math.random()‘+keys[Math.floor(Math.random()*26)]+”;}
return ch;
}).join(”);
}
// word-level edit distance (Levenshtein on tokens)
function werWords(ref,hyp){
var a=ref.split(/\s+/),b=hyp.split(/\s+/),n=a.length,m=b.length;
var d=[];for(var i=0;i<=n;i++){d[i]=[i];}
for(var j=0;j<=m;j++){d[0][j]=j;}
for(i=1;i<=n;i++)for(j=1;j<=m;j++){
var c=a[i-1]===b[j-1]?0:1;
d[i][j]=Math.min(d[i-1][j]+1,d[i][j-1]+1,d[i-1][j-1]+c);
}
return {dist:d[n][m],n:n};
}
// produce a decoded hypothesis at a given word-accuracy by swapping some words
var SWAPS={the:’they’,meeting:’meaning’,scheduled:’schedule’,tomorrow:’tomorow’,
afternoon:’aftermoon’,please:’pleased’,bring:’brings’,documents:’document’,
office:’offices’,would:’could’,like:’liked’,glass:’class’,cold:’gold’,water:’waiter’,
train:’rain’,leaves:’leaved’,station:’stations’,nine:’mine’,reading:’leading’,
book:’look’,garden:’harden’,she:’see’,is:’in’,my:’by’,to:’too’,for:’far’,of:’on’,at:’as’,a:’as’,i:’a’};
// corrupt exactly k swappable words (k driven by target accuracy) for stable metrics
function decodeWords(s,wordAcc){
var words=s.split(‘ ‘);
var idx=[];words.forEach(function(w,i){if(SWAPS[w])idx.push(i);});
var nBad=Math.round((1-wordAcc)*words.length);
nBad=Math.max(0,Math.min(nBad,idx.length));
// shuffle swappable indices, take first nBad
for(var i=idx.length-1;i>0;i–){var j=Math.floor(Math.random()*(i+1));var t=idx[i];idx[i]=idx[j];idx[j]=t;}
var bad={};idx.slice(0,nBad).forEach(function(i){bad[i]=1;});
return words.map(function(w,i){
if(bad[i])return {w:SWAPS[w],ok:false};
return {w:w,ok:true};
});
}

// —- scope animation —-
function drawScope(progress,noise){
var W=canvas.width,H=canvas.height;ctx.clearRect(0,0,W,H);
ctx.lineWidth=1.6;
for(var lane=0;lane<3;lane++){
ctx.beginPath();
var base=H*(0.32+lane*0.2), amp=12-lane*2, col=[‘#5fd0de’,’#8fe0ea’,’#3fb9c9′][lane];
ctx.strokeStyle=col;ctx.globalAlpha=0.5+lane*0.12;
for(var x=0;x<=W;x+=4){
var p=x/W, on=p=1 && !noisyEl.dataset.set){ // reveal noisy chars at encoder stage
noisyEl.innerHTML=corruptChars(sentence,charErr); noisyEl.dataset.set=”1″;
slab.textContent=”decoding characters”;
}
if(p<1){animRAF=requestAnimationFrame(loop);}else{finish(wordAcc,sentence);}
}
noisyEl.dataset.set=””;
animRAF=requestAnimationFrame(loop);

function finish(wordAcc,sentence){
stages.forEach(function(s){s.classList.remove(‘active’);s.classList.add(‘done’);});
slab.textContent=”sentence recovered”;
// build LM-corrected output
var dec=decodeWords(sentence,wordAcc);
finalEl.innerHTML=dec.map(function(o){
return ‘‘+o.w+’‘;
}).join(‘ ‘);
var hyp=dec.map(function(o){return o.w;}).join(‘ ‘);
var w=werWords(sentence,hyp);
// displayed accuracy tracks the modeled target (stable), with light jitter
var acc=Math.round(wordAcc*100 + (Math.random()*4-2));
acc=Math.max(0,Math.min(100,acc));
var werPct=100-acc;
animateNumber(accEl,0,acc,’%’,900,function(){
accBar.style.width=acc+’%’;
});
animateNumber(werEl,0,werPct,’%’,900,function(){werBar.style.width=werPct+’%’;});
// contextual note
var note=document.getElementById(‘b2qNote’);
if(device===’eeg’){
note.innerHTML=’EEG path: electric-field recordings are noisier, so accuracy stays low — close to the ~8% band reported for prior non-invasive methods.’;
}else if(+dataEl.value<10){
note.innerHTML=’Data scaling: at ‘+dataEl.value+’ h the model trails its ceiling. Accuracy climbs log-linearly toward the reported 61% average at 10 h.’;
}else{
note.innerHTML=’MEG v2 · full data: this lands near the reported 61% average word accuracy. Meta\’s best participant reached 78%, decoding over half of sentences with one word error or less.’;
}
busy=false;runBtn.classList.remove(‘busy’);runBtn.disabled=false;runTxt.textContent=”Decode again”;
postHeight();
}
}
runBtn.addEventListener(‘click’,run);

// idle scope shimmer
(function idle(){
if(!busy){var W=canvas.width,H=canvas.height;ctx.clearRect(0,0,W,H);
ctx.strokeStyle=”rgba(95,208,222,.25)”;ctx.lineWidth=1.4;ctx.beginPath();
for(var x=0;x<=W;x+=6){var y=H*0.5+Math.sin(x*0.03+performance.now()*0.0014)*5;
if(x===0)ctx.moveTo(x,y);else ctx.lineTo(x,y);}ctx.stroke();}
requestAnimationFrame(idle);
})();

setTimeout(postHeight,400);
})();



Source link

Exit mobile version