This post assumes certain technical ability and WordPress familiarity. Read everything, including the Half-Elf post, before proceeding to make sure you’re not going to get stuck partway through.

First, move (or copy, and delete later when you’re sure) your images from blogs.dir/BLOG_ID/files/ to /uploads/sites/BLOG_ID/.
Something like this

mkdir /path/to/wp-content/sites
cd /path/to/wp-content/sites

Then for each site

cp -r /path/to/wp-content/blogs.dir/BLOG_ID/files .
mv files BLOG_ID

For my 15-site network, doing this manually was fine. There is no doubt a script that can save you from doing this manually, but believe me when I say you don’t want me writing that for you.

Then you want to start making the database changes. Obvious are the image URLs, primarily in post_content, but also in other places, like theme_mods (custom headers, background images)

Then there are a couple other changes needed so that WordPress knows how to build the URLs, as well as where to put new uploads. So in each site’s options table, you can empty out upload_path, upload_url_path, and fileupload_url

And lastly, trip the ms_files_rewriting flag so that WordPress knows to stop treating your network like it still uses ms-files.php. ms_files_rewriting is a site option, so there’s only one place to set it (or insert it, since it may not be in the database already), and it should be false.

Once you’ve confirmed that nothing has exploded, you can remove the ms-files.php rules from your htaccess or nginx config files

To help out with the database edits, I wrote a plugin. It helped me get this network away from ms-files.php, but I haven’t done a fresh run on any other pre-3.5 network. READ THE SOURCE, USE WITH CAUTION, DON’T DO IT IN PRODUCTION LIKE ME.