Buckets:
| #!/usr/bin/env python3 | |
| """ | |
| NeuroFlow 蒸馏数据生成 — 调用 DeepSeek API 获取教师数据 | |
| 用法: | |
| python3 scripts/gen_distill_data.py --prompts prompts.txt --output teacher_data.jsonl --max-samples 10000 | |
| 输出 JSONL 格式: {"prompt": "...", "completion": "...", "teacher_text": "..."} | |
| """ | |
| import argparse, json, os, sys, time, random | |
| import requests | |
| # DeepSeek API (Anthropic-compatible endpoint) | |
| API_URL = os.environ.get('DEEPSEEK_API_URL', | |
| 'https://api.deepseek.com/anthropic/v1/messages') | |
| API_KEY = os.environ.get('DEEPSEEK_API_KEY', | |
| os.environ.get('ANTHROPIC_AUTH_TOKEN', '')) | |
| HEADERS = { | |
| "Authorization": f"Bearer {API_KEY}", | |
| "Content-Type": "application/json", | |
| } | |
| def call_deepseek(prompt: str, max_tokens: int = 128, temperature: float = 0.7) -> str: | |
| """Call DeepSeek API to generate text completion""" | |
| payload = { | |
| "model": "deepseek-chat", | |
| "messages": [{"role": "user", "content": prompt}], | |
| "max_tokens": max_tokens, | |
| "temperature": temperature, | |
| "stream": False, | |
| } | |
| try: | |
| resp = requests.post(API_URL, headers=HEADERS, json=payload, timeout=60) | |
| if resp.status_code == 200: | |
| data = resp.json() | |
| # Extract text from response | |
| for choice in data.get("content", []): | |
| if choice.get("type") == "text": | |
| return choice.get("text", "") | |
| # Fallback: try standard format | |
| if "choices" in data: | |
| return data["choices"][0]["message"]["content"] | |
| else: | |
| print(f" API error {resp.status_code}: {resp.text[:200]}") | |
| return "" | |
| except Exception as e: | |
| print(f" API exception: {e}") | |
| return "" | |
| def load_prompts(path: str) -> list: | |
| """Load prompts from file (one per line) or generate default Chinese prompts""" | |
| if path and os.path.exists(path): | |
| with open(path, 'r', encoding='utf-8') as f: | |
| return [line.strip() for line in f if line.strip() and not line.startswith('#')] | |
| # Default: diverse Chinese prompts from different domains | |
| defaults = [ | |
| # 科学 | |
| "请解释量子力学的基本原理", | |
| "什么是相对论?用简单的话解释", | |
| "人工智能的发展历史是什么", | |
| "DNA双螺旋结构的发现过程", | |
| # 数学 | |
| "如何求解一元二次方程", | |
| "微积分的基本思想是什么", | |
| "请解释概率论中的贝叶斯定理", | |
| # 文学 | |
| "请写一首关于春天的诗", | |
| "唐诗和宋词的区别是什么", | |
| "中国四大名著有哪些", | |
| # 历史 | |
| "秦始皇统一六国的过程", | |
| "工业革命对世界的影响", | |
| # 生活 | |
| "如何保持健康的饮食习惯", | |
| "怎样提高学习效率", | |
| "推荐几种有效的记忆方法", | |
| # 哲学 | |
| "什么是存在主义", | |
| "孔子的仁政思想是什么", | |
| # 技术 | |
| "Python编程语言的特点", | |
| "什么是深度学习", | |
| "区块链技术的基本原理", | |
| ] | |
| return defaults | |
| def main(): | |
| parser = argparse.ArgumentParser(description='NeuroFlow 蒸馏数据生成') | |
| parser.add_argument('--prompts', default='', help='Prompt文件 (一行一个)') | |
| parser.add_argument('--output', default='teacher_data.jsonl', help='输出文件') | |
| parser.add_argument('--max-samples', type=int, default=1000, help='最大样本数') | |
| parser.add_argument('--max-tokens', type=int, default=128, help='教师生成长度') | |
| parser.add_argument('--temperature', type=float, default=0.7, help='教师温度') | |
| parser.add_argument('--repeat', type=int, default=1, help='每个prompt重复次数(不同温度)') | |
| args = parser.parse_args() | |
| prompts = load_prompts(args.prompts) | |
| print(f"📝 加载 {len(prompts)} 个 prompts") | |
| # Expand: each prompt × repeat times with different temperatures | |
| all_tasks = [] | |
| for p in prompts: | |
| for r in range(args.repeat): | |
| temp = 0.3 + r * 0.4 / max(1, args.repeat - 1) if args.repeat > 1 else args.temperature | |
| all_tasks.append((p, temp)) | |
| random.shuffle(all_tasks) | |
| all_tasks = all_tasks[:args.max_samples] | |
| print(f"🎯 目标: {len(all_tasks)} 个样本") | |
| print(f"🔑 API: {API_URL}") | |
| print() | |
| success = 0 | |
| total_chars = 0 | |
| t0 = time.time() | |
| with open(args.output, 'w', encoding='utf-8') as out: | |
| for i, (prompt, temp) in enumerate(all_tasks): | |
| text = call_deepseek(prompt, args.max_tokens, temp) | |
| if text and len(text) >= 10: | |
| record = { | |
| "prompt": prompt, | |
| "completion": text, | |
| "temperature": temp, | |
| } | |
| out.write(json.dumps(record, ensure_ascii=False) + '\n') | |
| out.flush() | |
| success += 1 | |
| total_chars += len(text) | |
| if (i + 1) % 10 == 0: | |
| elapsed = time.time() - t0 | |
| rate = (i + 1) / elapsed * 60 if elapsed > 0 else 0 | |
| print(f" [{i+1}/{len(all_tasks)}] success={success} " | |
| f"rate={rate:.0f}/min elapsed={elapsed:.0f}s") | |
| else: | |
| print(f" [{i+1}] ❌ empty response for: {prompt[:50]}") | |
| # Rate limit: ~60 requests/min to be safe | |
| if (i + 1) % 50 == 0: | |
| time.sleep(1) | |
| elapsed = time.time() - t0 | |
| size_mb = os.path.getsize(args.output) / 1e6 if os.path.exists(args.output) else 0 | |
| print(f"\n✅ 完成!") | |
| print(f" 样本: {success}/{len(all_tasks)}") | |
| print(f" 字符: {total_chars:,}") | |
| print(f" 文件: {args.output} ({size_mb:.1f} MB)") | |
| print(f" 耗时: {elapsed:.0f}s ({elapsed/60:.1f}min)") | |
| print(f" 费用预估: ~${success * 128 / 1e6 * 0.14:.2f} (DeepSeek 输入$0.14/M tokens)") | |
| # Save stats | |
| stats = { | |
| "total_samples": success, | |
| "total_chars": total_chars, | |
| "elapsed_seconds": elapsed, | |
| "model": "deepseek-chat", | |
| } | |
| stats_path = args.output.replace('.jsonl', '_stats.json') | |
| with open(stats_path, 'w') as f: | |
| json.dump(stats, f, indent=2, ensure_ascii=False) | |
| print(f" 统计: {stats_path}") | |
| if __name__ == '__main__': | |
| main() | |
Xet Storage Details
- Size:
- 6.36 kB
- Xet hash:
- c172d38921ccd10aa96604739b1d5ab61a58f85b5e7e0d52875cf56a4474b64a
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.