Spaces:
Sleeping
Sleeping
| import streamlit as st | |
| # ========================================== | |
| # 页面基础配置 | |
| # ========================================== | |
| st.set_page_config( | |
| page_title="AI 团队协作深度指南", | |
| page_icon="🤗", | |
| layout="wide", | |
| initial_sidebar_state="expanded" | |
| ) | |
| # 统一的 CSS 样式调整 | |
| st.markdown(""" | |
| <style> | |
| .big-font { font-size:18px !important; line-height: 1.6; } | |
| .why-box { background-color: #f0f8ff; padding: 15px; border-left: 5px solid #1e90ff; border-radius: 5px; margin-bottom: 20px;} | |
| .danger-box { background-color: #ffe4e1; padding: 15px; border-left: 5px solid #ff4500; border-radius: 5px; margin-bottom: 20px;} | |
| </style> | |
| """, unsafe_allow_html=True) | |
| # ========================================== | |
| # 侧边栏导航 | |
| # ========================================== | |
| with st.sidebar: | |
| # 如果本地没有这个图片,可以使用在线链接或删掉这行 | |
| st.image("https://huggingface.co/front/assets/huggingface_logo-noborder.svg", width=50) | |
| st.title("团队协作 Wiki") | |
| st.markdown("---") | |
| menu = [ | |
| "🏠 首页:理念与权限", | |
| "📊 数据集 (Datasets) 实战", | |
| "🤖 模型 (Models) 实战", | |
| "🔄 核心:Git 协作工作流" | |
| ] | |
| choice = st.radio("📚 章节导航:", menu) | |
| st.markdown("---") | |
| st.caption("👩💻 维护者:团队架构组") | |
| st.caption("📅 版本:3.0 (代码实战版)") | |
| # ========================================== | |
| # 页面内容渲染 | |
| # ========================================== | |
| # --------------------------------------------------------- | |
| # 1. 首页 | |
| # --------------------------------------------------------- | |
| if choice == "🏠 首页:理念与权限": | |
| st.title("🤗 团队研发协作指南") | |
| st.markdown("<p class='big-font'>欢迎加入!本文档不仅指导你如何使用 Hugging Face,更将解释我们为什么要采用这套工业级协作标准。</p>", unsafe_allow_html=True) | |
| st.header("1. 底层理念:为什么不用网盘或 FTP?") | |
| st.markdown(""" | |
| <div class='why-box'> | |
| <b>💡 设计意义:</b><br> | |
| 在 AI 研发中,“数据版本”和“代码版本”是等价重要的。如果你用网盘传文件,一旦有人覆盖了 <code>dataset_final_v2.csv</code>,整个团队的心血就会瞬间蒸发,且无法回溯。<br> | |
| Hugging Face 的底层是 <b>Git LFS (Large File Storage)</b>。每一次数据修改、模型权重的迭代,都被打上了时间戳和数字签名,团队可以随时“时光倒流”到任意一个稳定版本。 | |
| </div> | |
| """, unsafe_allow_html=True) | |
| st.header("2. 权限隔离机制") | |
| st.markdown("团队项目统一托管在 Organization 下,且默认 **Private(私有)**。") | |
| col1, col2 = st.columns(2) | |
| with col1: | |
| st.info("**组员 (Write)**:\n具备拉取、创建分支、提交修改的权限,但**无权直接修改主线业务**。") | |
| with col2: | |
| st.warning("**组长 (Admin)**:\n负责全局把控,唯有 Admin 有权通过 Pull Request 将修改合并到主分支 (main)。") | |
| # --------------------------------------------------------- | |
| # 2. 数据集实战 | |
| # --------------------------------------------------------- | |
| elif choice == "📊 数据集 (Datasets) 实战": | |
| st.title("📊 数据集管理:上传与下载指南") | |
| st.markdown("<p class='big-font'>确保 Hugging Face 上的 main 分支永远是 <b>唯一可靠的真理源 (Single Source of Truth)</b>。</p>", unsafe_allow_html=True) | |
| tab1, tab2 = st.tabs(["⏬ 下载数据 (Download)", "⏫ 上传数据 (Upload)"]) | |
| with tab1: | |
| st.subheader("方案 A:Python API 直接加载(推荐)") | |
| st.markdown("自动下载、缓存并解析数据。对于超大数据集可开启流式加载 (`streaming=True`)。") | |
| st.code(""" | |
| from datasets import load_dataset | |
| # ================= 修改区 ================= | |
| REPO_ID = "你们的组织名/数据集仓库名" # 例如:"AILab/clean-audio-signals" | |
| TOKEN = "你的hf_xxxxxx" # 替换为你的真实 Token | |
| # ========================================== | |
| # 加载数据集到本地缓存 | |
| dataset = load_dataset(REPO_ID, token=TOKEN) | |
| print("下载成功!来看看第一条数据:") | |
| print(dataset['train'][0]) | |
| """, language="python") | |
| with tab2: | |
| st.subheader("方案 A:Python API 直接推文件(推荐单文件)") | |
| st.code(""" | |
| from huggingface_hub import HfApi | |
| api = HfApi() | |
| # ================= 修改区 ================= | |
| LOCAL_FILE_PATH = "data/batch_06.csv" # 本地刚清洗好的数据文件 | |
| REPO_ID = "你们的组织名/数据集仓库名" # 目标数据集仓库 | |
| FILE_IN_REPO = "cleaned_data/batch_06.csv" # 云端存储路径 | |
| TOKEN = "你的hf_xxxxxx" | |
| # ========================================== | |
| api.upload_file( | |
| path_or_fileobj=LOCAL_FILE_PATH, | |
| path_in_repo=FILE_IN_REPO, | |
| repo_id=REPO_ID, | |
| repo_type="dataset", # ⚠️ 关键:指定类型为 dataset | |
| token=TOKEN | |
| ) | |
| print("数据已成功上传!") | |
| """, language="python") | |
| st.subheader("方案 B:Git LFS 命令行推大文件夹(适合海量图片/音频)") | |
| st.code(""" | |
| git clone https://huggingface.co/datasets/组织名/仓库名 | |
| cd 仓库名 | |
| # 放入大量图片后,一定要追踪大文件格式! | |
| git lfs track "*.png" | |
| git add . | |
| git commit -m "Upload raw image dataset batch 1" | |
| git push | |
| """, language="bash") | |
| # --------------------------------------------------------- | |
| # 3. 模型实战 | |
| # --------------------------------------------------------- | |
| elif choice == "🤖 模型 (Models) 实战": | |
| st.title("🤖 模型托管:上传与下载指南") | |
| st.markdown("<p class='big-font'>无论是 LLM 还是小型的信号处理分类器,都可以托管在 Models 仓库中。</p>", unsafe_allow_html=True) | |
| tab1, tab2, tab3 = st.tabs(["⏬ 下载模型 (Download)", "⏫ 上传模型 (Upload)", "📝 自动写 README"]) | |
| with tab1: | |
| st.subheader("方案 A:Hugging Face 原生架构一键加载") | |
| st.code(""" | |
| from transformers import AutoModel, AutoTokenizer | |
| REPO_ID = "组织名/微调后的模型名" | |
| TOKEN = "你的hf_xxxxxx" | |
| tokenizer = AutoTokenizer.from_pretrained(REPO_ID, token=TOKEN) | |
| model = AutoModel.from_pretrained(REPO_ID, token=TOKEN) | |
| """, language="python") | |
| st.subheader("方案 B:自定义小模型精确下载权重") | |
| st.code(""" | |
| from huggingface_hub import hf_hub_download | |
| import torch | |
| # 将指定权重文件下载到缓存目录,并返回绝对路径 | |
| file_path = hf_hub_download( | |
| repo_id="组织名/信号分类小模型", | |
| filename="model_weights.pth", | |
| token="你的hf_xxxxxx" | |
| ) | |
| # my_model.load_state_dict(torch.load(file_path)) | |
| """, language="python") | |
| with tab2: | |
| st.subheader("方案 A:Trainer/Transformers 一键上传") | |
| st.code(""" | |
| model.push_to_hub( | |
| repo_id="组织名/新模型", | |
| token="你的hf_xxxxxx", | |
| commit_message="微调完成" | |
| ) | |
| """, language="python") | |
| st.subheader("方案 B:上传整个实验文件夹(含代码、日志和权重)") | |
| st.code(""" | |
| from huggingface_hub import HfApi | |
| api = HfApi() | |
| api.upload_folder( | |
| folder_path="./experiment_04_results", # 本地实验产出文件夹 | |
| repo_id="组织名/实验记录专用模型库", | |
| repo_type="model", | |
| token="你的hf_xxxxxx" | |
| ) | |
| """, language="python") | |
| with tab3: | |
| st.subheader("强制自动化 README 规范") | |
| st.markdown(""" | |
| <div class='why-box'> | |
| <b>💡 规范要求:</b>严禁手工填写实验指标!请在训练脚本末尾加入以下代码,实现真实客观的自动记录。 | |
| </div> | |
| """, unsafe_allow_html=True) | |
| st.code(""" | |
| import json | |
| from huggingface_hub import HfApi | |
| def upload_artifacts(model_path, metrics_dict, repo_id, token): | |
| api = HfApi() | |
| # 动态构建说明书 | |
| readme_content = f\"\"\"--- | |
| language: zh | |
| tags: | |
| - signal-classification | |
| --- | |
| # 自动生成的模型说明 | |
| ## 测试集表现 | |
| {json.dumps(metrics_dict, indent=4)} | |
| \"\"\" | |
| with open("README.md", "w") as f: | |
| f.write(readme_content) | |
| api.upload_folder( | |
| folder_path=".", | |
| allow_patterns=["*.pth", "README.md"], | |
| repo_id=repo_id, | |
| token=token | |
| ) | |
| """, language="python") | |
| # --------------------------------------------------------- | |
| # 4. Git 工作流 | |
| # --------------------------------------------------------- | |
| elif choice == "🔄 核心:Git 协作工作流": | |
| st.title("🔄 任务协同与代码流转机制") | |
| st.markdown("<p class='big-font'>这是团队防错机制的核心,务必严格遵守以下 4 步走流程。</p>", unsafe_allow_html=True) | |
| with st.expander("步骤 1:基于 Discussion 领任务", expanded=True): | |
| st.markdown(""" | |
| **操作:** 组长在 Community 发起任务,并 `@相关组员`。 | |
| <div class='why-box'> | |
| <b>💡 设计意义 (信息透明):</b>公开的 Discussion 让整个团队看到当前进度,且所有关于任务的疑问都在同一个帖子里沉淀。 | |
| </div> | |
| """, unsafe_allow_html=True) | |
| with st.expander("步骤 2:创建功能分支 (Branch)", expanded=True): | |
| st.markdown(""" | |
| **操作:** `git checkout -b feature/your-name-task` | |
| <div class='danger-box'> | |
| <b>🚫 危险行为:</b>直接在主干 (main) 上修改代码或上传数据。<br> | |
| <b>💡 设计意义 (沙盒隔离):</b>分支就像是“平行宇宙”,在自己分支上做错任何事都不会影响主线。 | |
| </div> | |
| """, unsafe_allow_html=True) | |
| with st.expander("步骤 3:发起 Pull Request (合并请求)", expanded=True): | |
| st.markdown(""" | |
| **操作:** 在网页端将分支请求合并到 main,并 `@组长` 审核。 | |
| <div class='why-box'> | |
| <b>💡 设计意义 (强制安检):</b>PR 是一道安检门,强迫主管审视代码差异,是防止脏数据混入标准集的最有效手段。 | |
| </div> | |
| """, unsafe_allow_html=True) | |
| with st.expander("步骤 4:代码审查 (Code Review) 与合并", expanded=True): | |
| st.markdown(""" | |
| **操作:** 组长审核无误后,点击 Merge。 | |
| <div class='why-box'> | |
| <b>💡 设计意义 (责任转移):</b>一旦点击 Merge,该代码引发的后果将由团队承担,这是保护工程师的终极机制。 | |
| </div> | |
| """, unsafe_allow_html=True) |