File size: 4,725 Bytes
61b0657
2b9d7ab
 
 
61b0657
2b9d7ab
 
 
 
 
 
 
 
61b0657
2b9d7ab
 
61b0657
fe4323b
61b0657
 
2b9d7ab
 
 
61b0657
2b9d7ab
 
 
 
61b0657
2b9d7ab
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61b0657
2b9d7ab
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61b0657
2b9d7ab
 
 
 
 
 
 
 
 
 
 
61b0657
2b9d7ab
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
import gradio as gr
import subprocess
import threading
import time

def get_md_content(file_path):
    try:
        with open(file_path, 'r', encoding='utf-8') as f:
            return f.read()
    except FileNotFoundError:
        return f"Error: {file_path} not found."
    except Exception as e:
        return f"An error occurred: {e}"

def run_script():
    """Function to run the fine-tuning script and stream output."""
    process = subprocess.Popen(
        ['python3', 'fine_tune_improved.py'],
        stdout=subprocess.PIPE,
        stderr=subprocess.STDOUT,
        text=True,
        bufsize=1,
        universal_newlines=True
    )
    output = ""
    for line in process.stdout:
        output += line
        yield output
    process.wait()

# JavaScript to find and render Mermaid diagrams
js_script = """
() => {
    function initMermaidAndConvert() {
        // Wait for mermaid to be available
        if (typeof mermaid === 'undefined') {
            console.log('Mermaid not loaded yet, retrying...');
            setTimeout(initMermaidAndConvert, 100);
            return;
        }
        
        console.log('Mermaid loaded successfully');
        // Initialize mermaid
        mermaid.initialize({ 
            startOnLoad: false, 
            theme: 'default',
            securityLevel: 'loose'
        });
        
        function convertMermaidCodeBlocks() {
            console.log('Converting Mermaid code blocks...');
            let processedCount = 0;
            
            // Look for pre blocks that contain mermaid syntax
            document.querySelectorAll('pre').forEach((pre, index) => {
                const code = pre.querySelector('code');
                if (code && !pre.classList.contains('mermaid-processed')) {
                    const text = code.textContent.trim();
                    // Check if it contains mermaid syntax
                    const isMermaid = text.includes('graph ') || 
                                    text.includes('flowchart ') || 
                                    text.includes('subgraph ') ||
                                    text.startsWith('graph') ||
                                    text.startsWith('flowchart') ||
                                    text.includes('classDiagram') ||
                                    text.includes('sequenceDiagram');
                    
                    if (isMermaid) {
                        console.log(`Found Mermaid diagram ${processedCount + 1}:`, text.substring(0, 50) + '...');
                        pre.classList.add('mermaid');
                        pre.classList.add('mermaid-processed');
                        pre.textContent = text;
                        processedCount++;
                    }
                }
            });
            
            console.log(`Processed ${processedCount} Mermaid diagrams`);
            // Run Mermaid
            try {
                mermaid.run();
            } catch (e) {
                console.log('Mermaid rendering error:', e);
            }
        }

        // Use a MutationObserver to re-run the conversion when Gradio updates the page
        const observer = new MutationObserver((mutations) => {
            // A simple debounce to avoid excessive re-renders
            clearTimeout(window.mermaidTimeout);
            window.mermaidTimeout = setTimeout(convertMermaidCodeBlocks, 100);
        });
        observer.observe(document.body, { childList: true, subtree: true });

        // Initial run
        convertMermaidCodeBlocks();
    }
    
    // Start the initialization
    initMermaidAndConvert();
}
"""

# HTML to include the Mermaid.js library
head_script = '<script src="https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></script>'

with gr.Blocks(theme=gr.themes.Soft(), head=head_script, js=js_script) as demo:
    gr.Markdown("# 微调技术分享")

    with gr.Tabs():
        with gr.TabItem("分享大纲"):
            gr.Markdown(get_md_content("outline.md"))
        
        with gr.TabItem("核心技术概览"):
            gr.Markdown(get_md_content("presentation.md"))

        with gr.TabItem("LoRA & QLoRA 深度解析"):
            gr.Markdown(get_md_content("lora_qlora_deep_dive.md"))



        with gr.TabItem("动手实战:模型微调"):
            with gr.Row():
                start_button = gr.Button("开始微调", variant="primary")
            
            log_output = gr.Textbox(
                label="训练日志",
                interactive=False,
                lines=20,
                show_copy_button=True
            )
            start_button.click(fn=run_script, outputs=log_output)

if __name__ == "__main__":
    demo.launch()