mirror of
https://github.com/BillyOutlast/flash-attention-prebuild-wheels-rocm.git
synced 2026-06-30 22:27:54 -04:00
feat: Add graph of download history
This commit is contained in:
@@ -0,0 +1,39 @@
|
|||||||
|
name: Update Download Statistics
|
||||||
|
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
# Run daily at 00:00 UTC
|
||||||
|
- cron: "0 0 * * *"
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
update-stats:
|
||||||
|
name: Update download statistics and graph
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Set up Python
|
||||||
|
uses: actions/setup-python@v5
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: |
|
||||||
|
pip install requests matplotlib
|
||||||
|
|
||||||
|
- name: Update download statistics
|
||||||
|
run: |
|
||||||
|
python update_download_stats.py
|
||||||
|
|
||||||
|
- name: Commit and push changes
|
||||||
|
run: |
|
||||||
|
git config --global user.name "github-actions[bot]"
|
||||||
|
git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
||||||
|
git add docs/data/download_history.json docs/data/download_graph.png
|
||||||
|
git diff --staged --quiet || git commit -m "chore: update download statistics
|
||||||
|
|
||||||
|
Update download statistics and graph for $(date -u +%Y-%m-%d)"
|
||||||
|
git push
|
||||||
@@ -136,6 +136,34 @@ If you use this repository in your research and find it helpful, please cite the
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Star History and Download Statistics
|
||||||
|
|
||||||
|
<div style="display: flex; flex-direction: row; gap: 24px; width: 100%;">
|
||||||
|
<a href="https://www.star-history.com/#mjun0812/flash-attention-prebuild-wheels&type=date&legend=top-left" style="display: inline-block;">
|
||||||
|
<picture>
|
||||||
|
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=mjun0812/flash-attention-prebuild-wheels&type=date&theme=dark&legend=top-left" />
|
||||||
|
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=mjun0812/flash-attention-prebuild-wheels&type=date&legend=top-left" />
|
||||||
|
<img alt="Star History Chart" src="https://api.star-history.com/svg?repos=mjun0812/flash-attention-prebuild-wheels&type=date&legend=top-left" height="300"/>
|
||||||
|
</picture>
|
||||||
|
</a>
|
||||||
|
<img alt="Download Statistics" src="./docs/data/download_graph.png" height="300" style="display: inline-block;"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
## Original Repository
|
## Original Repository
|
||||||
|
|
||||||
[repo](https://github.com/Dao-AILab/flash-attention)
|
[repo](https://github.com/Dao-AILab/flash-attention)
|
||||||
|
|
||||||
|
```bibtex
|
||||||
|
@inproceedings{dao2022flashattention,
|
||||||
|
title={Flash{A}ttention: Fast and Memory-Efficient Exact Attention with {IO}-Awareness},
|
||||||
|
author={Dao, Tri and Fu, Daniel Y. and Ermon, Stefano and Rudra, Atri and R{\'e}, Christopher},
|
||||||
|
booktitle={Advances in Neural Information Processing Systems (NeurIPS)},
|
||||||
|
year={2022}
|
||||||
|
}
|
||||||
|
@inproceedings{dao2023flashattention2,
|
||||||
|
title={Flash{A}ttention-2: Faster Attention with Better Parallelism and Work Partitioning},
|
||||||
|
author={Dao, Tri},
|
||||||
|
booktitle={International Conference on Learning Representations (ICLR)},
|
||||||
|
year={2024}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 91 KiB |
@@ -0,0 +1,30 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"timestamp": "2024-10-27T00:00:00+00:00",
|
||||||
|
"total_downloads": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": "2025-12-04T13:25:33.785415+00:00",
|
||||||
|
"total_downloads": 906514
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": "2025-12-04T13:26:09.117076+00:00",
|
||||||
|
"total_downloads": 906524
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": "2025-12-04T13:46:48.639327+00:00",
|
||||||
|
"total_downloads": 906741
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": "2025-12-04T13:53:02.674280+00:00",
|
||||||
|
"total_downloads": 906828
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": "2025-12-04T13:53:35.050423+00:00",
|
||||||
|
"total_downloads": 906834
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": "2025-12-04T13:56:13.655744+00:00",
|
||||||
|
"total_downloads": 906837
|
||||||
|
}
|
||||||
|
]
|
||||||
@@ -0,0 +1,193 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
Fetch GitHub release download statistics and generate a graph.
|
||||||
|
|
||||||
|
This script fetches download counts from GitHub API, stores historical data,
|
||||||
|
and generates a graph showing download trends over time.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import json
|
||||||
|
from datetime import datetime, timezone
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
import requests
|
||||||
|
|
||||||
|
|
||||||
|
def fetch_download_stats(owner: str, repo: str) -> dict:
|
||||||
|
"""
|
||||||
|
Fetch download statistics from GitHub API.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
owner: Repository owner
|
||||||
|
repo: Repository name
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
dict: Dictionary containing total downloads and timestamp
|
||||||
|
"""
|
||||||
|
url = f"https://api.github.com/repos/{owner}/{repo}/releases"
|
||||||
|
headers = {}
|
||||||
|
|
||||||
|
# Fetch all releases with pagination
|
||||||
|
all_releases = []
|
||||||
|
page = 1
|
||||||
|
per_page = 100 # Maximum per page allowed by GitHub API
|
||||||
|
|
||||||
|
while True:
|
||||||
|
params = {"page": page, "per_page": per_page}
|
||||||
|
response = requests.get(url, headers=headers, params=params)
|
||||||
|
response.raise_for_status()
|
||||||
|
|
||||||
|
releases = response.json()
|
||||||
|
if not releases:
|
||||||
|
break
|
||||||
|
|
||||||
|
all_releases.extend(releases)
|
||||||
|
page += 1
|
||||||
|
|
||||||
|
# Check if there are more pages
|
||||||
|
if len(releases) < per_page:
|
||||||
|
break
|
||||||
|
|
||||||
|
print(f"Fetched {len(all_releases)} releases")
|
||||||
|
|
||||||
|
total_downloads = 0
|
||||||
|
release_data = []
|
||||||
|
|
||||||
|
for release in all_releases:
|
||||||
|
release_downloads = 0
|
||||||
|
for asset in release.get("assets", []):
|
||||||
|
release_downloads += asset.get("download_count", 0)
|
||||||
|
|
||||||
|
total_downloads += release_downloads
|
||||||
|
release_data.append(
|
||||||
|
{
|
||||||
|
"tag": release["tag_name"],
|
||||||
|
"name": release["name"],
|
||||||
|
"downloads": release_downloads,
|
||||||
|
"created_at": release["created_at"],
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
return {
|
||||||
|
"total_downloads": total_downloads,
|
||||||
|
"releases": release_data,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def load_history(filepath: Path) -> list:
|
||||||
|
"""
|
||||||
|
Load historical download statistics from JSON file.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
filepath: Path to the history JSON file
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
list: List of historical data points
|
||||||
|
"""
|
||||||
|
if not filepath.exists():
|
||||||
|
return []
|
||||||
|
|
||||||
|
with open(filepath, "r") as f:
|
||||||
|
return json.load(f)
|
||||||
|
|
||||||
|
|
||||||
|
def save_history(filepath: Path, history: list) -> None:
|
||||||
|
"""
|
||||||
|
Save historical download statistics to JSON file.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
filepath: Path to the history JSON file
|
||||||
|
history: List of historical data points
|
||||||
|
"""
|
||||||
|
filepath.parent.mkdir(parents=True, exist_ok=True)
|
||||||
|
with open(filepath, "w") as f:
|
||||||
|
json.dump(history, f, indent=2)
|
||||||
|
|
||||||
|
|
||||||
|
def generate_graph(history: list, output_path: Path, label: str = "") -> None:
|
||||||
|
"""
|
||||||
|
Generate a download statistics graph in Star History (XKCD) style.
|
||||||
|
"""
|
||||||
|
if len(history) < 2:
|
||||||
|
print("Not enough data to generate a graph (need at least 2 data points)")
|
||||||
|
return
|
||||||
|
|
||||||
|
dates = [datetime.fromisoformat(entry["timestamp"]) for entry in history]
|
||||||
|
downloads = [entry["total_downloads"] for entry in history]
|
||||||
|
|
||||||
|
# --- XKCD Style Context ---
|
||||||
|
# これにより手書き風のエフェクト(歪んだ線、手書きフォント)が適用されます
|
||||||
|
with plt.xkcd():
|
||||||
|
fig, ax = plt.subplots(figsize=(8, 6))
|
||||||
|
|
||||||
|
# Star History風の色(オレンジ/赤系)
|
||||||
|
line_color = "#f05133"
|
||||||
|
|
||||||
|
# プロット
|
||||||
|
ax.plot(
|
||||||
|
dates,
|
||||||
|
downloads,
|
||||||
|
color=line_color,
|
||||||
|
linewidth=3,
|
||||||
|
label=label if label else "Downloads",
|
||||||
|
)
|
||||||
|
|
||||||
|
if label:
|
||||||
|
legend = ax.legend(loc="upper left", frameon=True, fontsize=10)
|
||||||
|
legend.get_frame().set_edgecolor("black")
|
||||||
|
legend.get_frame().set_linewidth(1.5)
|
||||||
|
|
||||||
|
ax.spines["right"].set_color("none")
|
||||||
|
ax.spines["top"].set_color("none")
|
||||||
|
|
||||||
|
ax.spines["bottom"].set_linewidth(1.5)
|
||||||
|
ax.spines["left"].set_linewidth(1.5)
|
||||||
|
|
||||||
|
plt.title("Download History", fontsize=16, y=1.05)
|
||||||
|
plt.xlabel("Date", fontsize=12)
|
||||||
|
plt.ylabel("Total Downloads", fontsize=12)
|
||||||
|
|
||||||
|
ax.set_ylim(bottom=0)
|
||||||
|
|
||||||
|
ax.yaxis.set_major_formatter(plt.FuncFormatter(lambda x, p: f"{int(x):,}"))
|
||||||
|
|
||||||
|
fig.autofmt_xdate(rotation=0, ha="center")
|
||||||
|
|
||||||
|
plt.tight_layout()
|
||||||
|
|
||||||
|
output_path.parent.mkdir(parents=True, exist_ok=True)
|
||||||
|
plt.savefig(output_path, dpi=150, bbox_inches="tight", facecolor="white")
|
||||||
|
print(f"Graph saved to {output_path}")
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
"""Main function to update download statistics and generate graph."""
|
||||||
|
owner = "mjun0812"
|
||||||
|
repo = "flash-attention-prebuild-wheels"
|
||||||
|
history_file = Path("docs/data/download_history.json")
|
||||||
|
graph_output = Path("docs/data/download_graph.png")
|
||||||
|
|
||||||
|
# Fetch current stats
|
||||||
|
print("Fetching download statistics from GitHub API...")
|
||||||
|
current_stats = fetch_download_stats(owner, repo)
|
||||||
|
print(f"Total downloads: {current_stats['total_downloads']}")
|
||||||
|
|
||||||
|
# Load and update history
|
||||||
|
history = load_history(history_file)
|
||||||
|
history.append(
|
||||||
|
{
|
||||||
|
"timestamp": datetime.now(timezone.utc).isoformat(),
|
||||||
|
"total_downloads": current_stats["total_downloads"],
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
# Save updated history
|
||||||
|
save_history(history_file, history)
|
||||||
|
print(f"History saved to {history_file}")
|
||||||
|
|
||||||
|
generate_graph(history, graph_output, f"{owner}/{repo}")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
Reference in New Issue
Block a user