-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
5a7b0c7
commit 1c2f18c
Showing
7 changed files
with
146 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
|
||
|
||
# This workflow will upload a Python Package using Twine when a release is created | ||
# For more information see: https://help.github.com/en/actions/language-and-framework-guides/using-python-with-github-actions#publishing-to-package-registries | ||
|
||
# This workflow uses actions that are not certified by GitHub. | ||
# They are provided by a third-party and are governed by | ||
# separate terms of service, privacy policy, and support | ||
# documentation. | ||
|
||
name: Upload Python Package | ||
|
||
on: | ||
release: | ||
types: [published] | ||
|
||
jobs: | ||
deploy: | ||
|
||
runs-on: ubuntu-latest | ||
|
||
steps: | ||
- uses: actions/checkout@v2 | ||
- name: Set up Python | ||
uses: actions/setup-python@v2 | ||
with: | ||
python-version: '3.x' | ||
- name: Install dependencies | ||
run: | | ||
python -m pip install --upgrade pip | ||
pip install build | ||
- name: Build package | ||
run: python -m build | ||
- name: Publish package | ||
uses: pypa/gh-action-pypi-publish@27b31702a0e7fc50959f5ad993c78deac1bdfc29 | ||
with: | ||
user: __token__ | ||
password: ${{ secrets.PYPI_API_TOKEN }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,55 @@ | ||
# TPDNE (wip) | ||
## TPDNE (wip) | ||
|
||
Thispersondoesnotexist went down, so this time, while building it back up, I am going to open source all of it. I'll try to make it modular enough so anyone can deploy their own ever-dreaming GAN (or soon to be 1-2 step DDPM) to be public facing | ||
<a href="https://twitter.com/kasiababis/status/1379370542986330112">Thispersondoesnotexist</a> went down, so this time, while building it back up, I am going to open source all of it. I'll try to make it modular enough so anyone can deploy their own ever-dreaming GAN (or soon to be 1-2 step DDPM) to be public facing | ||
|
||
I may also take some time to do something I've always wanted. To Dreambooth my dog into the machine and have it dream her up forever to the public. | ||
|
||
## Explained | ||
|
||
The site is hosted on Hetzner on a 100$ / month GPU server. Images are generated live, so people, try as they might, cannot exhaust the amount of faces they experience. Through this, they gain an intuition for how vast the latent space of these neural networks are. It also allowed me to explain it to laypeople as having an 'artificial intelligence endlessly dreaming', without it having to be an exaggeration. | ||
|
||
How was this feasible without scaling issues? Well, the site is actually a magic trick. Each user, when refreshing the page, actually sees the same image at any point in time. Images are replaced every 250ms, below the human reaction time. By the time the user studies the face and refreshes, the next face will be there, but it is the same face that everyone experiences around the world at the same time. | ||
|
||
The model itself was trained by <a href="https://research.nvidia.com/person/tero-karras">Tero Karras</a> under the name <a href="https://arxiv.org/abs/1912.04958">StyleGAN 2</a>. | ||
|
||
## Install | ||
|
||
```bash | ||
$ pip install TPDNE-utils | ||
``` | ||
|
||
## Usage | ||
|
||
```python | ||
from TPDNE_utils import sample_image_and_save_repeatedly | ||
|
||
# some function that returns a sampled image in the form of a 3 dimensional ndarray | ||
|
||
def generate_image(): | ||
import numpy as np | ||
return np.random.randn(3, 1024, 1024) | ||
|
||
# saves a new sampled image every 250ms as out/sampled.webp | ||
|
||
sample_image_and_save_repeatedly(generate_image, 'out/sampled') | ||
|
||
# use pm2 (node process manager) to run this script | ||
# then use nginx to serve out/sampled.web | ||
# optionally put behind cloudflare | ||
|
||
``` | ||
|
||
## Todo | ||
|
||
- [ ] take care of an nginx template that can be generated from a command-line | ||
|
||
## Citations | ||
|
||
```bibtex | ||
@inproceedings{Karras2020ada, | ||
title = {Training Generative Adversarial Networks with Limited Data}, | ||
author = {Tero Karras and Miika Aittala and Janne Hellsten and Samuli Laine and Jaakko Lehtinen and Timo Aila}, | ||
booktitle = {Proc. NeurIPS}, | ||
year = {2020} | ||
} | ||
``` |
Empty file.
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
from TPDNE_utils.tpdne import sample_image_and_save_repeatedly |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import os | ||
import numpy as np | ||
from time import time, sleep | ||
from pathlib import Path | ||
from functools import wraps | ||
from PIL import Image | ||
|
||
from beartype import beartype | ||
from beartype.typing import Callable | ||
|
||
@beartype | ||
def sample_image_and_save_repeatedly( | ||
fn: Callable[..., np.ndarray], # function that returns a ndarray of shape (3, <width>, <height>) | ||
output_path: str = './out/random', # path to the output image, without extension (will be saved as webp) | ||
*, | ||
call_every_ms: int = 250, # how often to sample | ||
tmp_dir = '/tmp', # to store temporary images, before symbolically linking to the output path | ||
num_rotated_tmp_images = 10, | ||
verbose: bool = True | ||
): | ||
tmp_dir = Path(tmp_dir) | ||
output_path = Path(output_path).with_suffix('.webp') | ||
call_every_seconds = call_every_ms / 1000 | ||
|
||
assert tmp_dir.is_dir() | ||
output_path.parents[0].mkdir(parents = True, exist_ok = True) | ||
|
||
tmp_image_index = 0 | ||
|
||
while True: | ||
start = time() | ||
image_tensor = fn() | ||
|
||
tmp_image_index = (tmp_image_index + 1) % num_rotated_tmp_images | ||
tmp_path = str(tmp_dir / f'{tmp_image_index}.webp') | ||
|
||
Image.fromarray(image_tensor, 'RGB').save(tmp_path, format = 'webp') | ||
os.system(f'ln -nfs {tmp_path} {output_path}') | ||
|
||
elapsed = time() - start | ||
|
||
if verbose: | ||
print(f'{elapsed:.3f}s - tmp image at {tmp_path}, output image at {output_path}') | ||
|
||
if elapsed >= call_every_seconds: | ||
continue | ||
|
||
sleep(call_every_seconds - elapsed) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters