pub struct QwenImageEncoder { /* private fields */ }Expand description
Qwen2.5-VL prompt encoder. The component CMF retains the official
model.* and visual.* tensor names, plus U8 image.*_json assets.
Implementations§
Source§impl QwenImageEncoder
impl QwenImageEncoder
Sourcepub fn open(path: &Path) -> Result<Self, String>
pub fn open(path: &Path) -> Result<Self, String>
Open a standalone Qwen2.5-VL component CMF. Sharded CMFs are opened through the core loader so the language and vision mappings remain lazy and no giant F32 embedding copy is created.
Examples found in repository?
138fn main() -> Result<(), Box<dyn Error>> {
139 let mut args = std::env::args_os().skip(1);
140 let fixture_path = PathBuf::from(args.next().ok_or("missing fixture JSON")?);
141 let cmf_path = PathBuf::from(args.next().ok_or("missing output CMF")?);
142 let fixture: Fixture = serde_json::from_slice(&std::fs::read(&fixture_path)?)?;
143 if fixture.grid != vec![1usize, 6, 10] || fixture.ids.len() <= 64 {
144 return Err(format!(
145 "unexpected fixture geometry grid={:?} ids={}",
146 fixture.grid,
147 fixture.ids.len()
148 )
149 .into());
150 }
151 if fixture.image_rgb.len() != fixture.image_width as usize * fixture.image_height as usize * 3 {
152 return Err("fixture RGB byte count does not match image dimensions".into());
153 }
154 pack(&fixture, &cmf_path)?;
155 let model = CmfModel::open(&cmf_path)?;
156 if !model.verify().is_empty() {
157 return Err(format!("fixture CMF failed verification: {:?}", model.verify()).into());
158 }
159 let encoder = QwenImageEncoder::open(&cmf_path)?;
160 let image = image::RgbImage::from_raw(
161 fixture.image_width,
162 fixture.image_height,
163 fixture.image_rgb.clone(),
164 )
165 .ok_or("fixture RGB image could not be constructed")?;
166 let output = encoder.encode(&fixture.prompt, &[image])?;
167 if output.hidden_size != 12 || output.seq_len * output.hidden_size != fixture.expected.len() {
168 return Err(format!(
169 "native conditioning shape {}×{} does not match oracle {} values",
170 output.seq_len,
171 output.hidden_size,
172 fixture.expected.len()
173 )
174 .into());
175 }
176 check(&output.hidden, &fixture.expected)?;
177 println!(
178 "encoder tiny fixture PASS: tokens={} rows={} grid={:?}",
179 fixture.ids.len(),
180 output.seq_len,
181 fixture.grid
182 );
183 Ok(())
184}Sourcepub fn model_uid(&self) -> u64
pub fn model_uid(&self) -> u64
Stable CMF identity for the caller’s targeted GPU buffer release after this encoder’s stage scope ends. The encoder keeps this value available without exposing its internal model mapping.
Sourcepub fn encode(
&self,
prompt: &str,
images: &[RgbImage],
) -> Result<Conditioning, String>
pub fn encode( &self, prompt: &str, images: &[RgbImage], ) -> Result<Conditioning, String>
Encode a positive or negative prompt with the same reference image list. The caller invokes this once for each true-CFG branch; image preprocessing and vision placeholders therefore remain identical.
Examples found in repository?
138fn main() -> Result<(), Box<dyn Error>> {
139 let mut args = std::env::args_os().skip(1);
140 let fixture_path = PathBuf::from(args.next().ok_or("missing fixture JSON")?);
141 let cmf_path = PathBuf::from(args.next().ok_or("missing output CMF")?);
142 let fixture: Fixture = serde_json::from_slice(&std::fs::read(&fixture_path)?)?;
143 if fixture.grid != vec![1usize, 6, 10] || fixture.ids.len() <= 64 {
144 return Err(format!(
145 "unexpected fixture geometry grid={:?} ids={}",
146 fixture.grid,
147 fixture.ids.len()
148 )
149 .into());
150 }
151 if fixture.image_rgb.len() != fixture.image_width as usize * fixture.image_height as usize * 3 {
152 return Err("fixture RGB byte count does not match image dimensions".into());
153 }
154 pack(&fixture, &cmf_path)?;
155 let model = CmfModel::open(&cmf_path)?;
156 if !model.verify().is_empty() {
157 return Err(format!("fixture CMF failed verification: {:?}", model.verify()).into());
158 }
159 let encoder = QwenImageEncoder::open(&cmf_path)?;
160 let image = image::RgbImage::from_raw(
161 fixture.image_width,
162 fixture.image_height,
163 fixture.image_rgb.clone(),
164 )
165 .ok_or("fixture RGB image could not be constructed")?;
166 let output = encoder.encode(&fixture.prompt, &[image])?;
167 if output.hidden_size != 12 || output.seq_len * output.hidden_size != fixture.expected.len() {
168 return Err(format!(
169 "native conditioning shape {}×{} does not match oracle {} values",
170 output.seq_len,
171 output.hidden_size,
172 fixture.expected.len()
173 )
174 .into());
175 }
176 check(&output.hidden, &fixture.expected)?;
177 println!(
178 "encoder tiny fixture PASS: tokens={} rows={} grid={:?}",
179 fixture.ids.len(),
180 output.seq_len,
181 fixture.grid
182 );
183 Ok(())
184}Sourcepub fn encode_pair(
&self,
prompt: &str,
negative_prompt: &str,
images: &[RgbImage],
) -> Result<(Conditioning, Conditioning), String>
pub fn encode_pair( &self, prompt: &str, negative_prompt: &str, images: &[RgbImage], ) -> Result<(Conditioning, Conditioning), String>
Name matching the pipeline’s positive/negative branch operation while keeping one shared image list and one immutable encoder mapping.