Here is another method I used to remove duplicates from a SSURGO soil data download. The downloaded shapefiles did not have a unique key, so a serial pk column was generated when I imported to PostGIS. There were a few overlaps in the data sets, and I inadvertently imported some records more than once while developing the import script.
The group by statement includes all columns in the table, excluding the primary key.
It will only delete one set of duplicate rows each time it's run, so if a row is repeated 4 times you will need to run this a minimum of 3 times. This is likely not as fast as John's solution, but works within an existing table. It also works when you don't have a unique id for each unique geometry (such as the osm_id in the original question).
I used a python script to repeat until duplicates were gone, and then ran a full vacuum. I think the script and vacuum each took about 30 minutes for a few hundred thousand duplicates from around 1.5 million records in 6 tables. Plenty good for a one-off. It went through the small tables very quickly.
DELETE FROM schema.table
WHERE primary_key IN
(SELECT MAX(primary_key)
FROM schema.table
GROUP BY ST_AsBinary(geom), col_1, col_2, col_etc
HAVING COUNT(primary_key) > 1);
EDIT: modified SQL to avoid running multiple times based on @dbaston suggestion: (below). I tried this query method on a large table (~1.5 million records, ~25,000 duplicate point rows), and after it ran for 45 minutes I canceled its execution. Running with the SQL above (using a smaller subquery from the HAVING COUNT) reduced each run to less than 30 seconds. After running 3 times, it was done with all duplicates. The SQL below should be OK for small tables.
DELETE FROM schema.table
WHERE primary_key NOT IN
(SELECT MAX(primary_key)
FROM schema.table
GROUP BY ST_AsBinary(geom), col_1, col_2, col_etc);