""" ParamHub - 参数百科 AI大模型与硬件参数速查平台 """ from flask import Flask, render_template, jsonify, request from flask_cors import CORS import json from pathlib import Path from datetime import datetime app = Flask(__name__, static_folder='static', static_url_path='/static') CORS(app) # 数据目录 DATA_DIR = Path(__file__).parent / 'data' DATA_DIR.mkdir(exist_ok=True) # 数据文件 MODELS_FILE = DATA_DIR / 'models.json' GPUS_FILE = DATA_DIR / 'gpus.json' CPUS_FILE = DATA_DIR / 'cpus.json' CATEGORIES_FILE = DATA_DIR / 'categories.json' KNOWLEDGE_FILE = DATA_DIR / 'knowledge.json' def load_data(file_path): """加载JSON数据""" if file_path.exists(): return json.loads(file_path.read_text(encoding='utf-8')) return [] def save_data(file_path, data): """保存JSON数据""" file_path.write_text(json.dumps(data, ensure_ascii=False, indent=2), encoding='utf-8') # ============ 页面路由 ============ @app.route('/') def index(): """首页""" return render_template('index.html') @app.route('/models') def models_page(): """模型数据库页面""" return render_template('models.html') @app.route('/gpus') def gpus_page(): """GPU数据库页面""" return render_template('gpus.html') @app.route('/cpus') def cpus_page(): """CPU数据库页面""" return render_template('cpus.html') @app.route('/tools') def tools_page(): """工具页面""" return render_template('tools.html') @app.route('/compare') def compare_page(): """对比页面""" return render_template('compare.html') @app.route('/knowledge') def knowledge_page(): """知识库页面""" return render_template('knowledge.html') @app.route('/admin') def admin_page(): """后台管理页面""" return render_template('admin.html') @app.route('/category/') def category_page(category_id): """动态分类页面""" categories = load_data(CATEGORIES_FILE) category = next((c for c in categories if c['id'] == category_id), None) if not category: return "分类不存在", 404 return render_template('category.html', category=category) # ============ API路由 ============ @app.route('/api/models') def api_models(): """获取模型列表""" models = load_data(MODELS_FILE) # 搜索过滤 keyword = request.args.get('q', '').strip().lower() if keyword: models = [m for m in models if keyword in m.get('name', '').lower() or keyword in m.get('organization', '').lower()] # 排序 sort_by = request.args.get('sort', 'name') reverse = request.args.get('order', 'asc') == 'desc' if sort_by in ['name', 'parameters', 'context_length', 'mmlu']: models = sorted(models, key=lambda x: x.get(sort_by, 0) or 0, reverse=reverse) return jsonify(models) @app.route('/api/models/') def api_model_detail(model_id): """获取单个模型详情""" models = load_data(MODELS_FILE) model = next((m for m in models if m['id'] == model_id), None) if not model: return jsonify({'error': 'Model not found'}), 404 return jsonify(model) @app.route('/api/models', methods=['POST']) def api_create_model(): """创建新模型""" data = request.get_json() models = load_data(MODELS_FILE) # 生成ID import uuid data['id'] = uuid.uuid4().hex[:12] data['created_at'] = datetime.now().strftime('%Y-%m-%d %H:%M:%S') models.append(data) save_data(MODELS_FILE, models) return jsonify(data) @app.route('/api/models/', methods=['PUT']) def api_update_model(model_id): """更新模型""" data = request.get_json() models = load_data(MODELS_FILE) model = next((m for m in models if m['id'] == model_id), None) if not model: return jsonify({'error': 'Model not found'}), 404 model.update(data) model['updated_at'] = datetime.now().strftime('%Y-%m-%d %H:%M:%S') save_data(MODELS_FILE, models) return jsonify(model) @app.route('/api/models/', methods=['DELETE']) def api_delete_model(model_id): """删除模型""" models = load_data(MODELS_FILE) models = [m for m in models if m['id'] != model_id] save_data(MODELS_FILE, models) return jsonify({'success': True}) @app.route('/api/gpus') def api_gpus(): """获取GPU列表""" gpus = load_data(GPUS_FILE) keyword = request.args.get('q', '').strip().lower() if keyword: gpus = [g for g in gpus if keyword in g.get('name', '').lower() or keyword in g.get('manufacturer', '').lower()] return jsonify(gpus) @app.route('/api/gpus/') def api_gpu_detail(gpu_id): """获取单个GPU详情""" gpus = load_data(GPUS_FILE) gpu = next((g for g in gpus if g['id'] == gpu_id), None) if not gpu: return jsonify({'error': 'GPU not found'}), 404 return jsonify(gpu) @app.route('/api/cpus') def api_cpus(): """获取CPU列表""" cpus = load_data(CPUS_FILE) keyword = request.args.get('q', '').strip().lower() if keyword: cpus = [c for c in cpus if keyword in c.get('name', '').lower() or keyword in c.get('manufacturer', '').lower()] return jsonify(cpus) @app.route('/api/cpus/') def api_cpu_detail(cpu_id): """获取单个CPU详情""" cpus = load_data(CPUS_FILE) cpu = next((c for c in cpus if c['id'] == cpu_id), None) if not cpu: return jsonify({'error': 'CPU not found'}), 404 return jsonify(cpu) @app.route('/api/gpus', methods=['POST']) def api_create_gpu(): """创建新GPU""" data = request.get_json() gpus = load_data(GPUS_FILE) import uuid data['id'] = uuid.uuid4().hex[:12] data['created_at'] = datetime.now().strftime('%Y-%m-%d %H:%M:%S') gpus.append(data) save_data(GPUS_FILE, gpus) return jsonify(data) @app.route('/api/gpus/', methods=['PUT']) def api_update_gpu(gpu_id): """更新GPU""" data = request.get_json() gpus = load_data(GPUS_FILE) gpu = next((g for g in gpus if g['id'] == gpu_id), None) if not gpu: return jsonify({'error': 'GPU not found'}), 404 gpu.update(data) gpu['updated_at'] = datetime.now().strftime('%Y-%m-%d %H:%M:%S') save_data(GPUS_FILE, gpus) return jsonify(gpu) @app.route('/api/gpus/', methods=['DELETE']) def api_delete_gpu(gpu_id): """删除GPU""" gpus = load_data(GPUS_FILE) gpus = [g for g in gpus if g['id'] != gpu_id] save_data(GPUS_FILE, gpus) return jsonify({'success': True}) @app.route('/api/cpus', methods=['POST']) def api_create_cpu(): """创建新CPU""" data = request.get_json() cpus = load_data(CPUS_FILE) import uuid data['id'] = uuid.uuid4().hex[:12] data['created_at'] = datetime.now().strftime('%Y-%m-%d %H:%M:%S') cpus.append(data) save_data(CPUS_FILE, cpus) return jsonify(data) @app.route('/api/cpus/', methods=['PUT']) def api_update_cpu(cpu_id): """更新CPU""" data = request.get_json() cpus = load_data(CPUS_FILE) cpu = next((c for c in cpus if c['id'] == cpu_id), None) if not cpu: return jsonify({'error': 'CPU not found'}), 404 cpu.update(data) cpu['updated_at'] = datetime.now().strftime('%Y-%m-%d %H:%M:%S') save_data(CPUS_FILE, cpus) return jsonify(cpu) @app.route('/api/cpus/', methods=['DELETE']) def api_delete_cpu(cpu_id): """删除CPU""" cpus = load_data(CPUS_FILE) cpus = [c for c in cpus if c['id'] != cpu_id] save_data(CPUS_FILE, cpus) return jsonify({'success': True}) @app.route('/api/search') def api_search(): """全局搜索""" keyword = request.args.get('q', '').strip().lower() if not keyword: return jsonify({'models': [], 'gpus': [], 'cpus': []}) models = load_data(MODELS_FILE) gpus = load_data(GPUS_FILE) cpus = load_data(CPUS_FILE) result = { 'models': [m for m in models if keyword in m.get('name', '').lower() or keyword in m.get('organization', '').lower()], 'gpus': [g for g in gpus if keyword in g.get('name', '').lower() or keyword in g.get('manufacturer', '').lower()], 'cpus': [c for c in cpus if keyword in c.get('name', '').lower() or keyword in c.get('manufacturer', '').lower()] } return jsonify(result) @app.route('/api/calculate/vram') def api_calculate_vram(): """显存计算""" params = request.args.get('params', '7', type=float) # 参数量(B) precision = request.args.get('precision', 'fp16', type=str) # 精度 # 计算公式 # FP32: 参数 * 4字节 # FP16: 参数 * 2字节 # INT8: 参数 * 1字节 # INT4: 参数 * 0.5字节 bytes_per_param = { 'fp32': 4, 'fp16': 2, 'int8': 1, 'int4': 0.5 } multiplier = bytes_per_param.get(precision, 2) vram_gb = params * multiplier * 1e9 / (1024**3) # 转换为GB # 加上KV cache和激活值估算(约30%额外开销) total_vram = vram_gb * 1.3 # 推荐GPU gpus = load_data(GPUS_FILE) suitable_gpus = [g for g in gpus if g.get('memory_gb', 0) >= total_vram] return jsonify({ 'model_vram': round(vram_gb, 2), 'total_vram': round(total_vram, 2), 'suitable_gpus': suitable_gpus }) @app.route('/api/stats') def api_stats(): """统计数据""" models = load_data(MODELS_FILE) gpus = load_data(GPUS_FILE) cpus = load_data(CPUS_FILE) categories = load_data(CATEGORIES_FILE) knowledge = load_data(KNOWLEDGE_FILE) return jsonify({ 'models_count': len(models), 'gpus_count': len(gpus), 'cpus_count': len(cpus), 'categories_count': len(categories), 'knowledge_count': len(knowledge), 'latest_models': sorted(models, key=lambda x: x.get('created_at', ''), reverse=True)[:5] }) # ============ 分类管理API ============ @app.route('/api/categories') def api_categories(): """获取分类列表""" categories = load_data(CATEGORIES_FILE) return jsonify(categories) @app.route('/api/categories', methods=['POST']) def api_create_category(): """创建新分类""" data = request.get_json() categories = load_data(CATEGORIES_FILE) import uuid data['id'] = uuid.uuid4().hex[:12] data['created_at'] = datetime.now().strftime('%Y-%m-%d %H:%M:%S') categories.append(data) save_data(CATEGORIES_FILE, categories) return jsonify(data) @app.route('/api/categories/', methods=['PUT']) def api_update_category(category_id): """更新分类""" data = request.get_json() categories = load_data(CATEGORIES_FILE) category = next((c for c in categories if c['id'] == category_id), None) if not category: return jsonify({'error': 'Category not found'}), 404 category.update(data) category['updated_at'] = datetime.now().strftime('%Y-%m-%d %H:%M:%S') save_data(CATEGORIES_FILE, categories) return jsonify(category) @app.route('/api/categories/', methods=['DELETE']) def api_delete_category(category_id): """删除分类""" categories = load_data(CATEGORIES_FILE) categories = [c for c in categories if c['id'] != category_id] save_data(CATEGORIES_FILE, categories) return jsonify({'success': True}) # ============ 知识库管理API ============ @app.route('/api/knowledge') def api_knowledge(): """获取知识列表""" knowledge = load_data(KNOWLEDGE_FILE) # 搜索过滤 keyword = request.args.get('q', '').strip().lower() if keyword: knowledge = [k for k in knowledge if keyword in k.get('title', '').lower() or keyword in k.get('content', '').lower()] # 分类过滤 category = request.args.get('category', '') if category: knowledge = [k for k in knowledge if k.get('category') == category] return jsonify(sorted(knowledge, key=lambda x: x.get('order', 0))) @app.route('/api/knowledge/') def api_knowledge_detail(knowledge_id): """获取单个知识详情""" knowledge = load_data(KNOWLEDGE_FILE) item = next((k for k in knowledge if k['id'] == knowledge_id), None) if not item: return jsonify({'error': 'Knowledge not found'}), 404 return jsonify(item) @app.route('/api/knowledge', methods=['POST']) def api_create_knowledge(): """创建新知识""" data = request.get_json() knowledge = load_data(KNOWLEDGE_FILE) import uuid data['id'] = uuid.uuid4().hex[:12] data['created_at'] = datetime.now().strftime('%Y-%m-%d %H:%M:%S') if 'order' not in data: data['order'] = len(knowledge) knowledge.append(data) save_data(KNOWLEDGE_FILE, knowledge) return jsonify(data) @app.route('/api/knowledge/', methods=['PUT']) def api_update_knowledge(knowledge_id): """更新知识""" data = request.get_json() knowledge = load_data(KNOWLEDGE_FILE) item = next((k for k in knowledge if k['id'] == knowledge_id), None) if not item: return jsonify({'error': 'Knowledge not found'}), 404 item.update(data) item['updated_at'] = datetime.now().strftime('%Y-%m-%d %H:%M:%S') save_data(KNOWLEDGE_FILE, knowledge) return jsonify(item) @app.route('/api/knowledge/', methods=['DELETE']) def api_delete_knowledge(knowledge_id): """删除知识""" knowledge = load_data(KNOWLEDGE_FILE) knowledge = [k for k in knowledge if k['id'] != knowledge_id] save_data(KNOWLEDGE_FILE, knowledge) return jsonify({'success': True}) # ============ 动态分类数据API ============ @app.route('/api/items/') def api_items(category_id): """获取分类下的数据列表""" items_file = DATA_DIR / f'items_{category_id}.json' items = load_data(items_file) return jsonify(items) @app.route('/api/items//') def api_item_detail(category_id, item_id): """获取单个数据详情""" items_file = DATA_DIR / f'items_{category_id}.json' items = load_data(items_file) item = next((i for i in items if i['id'] == item_id), None) if not item: return jsonify({'error': 'Item not found'}), 404 return jsonify(item) @app.route('/api/items/', methods=['POST']) def api_create_item(category_id): """创建新数据""" data = request.get_json() items_file = DATA_DIR / f'items_{category_id}.json' items = load_data(items_file) import uuid data['id'] = uuid.uuid4().hex[:12] data['category_id'] = category_id data['created_at'] = datetime.now().strftime('%Y-%m-%d %H:%M:%S') items.append(data) save_data(items_file, items) return jsonify(data) @app.route('/api/items//', methods=['PUT']) def api_update_item(category_id, item_id): """更新数据""" data = request.get_json() items_file = DATA_DIR / f'items_{category_id}.json' items = load_data(items_file) item = next((i for i in items if i['id'] == item_id), None) if not item: return jsonify({'error': 'Item not found'}), 404 item.update(data) item['updated_at'] = datetime.now().strftime('%Y-%m-%d %H:%M:%S') save_data(items_file, items) return jsonify(item) @app.route('/api/items//', methods=['DELETE']) def api_delete_item(category_id, item_id): """删除数据""" items_file = DATA_DIR / f'items_{category_id}.json' items = load_data(items_file) items = [i for i in items if i['id'] != item_id] save_data(items_file, items) return jsonify({'success': True}) if __name__ == '__main__': print("=" * 50) print("ParamHub - 参数百科") print("=" * 50) print(f"访问地址: http://localhost:19010") print("=" * 50) app.run(host='0.0.0.0', port=19010, debug=True)