Skip to main content

entrenar/hf_pipeline/export/
publish_pipeline.rs

1//! Quantize-Export-Publish pipeline (feature-gated: hub-publish)
2//!
3//! Combines quantization, GGUF export, and HuggingFace Hub publishing
4//! into a single pipeline operation.
5
6use crate::hf_pipeline::error::FetchError;
7use crate::hf_pipeline::export::gguf_writer::GgufQuantization;
8use crate::hf_pipeline::export::pipeline::{quantize_and_export, QuantExportResult};
9use crate::hf_pipeline::export::weights::ModelWeights;
10use crate::hf_pipeline::publish::config::PublishConfig;
11use crate::hf_pipeline::publish::publisher::HfPublisher;
12use crate::hf_pipeline::publish::result::{PublishError, PublishResult};
13use std::path::Path;
14
15/// Result of the full quantize-export-publish pipeline
16#[derive(Debug, Clone)]
17pub struct QuantPublishResult {
18    /// Quantize-export result
19    pub export: QuantExportResult,
20    /// Publish result from HuggingFace Hub
21    pub publish: PublishResult,
22}
23
24/// Quantize, export to GGUF, and publish to HuggingFace Hub
25///
26/// Full pipeline:
27/// 1. Quantize weights (Q4_0, Q8_0, or unquantized)
28/// 2. Export as GGUF with metadata
29/// 3. Generate model card/README
30/// 4. Publish to HuggingFace Hub
31pub fn quantize_export_publish(
32    weights: &ModelWeights,
33    quantization: GgufQuantization,
34    publish_config: PublishConfig,
35    output_dir: impl AsRef<Path>,
36) -> std::result::Result<QuantPublishResult, QuantPublishError> {
37    let output_dir = output_dir.as_ref();
38    let filename = "model.gguf";
39
40    // Step 1+2: Quantize and export
41    let export_result = quantize_and_export(weights, quantization, output_dir, filename)
42        .map_err(QuantPublishError::Export)?;
43
44    // Step 3: Create publisher and publish
45    let publisher = HfPublisher::new(publish_config).map_err(QuantPublishError::Publish)?;
46
47    let gguf_path = output_dir.join(filename);
48    let files: Vec<(&Path, &str)> = vec![(&gguf_path, filename)];
49
50    // Publish files (no ModelCard — we upload the README separately)
51    let mut publish_result = publisher.publish(&files, None).map_err(QuantPublishError::Publish)?;
52
53    // Upload generated README if available
54    if let Some(readme) = &export_result.readme {
55        publisher
56            .upload_bytes(readme.as_bytes(), "README.md")
57            .map_err(QuantPublishError::Publish)?;
58        publish_result.model_card_generated = true;
59    }
60
61    Ok(QuantPublishResult { export: export_result, publish: publish_result })
62}
63
64/// Errors from the quantize-export-publish pipeline
65#[derive(Debug, thiserror::Error)]
66pub enum QuantPublishError {
67    /// Export phase failed
68    #[error("Export failed: {0}")]
69    Export(FetchError),
70
71    /// Publish phase failed
72    #[error("Publish failed: {0}")]
73    Publish(PublishError),
74}