P-HAR: a three-stream action recogniser for adult video, and what its 75.64% actually measures
deep learning sex position classifier
At a glance
- What is it?
- P-HAR late-fuses RGB, skeleton and audio models built on MMAction2 to classify 17 actions in pornographic video. The repository is a research side project with a small training set, a manual MMDetection/MMPose install path, and a README that already flags the hard cases.
- Who is it for?
- Adopt P-HAR only as a starting point for experimentation or as a reference for how late fusion is wired together, and only if you can install the MMDetection, MMPose and MMAction2 stack yourself. Do not adopt it as a production tagger: the README describes a small training set, 17 supported actions, and a 75.64% figure that is a top-2 measurement, and the author states that deployment depends on whether people find the project useful.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 95 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
What P-HAR classifies, and the two audiences it addresses
P-HAR stands for Porn Human Action Recognition. The repository describes itself as a side project that applies human action recognition models to the pornographic domain, and it currently supports 17 actions listed in resources/annotations/annotations.txt. The stated use cases are automated tagging, timestamp generation, recommendation input, and cutting non-sexual content out of a video. Each of those is a downstream consumer of the same output: a sequence of predictions over time, with the top labels attached to intervals.
The audience splits in two. The first is engineers who want tags or timestamps from a video file and are willing to run a Python pipeline locally. The second is researchers looking at how SOTA action recognition behaves under a specific kind of visual difficulty. The README is explicit about why the domain is technically interesting: light variation, occlusions, and a wide range of camera angles and filming techniques, including POV and dedicated camera operators. Two identical positions can be shot from perspectives different enough to confuse the model. That framing matters, because it tells you the accuracy figure is not a general-purpose action recognition number.
Late fusion across RGB, skeleton and audio
The architecture uses three input streams: RGB frames, human skeleton, and audio. Three separate models are trained, one per stream, and their results are merged through late fusion. Late fusion here means the individual model outputs are combined after each has produced its own prediction, rather than a single network consuming all three modalities at the input layer. The demo exposes the combination through a --coefficients flag, which takes one value per model, so the weighting is a runtime parameter rather than something baked into the checkpoint.
The pipeline is built on MMAction2, with MMDetection supplying the human detector and MMPose supplying the pose model. That is the data flow: a detector locates people in frames, the pose model extracts skeletons, the RGB stream reads frames directly, and audio is handled by its own model. All three checkpoints are downloaded separately and placed in checkpoints/har. The README points to a Faster R-CNN R50 FPN checkpoint for detection and an HRNet W32 COCO 256x192 checkpoint for pose, plus HAR models from the v1.0.0 release.
The models operate on spatio-temporal data, meaning clips rather than single frames. The README contrasts this with miles-deep, which uses single images, and calls clip-based processing an inherently superior way to do action recognition. That is a defensible position for actions that unfold over time, though it also means the pipeline cannot classify anything from a still frame, and clip length becomes a parameter you have to reason about.
Running the multimodal demo, and what the flags change
The main entry point is src/demo/multimodial_demo.py. The README gives this example: python src/demo/multimodial_demo.py video.mp4 demo.mp4. The second argument is the output, and the README states it can be a video file or a JSON file, so passing demo.json dumps predictions instead of rendering an annotated clip. The demo shows top predictions every 7 seconds by default.
To drop the audio model, the README gives: python src/demo/multimodial_demo.py video.mp4 demo.json --audio-checkpoint '' --coefficients 0.5 1.0 --verbose. Two things are happening there. An empty --audio-checkpoint disables that branch, and --coefficients supplies weights for the remaining models. If you disable a branch, the coefficient list has to match what is left, which is a small but real footgun: the README does not spell out the failure mode if the counts mismatch.
Timestamps come from a flag on the same script: python src/demo/multimodial_demo.py video.mp4 demo.json --timestamps. Tags are a separate step that consumes the JSON: python src/top_tags.py demo.json, which the README says grabs the top 3 tags by default. Content filtering is listed as a TODO, conditional on demand, so it is not implemented in the version described here.
The installation chain is the real cost of entry
There is a Docker path: docker build -f docker/Dockerfile . -t rlleshi/phar. The manual path is longer and version-sensitive. The README instructs you to clone with submodules (git clone --recurse-submodules git@github.com:rlleshi/phar.git), create an environment with Python 3.8 or newer, install torch with CUDA and cuDNN recommended, then install the correct mmcv version for your CUDA and Torch combination. The example given is pip install mmcv-full==1.3.18 -f https://download.openmmlab.com/mmcv/dist/cu113/torch1.10.0/index.html, which pins CUDA 11.3 and Torch 1.10.0.
After that you build MMAction2 from the bundled submodule: cd mmaction2/ && pip install cython --no-cache-dir && pip install --no-cache-dir -e ., then install MMPose and MMDetection from their own documentation, then pip install -r requirements/extra.txt. Four separate projects have to agree on versions. The README's own instruction to pick the right mmcv build is the load-bearing step: mmcv-full wheels are compiled against specific CUDA and Torch pairs, and the example URL is a single point in that matrix, not a universal command. Expect to spend most of your setup time here rather than in the P-HAR code itself.
What 75.64% means, and where the model is likely to fail
The README reports 75.64% as the best accuracy for the multi-model configuration, and then explains why that number should be read as a top-2 figure. More than one action can happen at the same time, and some of the 17 actions overlap conceptually, so the README states it is best to consider top 2 accuracy as the performance measurement. That is a meaningful caveat. A top-2 score of roughly 75% is not the same claim as a top-1 score of 75%, and anyone quoting the number without that context is misreading the repository.
The README also notes the training set is small and that only around 50 experiments had been performed at the time of writing. It asks for more data and says help is welcomed. So the honest limitation is data volume, not architecture: three streams and late fusion are a reasonable design for this problem, but they cannot compensate for a small labelled corpus. The README's own description of the domain difficulty (identical positions shot from very different angles) points at the failure mode you should expect: confident predictions on a position that is visually similar to another one under an unusual camera setup.
A second limitation is scope. Seventeen actions is a closed set. Anything outside it, including non-sexual content, is being forced into those categories or into whatever background class the training data implies. The README lists cutting non-sexual content as a motivation, but content filtering is a TODO, so the repository does not ship that capability in the described version.
How it differs from single-frame classifiers like miles-deep
The README names miles-deep as a comparison point and states the difference directly: miles-deep uses single images, while P-HAR processes video clips. That is the actual distinction in approach. A single-frame classifier labels a still, which means it has no access to motion, duration, or ordering. For action recognition, where the action is defined by what changes between frames, that is a real constraint. P-HAR's clip-based models see temporal structure, and the skeleton stream adds pose geometry that a raw-frame classifier does not get.
The trade-off runs the other way too. A single-frame pipeline can classify a thumbnail or a sampled frame with no clip extraction, no detector, and no pose model, which makes it far cheaper to run and easier to deploy. P-HAR needs MMDetection, MMPose, and MMAction2 plus three checkpoints before it produces anything. If your requirement is coarse filtering rather than fine-grained position labels, that dependency weight is hard to justify. The README itself leaves deployment as an open question, stating it depends on whether people find the project useful, and that currently one has to install the relevant libraries.
Licence, maintenance and the commercial fork in the road
The repository is Apache-2.0. That is a permissive licence with an explicit patent grant and a requirement to retain notices and state changes. It does not, on its own, settle what you can do with the model weights or with the data the models were trained on, and the README does not describe the dataset's licence or provenance beyond linking to annotation files. If you plan to ship anything built on these checkpoints, that gap is worth resolving before you build on top of it. This is a description of the licence text, not legal advice.
The maintenance picture has a visible split. The last push is dated 2026-06-12, but the only release is v1.0.0 from 2022-06-01, and the README's opening update points to separately trained models reaching over 94% accuracy on 20 action categories, available through an API with business enquiries directed to an email address. So the open repository and the improved models are not the same artifact. The open version supports 17 actions and reports 75.64%; the better-performing models described in the update are not in this repository. That is the single most important thing to understand before adopting: you are getting the 2022 research release, not the current commercial one.
Upgrade cost follows from the dependency chain. Because mmcv-full, MMAction2, MMPose and MMDetection are pinned to compatible versions, moving to a newer Torch or CUDA means re-resolving that matrix, and the README's example build is tied to cu113 and torch1.10.0. There is no migration guide in the material provided.
Who should clone this, and who should not
Clone it if you want a worked example of late fusion across RGB, skeleton and audio in MMAction2, or if you are researching action recognition under difficult filming conditions and want a baseline to compare against. The demo commands are short and the JSON output is easy to post-process with src/top_tags.py. The README's honesty about the top-2 measurement and the small dataset makes it usable as a research reference without much risk of overreading it.
Do not clone it if you need a production tagger with predictable accuracy across arbitrary adult content, or if you need content filtering, which is listed as a TODO. Do not clone it if you cannot install MMDetection, MMPose and MMAction2 with matching mmcv-full builds, or if you need the 20-category models mentioned in the update, since those live behind an API rather than in this repository. And do not quote the 75.64% figure as a top-1 accuracy. It is not one.
Editorial conclusion
Adopt P-HAR only as a starting point for experimentation or as a reference for how late fusion is wired together, and only if you can install the MMDetection, MMPose and MMAction2 stack yourself. Do not adopt it as a production tagger: the README describes a small training set, 17 supported actions, and a 75.64% figure that is a top-2 measurement, and the author states that deployment depends on whether people find the project useful. Before committing, verify the exact mmcv-full build that matches your CUDA and Torch versions, and run src/demo/multimodial_demo.py on one clip from your own domain to see the top predictions at the 7 second default interval.
Community notes